「BASE」を含む日記 RSS

はてなキーワード: BASEとは

2009-10-04

グーグルマップ壁紙にしてみる

10/18 改訂

グーグルマップ航空写真をつなげて一枚にするスクリプト

なお、取得した画像著作権グーグル他各社が保持しています。

ご利用は計画的に私的範囲でどうぞご利用ください。

#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Long;
use LWP::UserAgent;
use GD;

my $cmdline = join(" ", $0, @ARGV);
my $usage = "usage: $0 -sx=116423 -sy=51603 -ex=116426 -ey=51605 -dx=4 -dy=3 -z=17 -size=300 -get=30 -dir=cache -output=output.jpg -nodebug";
my ($sx, $sy) = (0, 0);
my ($ex, $ey) = (0, 0);
my ($dx, $dy) = (4, 3);
my $z = 17;
my $size = 300;
my $get = 30;
my $dir = "cache";
my $output = "output.jpg";
my $debug = 0;
GetOptions("sx=i" => \$sx, "sy=i" => \$sy,
	   "ex=i" => \$ex, "ey=i" => \$ey,
	   "dx=i" => \$dx, "dy=i" => \$dy,
	   "z=i" => \$z,
	   "size=i" => \$size, "get=i" => $get,
	   "dir=s" => \$dir, "output=s" => \$output,
	   "debug!" => \$debug) or die "$usage\nDied";
if ($ex == 0) {
    $ex = $sx + $dx;
} else {
    $ex++;
    $dx = $ex - $sx;
}
if ($ey == 0) {
    $ey = $sy + $dy;
} else {
    $ey++;
    $dy = $ey - $sy;
}
$sx>0 and $dx>0 and $sy>0 and $dy>0 and $z>0 and $dir and $output
    or die "$usage\nBad arguments";
$dx*$dy > $size and die "Getting too large.";

$debug and print "debug: mkdir $dir\n";
mkdir $dir;
-d $dir or die "can't make dir $dir: $!";

my $base = sprintf("http://khm%d.google.co.jp/kh/v=46&z=%d", int(rand(4)), $z);
my $ua = LWP::UserAgent->new;
printf "now get %d images...\n", $dx*$dy;
for (my $x=$sx; $x < $ex; $x++) {
    for (my $y=$sy; $y < $ey; $y++) {
	my $file = sprintf("%s/%02dz%06dx%06d.jpg", $dir, $z, $x, $y);
	$debug and print "debug: check of $file\n";
	-s $file and next;
	--$get < 0 and last;
	my $req = HTTP::Request->new(GET=>+"$base&x=$x&y=$y");
	$debug and print "debug: fetch from ".$req->uri."\n";
	my $res = $ua->request($req);
	unless ($res->is_success) {
	    print "fail fetch from $file: ", $res->status_line, "\n";
	    next;
	}
	if (open(my $fh, ">", $file)) {
	    $debug and print "debug: write of $file\n";
	    binmode $fh;
	    print $fh $res->content;
	    close $fh;
	} else {
	    print "fail open in $file: $!\n";
	}
    }
}
$get < 0 and print "reach the getting limit, skip after all.\n";

printf "creating %dX%d image...\n", 256*$dx, 256*$dy;
my $image = new GD::Image(256*$dx, 256*$dy);
for (my $x=$sx; $x < $ex; $x++) {
    for (my $y=$sy; $y < $ey; $y++) {
	my $file = sprintf("%s/%02dz%06dx%06d.jpg", $dir, $z, $x, $y);
	$debug and print "debug: check of $file\n";
	-s $file or next;
	$debug and print "debug: read of $file\n";
	my $part = GD::Image->newFromJpeg($file);
	$debug and print "debug: image copy\n";
	$image->copy($part, 256*($x-$sx), 256*($y-$sy), 0, 0, 256, 256);
    }
}
#$image->string(gdSmallFont, 0, 0, $cmdline, $image->colorAllocate(255, 255, 255));
open(my $fh, ">", $output) or die "fail open $output: $!";
$debug and print "debug: write of $output\n";
binmode $fh;
print $fh $image->jpeg();
close $fh;

例えば秋葉原とか

perl gmwall.pl -sx=116423 -sy=51603 -ex=116427 -ey=51606

駅だけとか

perl gmwall.pl -sx=465701 -sy=206420 -ex=465705 -ey=206423 -z=19

使う数値はfirebugなどで拾ってください。

2009-03-18

公明党都議選重視?

コピーして、test.htaのような拡張子HTAで保存

HTAプログラム

 ↓

<html&gt;

<head&gt;

<style type="text/css"&gt;dt{float:left;clear:left;width:10em;}</style&gt;

<meta content="charset=Shift_JIS"/&gt;

</head&gt;

<body&gt;

<script type="text/javascript"&gt;</p&gt; <p&gt;window.onload = init;</p&gt; <p&gt;var url = [</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/h19sangiin/san_kekka/h19san_hkai.html"&gt;http://www.senkyo.metro.tokyo.jp/h19sangiin/san_kekka/h19san_hkai.html</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/h17shugiin/sokuhou/7kaijyo_s.htm"&gt;http://www.senkyo.metro.tokyo.jp/h17shugiin/sokuhou/7kaijyo_s.htm</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/h17togisen/sokuhou/2kaijyo_s.htm"&gt;http://www.senkyo.metro.tokyo.jp/h17togisen/sokuhou/2kaijyo_s.htm</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/data/h16san_hkai.html"&gt;http://www.senkyo.metro.tokyo.jp/data/h16san_hkai.html</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/data/h15shu_hkai.html"&gt;http://www.senkyo.metro.tokyo.jp/data/h15shu_hkai.html</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/data/data01_01_03.html"&gt;http://www.senkyo.metro.tokyo.jp/data/data01_01_03.html</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/data/data01_02_05.html"&gt;http://www.senkyo.metro.tokyo.jp/data/data01_02_05.html</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/data/data03_04.html"&gt;http://www.senkyo.metro.tokyo.jp/data/data03_04.html</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/data/data01_05_05.html"&gt;http://www.senkyo.metro.tokyo.jp/data/data01_05_05.html</a&gt;"</p&gt; <p&gt;];</p&gt; <p&gt;var base = "<a href="http://www.senkyo.metro.tokyo.jp/data/tokuhyo_23ku/"&gt;http://www.senkyo.metro.tokyo.jp/data/tokuhyo_23ku/</a&gt;";</p&gt; <p&gt;var file = ["chiyoda","chuou","minato","shinjyuku","bunkyo",</p&gt; <p&gt; "taitho","sumida","koutho","sinagawa","meguro",</p&gt; <p&gt; "ohta","setagaya","shibuya","nakaono","suginami",</p&gt; <p&gt; "toshima","kita","arakawa","itabashi","nerima",</p&gt; <p&gt; "adachi","katushika","edogawa"];</p&gt; <p&gt;for(var i=0; i<23; i++){</p&gt; <p&gt; url.push(base + file[i] + "\.html");</p&gt; <p&gt;}</p&gt; <p&gt;var id = [</p&gt; <p&gt; "2007 参院比", "2005 衆院比", "2005 都議会", "2004 参院比", "2003 衆院比",</p&gt; <p&gt; "2001 参院比", "2001 都議会", "2000 衆院比", "1998 参院比", "1997 都議会"</p&gt; <p&gt;];</p&gt; <p&gt;var ku = [</p&gt; <p&gt; "千代田","中央","港","新宿","文京",</p&gt; <p&gt; "台東","墨田","江東","品川","目黒",</p&gt; <p&gt; "大田","世田谷","渋谷","中野","杉並",</p&gt; <p&gt; "豊島","北","荒川","板橋","練馬",</p&gt; <p&gt; "足立","葛飾","江戸川"</p&gt; <p&gt;];</p&gt; <p&gt;var regexku = new RegExp("(" + ku.join("|") + ")区");</p&gt; <p&gt;var iframe = [];</p&gt; <p&gt;var data = {};</p&gt; <p&gt;var parse = [ function(){</p&gt; <p&gt; var d = iframe[0].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.nodeValue)){</p&gt; <p&gt; for(var j=0, e=td[i]; j<10; j++){</p&gt; <p&gt; e = e.nextSibling;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "0"] = e.firstChild.firstChild.nodeValue.replace(/\.\d+/,"");</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[1].contentWindow.document;</p&gt; <p&gt; var nobr = d.getElementsByTagName("nobr");</p&gt; <p&gt; for(var i=0, l=nobr.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(nobr[i].firstChild.nodeValue)){</p&gt; <p&gt; for(var j=0, e=nobr[i].parentNode; j<4; j++){</p&gt; <p&gt; e = e.nextSibling;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "1"] = e.firstChild.nodeValue;</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[2].contentWindow.document;</p&gt; <p&gt; var nobr = d.getElementsByTagName("nobr");</p&gt; <p&gt; for(var i=0, l=nobr.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(nobr[i].firstChild.nodeValue) &amp;&amp; nobr[i].parentNode.tagName == "SPAN"){</p&gt; <p&gt; for(var j=0, e=nobr[i]; j<6; j++){</p&gt; <p&gt; e = e.parentNode;</p&gt; <p&gt; }</p&gt; <p&gt; var e2 = e.nextSibling.nextSibling.firstChild.childNodes[2].firstChild;</p&gt; <p&gt; var k = 0;</p&gt; <p&gt; data[RegExp.$1 + "2"] = 0;</p&gt; <p&gt; while(e2){</p&gt; <p&gt; if(e2.firstChild.firstChild.nodeValue.indexOf("公明党") != -1){</p&gt; <p&gt; data[RegExp.$1 + "2"] += parseInt(e2.parentNode.nextSibling.childNodes[k+2].firstChild.nodeValue.replace(",",""), 10);</p&gt; <p&gt; }</p&gt; <p&gt; e2 = e2.nextSibling;</p&gt; <p&gt; k++;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "2"] = int2str(data[RegExp.$1 + "2"]);</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[3].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.nodeValue)){</p&gt; <p&gt; for(var j=0, e=td[i]; j<19; j++){</p&gt; <p&gt; e = e.nextSibling;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "3"] = e.firstChild.firstChild.nodeValue.replace(/\.\d+/,"");</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[4].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; var regexku2 = /(大田|世田谷|練馬|足立|江戸川)/;</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.nodeValue)){</p&gt; <p&gt; data[RegExp.$1 + "4"] = td[i].nextSibling.nextSibling.firstChild.nodeValue.replace(/\.\d+/,"");</p&gt; <p&gt; continue;</p&gt; <p&gt; }</p&gt; <p&gt; if(regexku2.test(td[i].firstChild.nodeValue)){</p&gt; <p&gt; data[RegExp.$1 + "4"] = (data[RegExp.$1 + "4"] || 0) </p&gt; <p&gt; + parseInt(td[i].nextSibling.nextSibling.firstChild.nodeValue.replace(",","").replace(/\.\d+/,""));</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; for(var j=0; j<5; j++){</p&gt; <p&gt; data[ku[[10,11,19,20,22][j]]+"4"] = int2str(data[ku[[10,11,19,20,22][j]]+"4"]);</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[5].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.firstChild.nodeValue)){</p&gt; <p&gt; for(var j=0, e=td[i]; j<10; j++){</p&gt; <p&gt; e = e.nextSibling;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "5"] = e.firstChild.firstChild.nodeValue.replace(/\.\d+/,"");</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[6].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.firstChild.nodeValue)){</p&gt; <p&gt; for(var j=0, e=td[i]; j<7; j++){</p&gt; <p&gt; e = e.nextSibling;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "6"] = e.firstChild.firstChild.nodeValue.replace(/\.\d+/,"").replace("-","0");</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[7].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.firstChild.nodeValue)){</p&gt; <p&gt; for(var j=0, e=td[i]; j<9; j++){</p&gt; <p&gt; e = e.nextSibling;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "7"] = e.firstChild.firstChild.nodeValue;</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[8].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.firstChild.nodeValue)){</p&gt; <p&gt; data[RegExp.$1 + "8"] = int2str(td[i].nextSibling.firstChild.firstChild.firstChild.nodeValue);</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(n){ return function(){</p&gt; <p&gt; var d = iframe[n+9].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; data[ku[n]+"9"] = 0;</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if((((td[i].firstChild || 0).firstChild || 0).nodeValue || "").indexOf("公明") == 0){</p&gt; <p&gt; data[ku[n]+"9"] += parseInt(td[i].parentNode.lastChild.firstChild.firstChild.nodeValue.replace(",",""));</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; data[ku[n]+"9"] = int2str(data[ku[n]+"9"]);</p&gt; <p&gt; show();</p&gt; <p&gt;}}];</p&gt; <p&gt;function init(){</p&gt; <p&gt; for(var i=0; i<23; i++){</p&gt; <p&gt; var dl = document.createElement("dl");</p&gt; <p&gt; dl.appendChild(document.createTextNode("\n【" + ku[i] + "区における公明票】\n"));</p&gt; <p&gt; for(var j=0; j<10; j++){</p&gt; <p&gt; var dt = document.createElement("dt");</p&gt; <p&gt; var dd = document.createElement("dd");</p&gt; <p&gt; dt.innerText = id[j];</p&gt; <p&gt; dl.appendChild(dt);</p&gt; <p&gt; dl.appendChild(dd);</p&gt; <p&gt; }</p&gt; <p&gt; document.body.firstChild.appendChild(dl);</p&gt; <p&gt; }</p&gt; <p&gt; for(var i=0; i<32; i++){</p&gt; <p&gt; var e = document.createElement("iframe");</p&gt; <p&gt; iframe[i] = e;</p&gt; <p&gt; e.style.display = "none";</p&gt; <p&gt; if(i<9) var f = parse[i];</p&gt; <p&gt; else var f = parse[9](i-9);</p&gt; <p&gt; e.attachEvent("onload", f);</p&gt; <p&gt; e.src = url[i];</p&gt; <p&gt; document.body.appendChild(e);</p&gt; <p&gt; }</p&gt; <p&gt;}</p&gt; <p&gt;function show(){</p&gt; <p&gt; for(var i=0; i<23; i++){</p&gt; <p&gt; var dl = document.body.firstChild.childNodes[i];</p&gt; <p&gt; for(var j=0; j<10; j++){</p&gt; <p&gt; var dt = dl.childNodes[j*2+1];</p&gt; <p&gt; dt.innerText = id[j] + " " + (data[ku[i]+j] || "");</p&gt; <p&gt; dt.nextSibling.innerText = bar(data[ku[i]+j], j);</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt;}</p&gt; <p&gt;function int2str(num){</p&gt; <p&gt; return new String(num).split("").reverse().join("").replace(/(\d{3})/g,"$1,").split("").reverse().join("");</p&gt; <p&gt;}</p&gt; <p&gt;function bar(str, flag){</p&gt; <p&gt; str = str || "";</p&gt; <p&gt; if(str == "" || str.length < 5) return "";</p&gt; <p&gt; var num = parseInt(str.match(/\d+/)) + 1;</p&gt; <p&gt; var arrow = (flag == 2 || flag == 6 || flag == 9) ? " ←" : "";</p&gt; <p&gt; var _bar = new Array(num).join("|") + arrow;</p&gt; <p&gt; return _bar;</p&gt; <p&gt;}</p&gt; <p&gt;</script&gt;

</body&gt;

</html&gt;

2009-03-06

http://anond.hatelabo.jp/20090306140645

それ、ユーザースタイルシートで、と思った。

IEってどうやるんだっけ?

base.css

.refererlist .box-curve p {
  text-indent: 0;
}

らしい。

2009-02-18

常に卵の側に(ハアレツに寄せられたコメント

http://anond.hatelabo.jp/20090218005155

村上春樹:「常に卵の側に」( http://www.haaretz.com/hasen/spages/1064909.html )でハアレツに寄せられたコメントの一部です。


http://www.haaretz.com/hasen/objects/pages/ResponseDetails.jhtml?resNo=4542207&amp;itemno=1064909&amp;cont=2

Title: To Mr. Murakami: a few words of reply from an egg

Name: A Philosopher

City: State:

First, let me welcome you to the region. Second, I would like to disagree with you about your description of literature as a skilful lie. A lie must, by definition, involve malice, deception, whereas literature is about imagination: there is no malice about that. Unfortunately, much of what you hear lately on international TV about Israel are indeed lies, not even fiction. You say that Israel is the wall and the Palestinians are the eggs, just because we have Tanks. You tend to forget that the Palestinians are part of more than one billion Muslims in the world, many of whom would like to get rid of Israel if they just could. You also forget that if the situation were reversed and the Palestinians were instead in possession of tanks, there wouldn`t be any eggs left in the middle-east. The wall we build is exactly to protect us, as eggs, from the wolf lurking outside. And If the terrorists didn`t use their own eggs as shield, they wouldn`t break either. All the best to you.

題:村上さんに卵からいくつかの回答

まずは、中東までご苦労さまでした。で、技巧に富んだ嘘として文学を称された件については賛成できません。嘘とはその定義によれば、悪意やごまかしを含んでいるのに対し、文学想像力に関するものであり、悪意はありません。不幸にもイスラエルに関してあなたが国際報道で目にしたことはまったくの嘘であり、創作でさえありません。イスラエルは壁でパレスチナは卵だとおっしゃられますが、たまたま戦車が私たちにあっただけです。お忘れのようですがパレスチナは10億以上の人口を抱えるイスラム世界の一部です。その多くがもし可能ならイスラエルを消滅させたいと願っています。逆の立場で考えればパレスチナ人戦車を持ったら中東から卵は消え去る事も思い出して下さい。外をうろつく狼から身を守るためだけに私たちは壁を作ったのです。テロリスト自分のところの卵を人間の盾に仕立てなければ、割れることもなかったでしょう。

ごきげんよう


http://www.haaretz.com/hasen/objects/pages/ResponseDetails.jhtml?itemno=1064909&amp;resNo=4543094

Title: Like Quixote tilting at windmills

Name: Fed Up

City: Barcelona State:

I don`t doubt that this fellow`s books may be addictive, but I do doubt the value of getting hooked on stories that are all, apparently, based on a false ontology of the world being clearly divided into "walls" and "eggs." As talkback #1 points out, even tank-drivers have their fragility, and to deny their humanity by summarily labeling them "walls," and considering them to be part of some chimerical menace called "the system," is to paint a thin veneer of chivalry over a rotten base of moral recklessness.

What`s been going on in Sderot over the last several years? Have Gazans, driven to desperation by the evil system-monster, been left with no option but to toss their eggs against the walls that surround them? Is it evil for people on the receiving end to retreat unto bomb-shelters (aka "walls") against which these eggs can`t help but break?

Mr. Murakami, walls don`t break eggs unless there is someone throwing those eggs.

題:まるでドンキホーテ

彼の本がやみつきになるのは私も否定しないが、与太話、明らかに間違った本体論、つまり「壁」と「卵」とに世界を分類するというのは何の意味もない。1番目のコメントが指摘するように戦車の兵士だって(卵のように)壊れやすい。あっさり彼らを「壁」とひとくくりして、「システム」という名のでっちあげた脅威にしたてるなんて、わけわからん理由で廃屋に挑む騎士のようなもんだ。スデロット(Sderot)でここ何年もなにが起きている?ガザ連中は悪のシステムモンスターのせいでやけっぱちのやけくそ自分とこの卵をぐるりと囲む壁に投げつけたというのだろうか?シェルターに追いつめられた(これも「壁」だよね、卵は仕方なしに投げつけられて壊れる)人々が邪悪だって?村上さん、誰かが卵を投げなければ壁は卵を壊さないんだよ。


http://www.haaretz.com/hasen/objects/pages/ResponseDetails.jhtml?itemno=1064909&amp;resNo=4543134

Title: wall &amp; eggs

Name: JR

City: Amsterdam State:

bit folish to say that the only option is that the hurt civilians are the eggs and the israeli tank and bombs are the wall. Never thought that the israel people are the eggs in a small basket called eretz jisrael which is surrounded by a rather large muslim wall?

No fiction here mr , just hard facts.

Kind regards from the Netherlands

題:壁と卵

負傷した人々が卵でイスラエル戦車爆弾が壁だとしか言えないなんてちょっとまぬけだね。もっと大きいムスリムの壁に包囲されたイスラエルの地(eretz jisrael)という小さなかごにいる人たちが卵だって考えなかったのかね?フィクションじゃないよ、ちゃんとした事実だ。


http://www.haaretz.com/hasen/objects/pages/ResponseDetails.jhtml?itemno=1064909&amp;resNo=4543210

Title: re #5

Name: B

City: SF State: CA

I get where you`re coming from because I`m tired of utopian solutions from dreamers in Europe.

But I believe Murakami is a guy who also understands the tank driver and our kids in Sderot. I know we`re not used to having media acknowledge our citizens as people, so we get defensive, but I give Mr. Murakami the benefit of the doubt.

From his speech I feel he`s criticizing the entire system that has our neighbors trying to destroy us in the first place and the world legitimizing it and the common acceptance of boycotting Israel because it`s the in thing to do. This guy is acknowledging our fight to overcome this as individuals and as societies.

This guy is deeper than our critics from Europe, and this guy is a novelist, not a critic.

In Norwegian Wood he painted a really accurate picture of some self-righteous university organizations, quite similar to many of our critics. All I`m saying is before dismissing him or arguing, see that he`s not picking fights or sides.. besides us eggs

題:「ドンキホーテ」のコメント主へ

ヨーロッパ連中が言うユートピア的解決にはもう飽き飽きしちゃうよね。

村上戦車の兵士やスデロット子供たちも理解していると思う。メディアはぼくらを人間あつかいしないから、防戦一方だけど。でも村上さんに対して性急な判断は控えたい。ぼくらのご近所さんイスラエル破壊しようとしている事、世界がそれを正当化しようとしている事、イスラエルボイコットの考えが一般化する事を強制するシステム全体を非難しているようにぼくには思えた。こいつは僕らの戦いが個人として、社会として克服されるって事を知ってる。

ヨーロッパ評論家よりずっとわかってるし、彼は小説家であって評論家じゃない。

ノルウェイの森に出てくる独善的な学生運動家は評論家連中みたいで、きっちり描かれている。彼のことをくさす前に、論争を挑んだり一方の側につくつもりがないのを理解しないと。

http://anond.hatelabo.jp/20090218160043

かんよう-く くわん― 3 【慣用句

(1)二語以上が結合し、その全体が一つの意味を表すようになって固定したもの。「道草を食う」「耳にたこができる」の類。慣用語。イディオム

(2)二語以上が、きまった結びつきしかしない表現。「間髪を入れず」「悦に入る」の類。慣用語。イディオム

http://dictionary.goo.ne.jp/search.php?MT=%B4%B7%CD%D1%B6%E7&amp;kind=jn&amp;mode=0&amp;base=1&amp;row=0

文型・・・

2009-01-22

空き巣

正式には「空き巣狙い」と言うらしい。

http://dictionary.goo.ne.jp/search.php?MT=%B6%F5%A4%AD%C1%E3&kind=jn&mode=0&base=1&row=1

留守の家をねらって忍び込み、盗みをすること。また、その人。あきす。

盗まれる対象が金品や貴重品だけとは限らなくなっているのが最近の怖いところだな。

特に、「自分しか使わないから」とユーザIDパスワードブラウザに保存しまくってる人などは、場合によっては免許証預金通帳を盗まれるよりも深刻なダメージを受ける事になりそうだな。物や金と違って、盗まれた事そのものが発覚する可能性も低いだろうし。

2008-12-17

フィギュアスケートスコアの解説

http://anond.hatelabo.jp/20081217003010

(追記)今の採点ルールが導入された経緯

採点が分からないという声に対して。

ソルトレークシティでの採点疑惑というものがあったのが直接のきっかけだったと思いますが、詳しい経緯はWikipediaあたりを参照してもらうとして、新採点方式の方針は、曖昧さの排除です。そうすることで、技術的に正しい事をやっている選手が勝つようにするという事です。技術点何点、芸術点何点というのでは、演技の中でなにが得点に貢献しているのかさっぱり分からないので、それを各要素に分解して評価しようと言うものだと解釈してます。先シーズン導入され、浅田真央選手が受けていたロングエッジ(Wrong Edge = 間違ったエッジ)判定の導入もその流れにあると思われます。

その結果、転倒した選手が優勝する事も増え、一見ルールが分かりにくくなったと言えるでしょう。しかし、新採点方式のもとでは確実にジャンプ以外のスピンステップスパイラルレベル(難易度という意味での)が上がったと言えるでしょう。

今、旧採点方式の競技のビデオYoutubeなどでみると、ジャンプ以外のスキル現在レベルより低いものが多いです。ジャンプも旧採点では回転不足でも認定されがちです。競技としてのフィギュアスケートは、新採点方式の導入で確実に向上したと言えるのではないでしょうか。

各要素ごとに採点する新採点方式に対し、演技全体を評価する旧採点方式は、観客から見たときの分かりやすさが優れているのは確かなのですが、新採点にもこのようなメリットがあるのです。

(追記ここまで)

スコアの読み方

ルールと採点の仕方を理解する事でフィギュアスケートの今の状況を俯瞰出来るようにと解説を書いてみます。

最初に、このPDFダウンロードしてください。

http://www.isuresults.com/results/gpf0809/gpf0809_SeniorLadies_FS_Scores.pdf

これは国際スケート連盟(ISU)のサイトに出ているリザルトつまり結果なのですが、このPDFは先日行なわれたグランプリファイナルシニア女子部門のフリースケーティング(FS)におけるスコア集となってます。ここには、そのスコアがどのように計算されて出たのかの詳細が表となって各選手ごと、フリースケーティングの順位順に並んでいます。

最初の一ページ目から見ましょう。Mao Asadaとありますね。名前の横にJPNと書いてり、その右に線で区切られて Total Segment Score = 123.17とあるはずです。これがFSの得点にあたる部分です。略してTSSと言います。今回、浅田選手は123.17点をFSで取ったということです。

その右の Total Element Score + 64.57 は略してTESと呼ばれます。これは旧採点における技術点と言われるのですが、直訳すると「要素の点の合計」でしてこちらの解釈の方が正しいと思います。新採点方式では各要素(女子の場合はジャンプステップスパイラルスピンの4種類の要素があります。FSではステップ1回、スパイラル1回、スピン3回、ジャンプ7回の合計12個の要素をこなします)ごとにその要素の難しさに応じた点数とGOE(Grade of Excusionの略で日本語にすると技の出来映えになります) に応じた点数がつけられます。それらを合計したものがTESなのです。

TESの右の Total Program Component Score + 59.60 はコンポーネントの点数の合計です。略す時はPCSとなります。このコンポーネントは5つあり、ファイブコンポーネントとも呼ばれています。日本語ではしばしばプログラム構成点と言われる事もあります。TESは要素の点数の合計なのですが、PCSプログラム構成という字面から分かる通り、演技全体を5つの軸から評価するものです。ですから表現力の点数とされています。

最後に Total Dedcutions です。減点にあたります。減点は転倒したときにつきます。1.00となってるのは3F(トリプルフリップ)で転倒があったからですね。そのほかにも演技時間オーバーなどでつく時があります。

ここまではテレビ放送でも表示される部分です。どのようなものかお分かりになったでしょうか。

次にうつります。今まで見てきたものの下を見ると、なにやら記号が表になってならんでますね。1〜12までの番号が振ってある記号は、各要素になります。要素がこなされた順番に並んでいます。1番をみると3A-2Tとなっています。これは浅田選手演技の最初に跳んだトリプルアクセル-ダブルトゥループというコンビネーションジャンプを表しています。ジャンプの記号は「回転数」+「ジャンプの種類(A = アクセル、Lz = ルッツ、F = フリップLo = ループ、S = サルコー、T = トゥループ)」で表されているのですね。

要素名が書いてある右の9.50は Base Value、基礎点です。各要素にあらかじめ決められている点数のことです。この要素はコンビネーションジャンプなので、3Aの8.20と2Tの1.30を合計した9.50点となっているわけです。さて、その右の0.80にうつりたいと思います。これは先程も述べたGOE、要素の出来映えの点数です。これには+と-があり今回は0.80点の+となっています。つまり出来映えの良いジャンプだったということです。

このGOEは複数の審判によって採点されます。それが右の The Judges Panel です。点数が 1 1 2 1 0… と並んでいますが、これはそれぞれのジャッジがつけたGOEの点数なのです。それらの平均がGOEとなりますが、その前に何人かの審判の採点は抽選であらかじめ採用されないことが決まっています。基礎点とGOEを加えた点数が10.30で、この要素の点数です。

ジャンプ以外の要素はSpと最後の数字の前についているものが、スピンStステップ。SpSqはスパイラルです。最後の数字はその要素のレベルを表します。レベルは1〜4で、トップ選手となるとステップレベル3で、そのほかはレベル4が当たり前、それ以下だった場合は取りこぼしと言われてしまいます。

ジャンプでついている<の記号はDG(ダウングレード)、日本語では回転不足を表します。基礎点は一つ下の回転数となり、GOEも引かれます。つまり二重に減点される構造があります。そのため回転は足りている3回転ジャンプの転倒は、回転が不足しているがきちんとした着地のジャンプの点数とほぼ同じになることがあります。例えばカロリーナ・コストナーの4番目の要素の3Loの要素点(基礎点+GOE)は2.0。そこから転倒による減点があるのでこのジャンプは1.0の価値があるわけです。一方、安藤美姫の2つめの要素3Fは1.16。安藤選手の3Fは着地が少々乱れた面はあるものの転倒はしてないのですが、点数はほとんど同じです。この問題はショートプログラム(SP)で浅田選手コンビネーションジャンプの二回目が回転不足となったためにジャンプが一回転になってしまったキムヨナ選手に順位で負けたことの原因です。

TESの解説でもう疲れたのでPCSの解説はしませんが、TESの読み方が分かれば理解可能だと思います。

より詳細なことを知りたい方はこちらのホームページへ。まぁこちらに私の書いた事すべてあるんですが。。。

http://www.geocities.co.jp/Athlete-Athene/9074/index.html

ニコニコフィギュアスケートを見ると、各要素の点数が要素が実行された後にコメントとして表示されるので、フィギュアスケート勉強に便利です。もちろんこれはリザルトの結果を書いているので、生放送中には出来ないのですがね。

これでリザルトの読み方が分かったと思いますが、これが分かるといろいろなものが見えてきます。今回の結果のみならず、他の大会男子のものを見ると、フィギュアスケート界の採点の歪みが見えて来ます。このままではスポーツとして危ういという現状があります。バンクーバーオリンピックは問題はないでしょうが、次のオリンピックでは実施競技から外されてしまうのではないかという危機感がフィギュアスケートファンの中にはあります。

以下、私個人の考えるフィギュアスケート界の問題

を書こうとして疲れたからもういいや、また今度!

要は二つで、

  • 採点基準が曖昧かつ不公平…に見える
  • 採点基準が試合によって変わりまくる

元増田に対するツッコミ

安藤美姫選手には4S、やって欲しいです。それが彼女へのプレッシャーになってると言えばそうなんですが、それでもやってほしい。最高難度のジャンプが練習でかなりの確率で出来るのに試合で回避するってのはスポーツであるフィギュアスケートにとって良くない事だと思うんですよね。フィギュアスケートスポーツであることを止めたくないなら、高難度の技への挑戦をしやすくなる方向に競技全体を持って行かないと、と。

2008-09-04

http://anond.hatelabo.jp/20080904204100

配列の宣言がキモいよぉ。なんで「要素数-1」なんだよぉ。

option base 1で。

なんで「イコール」と「代入」が同じ「=」なんだよぉ。

まぁ確かに。BASICはそういう言語なんだ。

紛らわしい評価はさせないことだな。

2008-06-29

見出しの最後が「や」だったら、阪神タイガースの記事

秋田祭り鳥谷安打で竜と7差や」

http://sports.yahoo.co.jp/hl?c=npb&a=20080629-00000023-dal-base

結構気になるんだけど、……や、というのが阪神タイガースの記事の見出しになっていることが多い。

なんか、そういう決まりでもあるんだろうか。

大阪で発行されている新聞でも……やと書いてあるのだろうか。

九州出身で、東京住まいの俺には、……や、というのが、わざとらしく感じる。

2008-03-23

違和感を感じる」って国語辞典の中に例文として載ってるんだけど

http://dictionary.goo.ne.jp/search.php?MT=%B0%E3%CF%C2%B4%B6&kind=jn&mode=0&base=1&row=0

増田達のやりとりが皮肉や風刺の類なのか判断しかねるから困る。

やっぱ日本語は難しい。

2008-02-27

Joel On Software私訳

訳してみた。あらためて、和訳はものすごく時間を要する作業だということがわかった。もうしないと思う。

注意:以下は意訳、適当訳、稚拙訳であり、誤訳を多々含んでいることは確実であり、Joel氏が本当に以下のように述べているとは限りません。

なぜMicrosoft Officeファイルフォーマットはこんなにもややこしいのか (そしてその対処法を幾つか)

Tuesday, February 19, 2008

先週、MicrosoftOfficeバイナリフォーマットを公開したが、このフォーマットは殆ど正気でないように見える。Excel 97-2003ファイルフォーマットは349ページのPDFファイルだ。でも待って、それで全部じゃない。このドキュメントには次の面白いコメントが書いてある。

それぞれのExcelワークブックは1つのcompound fileに収められている

つまり、Excel 97-2003ファイルはOLE coumpound documentで、それは結局、1つのファイル内にあるファイルシステムである。これは、理解するのにあと9ページはスペックを読まなくちゃならないぐらいには十分に複雑だ。そしてこれらの「スペック」は、普通我々が考えるようなスペックというよりは、Cデータ構造みたいに見える。これ全体が階層的ファイルシステムなのだ。

もしあなたが週末を、Wordドキュメントブログインポートしたり、あなたの個人的な財務データからExcelフォーマットスプレッドシートを生成するような気の利いたコードを書くのに使おうと思ってこれらのドキュメントを読み始めたなら、このスペックのややこしさと長さがそんな気をあっという間に失せさせるだろう。普通プログラマはこのOfficeバイナリファイルフォーマットについて次のような結論を下す:

この4つ全てについて、きみは間違っている。ちょっとだけ掘り下げて、これらのファイルフォーマットがどうしてこんなに信じがたいくらいに複雑なのか、なぜMicrosoftの悪いプログラミングを反映しているのではないのか、そしてそれを回避するためにあなたに何ができるか、を明らかにしよう。

理解すべき最初のことは、これらのバイナリファイルフォーマットはちょっと違ったデザインゴールを持って設計されたということだ。たとえばHTMLとは。

これらはすごく古いコンピュータで速く処理できるようにデザインされた。Excel for Windowsの初期のバージョンでは、1MBのRAM、20MHz動作の80386が Excelを快適に走らせることができるための妥当なものだった。このファイルフォーマット内には、ファイルを素早く開いたり閉じたりするための最適化が沢山仕込まれている:

これはライブラリを使うことを想定して設計されている。もしあなたがバイナリインポートするものを1から書き上げたいと思ったら、Windows Metafile Format (何か図を描く場合) や OLE Counpound Storage みたいなものをサポートしなくてはいけなくなる。もしあなたが Windows上でやるのなら、そうしたことをたいしたことのない作業にするためのライブラリサポート存在する... そういったフィーチャーを使うことは(元々)マイクロソフトチームのためのショートカットだった。でもあなたが全部を自分でスクラッチから書くなら、全部の作業を自分自身でやらなくてはいけない。

オフィスはcompound documentsに対して広範囲のサポートを持っている。例えば、スプレッドシートWord文書に埋め込んだりできる。完璧Wordファイルフォーマットのparserは、同じように、埋め込まれたスプレッドシートで何かインテリジェントなことが出来るべきだろう。

それは相互協調性(interoperability)を意識してデザインされてはいない。仮定されていたのは、WordファイルフォーマットWordからのみ読み書きされなくてはいけない、ということで、それは当時においては十分に合理的なものだった。これは、Wordチームのプログラマファイルフォーマットをどう変更するかについて決定を行う場合にはいつでも、彼らが気にするのは (a)何が高速か (b)Wordコードベースにおいて最小の行数になるのは何か、だったことを意味する。SGMLHTML-interchangeableといった標準ファイルフォーマットのようなアイデアは、最初にインターネットドキュメントの相互交換を実現するまで現実のものにはならなかった。それはOfficeバイナリフォーマットが最初に考案されてから10年後のことだったのだ。ドキュメントを交換するのにインポーターエクスポーターを使うことができるという仮定が常にあった。実際Wordは簡便な交換のために設計されたRTFと呼ばれるフォーマットを持っており、そのフォーマットは殆ど最初のころからあり、今も100%サポートされている。

それはアプリケーションの全ての複雑さを反映していなくてはいけない。 全部のチェックボックス、全部のフォーマッティングオプション、そして全部の、Microsoft Officeのフィーチャーは、ファイルフォーマットのどこかで叙述されていなくてはいけない。Wordパラグラフメニューにある、"Keep With Next" と呼ばれるチェックボックス、これはパラグラフを、その後ろのパラグラフと同じページに置くのに必要な場合は、次のページに移動させるもの(?)だが、これもファイルフォーマットの中に無くてはいけない。そしてこれはつまり、あなたがWordドキュメントを正しく読み込める完璧Wordクローンを実装したいなら、そういったフィーチャーを実装しなくてはいけないということだ。Wordドキュメントをロードする競争力のあるワードプロセッサを作っているのなら、ファイルフォーマットからそのビットをロードするコードを書くのには1分しかかからないかもしれないが、ページのレイアウトアルゴリズムをそれに対応させるのに何週間もかかるかもしれない。もしあなたがそうしない場合、カスタマーがあなたのクローンWordファイルを読み込んだら、全部のページがぐちゃぐちゃになってしまうだろう。

それはアプリケーション歴史を反映していなくてはいけない。 このファイルフォーマットに見られる多くの複雑さは、古く、複雑で、愛されず、めったに使われないフィーチャーを反映している。それらはファイルフォーマットのなかに後方互換性のためにまだあり、そしてMicrosoftにとってその辺りのコードを残しておくことには何らコストはかからない。しかしあなたがこれらのファイルフォーマットをparseおよびwriteする一貫した完全な仕事をしたいと思うなら、Microsoftインターンが15年前にやったのと同じことを全て、またやらなくてはいけない。要点は、何千人年の仕事が今のWordExcelには費やされてきたのであり、これらのアプリケーション完璧クローンを作りたいと本当に欲するなら、あなたは何千人年を費やさなくてはならないことになる、ということだ。ファイルフォーマットは単に、アプリケーションサポートする全てのフィーチャーの簡潔なサマリーなのだ。

手始めに、小さな例を一つ、深く見てみよう。Excelのワークシートは色々なタイプのBIFFレコードの集まったものだ。私はスペックの一番最初のBIFFを見てみたい。1904と呼ばれるレコードだ。

Excelファイルフォーマット仕様のこのレコードについての記述は非常に曖昧なものだ。そこでは単に、1904レコードが「1904日付システムが使われているかどうか」を示すレコードだ、と述べているだけだ。ああ、使えない仕様書の典型的な一例だ。あなたがExcelファイルフォーマットで何かしている開発者で、そしてファイルフォーマット仕様にこう書いてあるのを見つけたなら、あなたがMiocrosoftは何かを隠しているのだと結論付けたとしても無理はない。この情報の断片は十分な情報をあなたに与えはしない。あなたには幾ばくか外部の情報が必要で、私は今ここで、それを提供しよう。Excelワークシートには、2種類ある。日付のエポックが1900/1/1のもの(これには、Lotus 1-2-3 との互換性のために故意に入れられた閏年に関するバグがあるが、ここでそれについて述べるのは退屈すぎる)、および、1904/1/1のものだ。Excelは両方をサポートしているが、それはExcelの最初のバージョンMac版であり、それは単に簡単だったという理由でOSエポックを使っていて、しかしWindows版のExcel1-2-3ファイルインポートできなくてはならず、そしてそれは1900/1/1をエポックとして採用していたからだ。あなたが涙ぐむのも無理はない。歴史のどの時点においても、プログラマが正しいことをしなかった、という時はないのだが、しかし現実にあなたが手にしているものはこれなのだ。

1900と1904のファイルタイプは両方とも世の中には広く存在しており、それは通常、ファイルWindowsMacのどちらで作られたかによる。一方のタイプから他方のタイプへ黙って変換するのはIntegrity的に問題があるので、Excelファイルタイプを変換することをしない。Excelファイルをparseするためには、あなたは両方を扱わなくてはならない。それはファイルからこのbitをロードするだけの問題ではなく、あなたが日付表示と両方のエポックを扱うparsingのコードまで書き直さなくてはいけないということを意味する。実装には何日かかかるだろうと私は思う。

実際、あなたがExcelクローンの作業をするなら、日付の扱いについて、あらゆる種類の微妙ディティール発見することになるだろう。Excelは日付の値をいつ変換するのか? 表示の整形はどうやっているのか? なぜ1/31は今年の January 31と翻訳され、また一方で1/50はJanuary 1st, 1950と翻訳されるのか? Excelソースコードと同じだけの量のドキュメントを書かないがぎり、振る舞いに関しての微妙ビットを全て完全に記述することはできない。

そしてこのレコードは、あなたが扱う何百もあるBIFFレコードの最初の1つに過ぎず、しかももっとも単純なものなのだ。他のレコードの殆どは、より多くのプログラマーを涙に暮れさせるぐらいには十分複雑だ。

唯一導き得る結論はこれだ。

MicrosoftMicrosoftOfficeファイルフォーマットリリースしたことは大変有用なことだが、しかしそれでOfficeファイルフォーマットインポートしたり保存したりするのが楽になるということは全く無さそうだ。それらは狂気じみて複雑で、リッチアプリケーションで、そしてあなたは人気のある20%の部分を実装して80%の人々を幸せにするというくらいのことしかできない。バイナリファイル仕様によってなされるのは、多く見積もっても、著しく複雑なシステムリバースエンジニアリングにかかる時間を何分か削減するくらいだろう。

オーケー, 私はいくつか回避法を教えると約束した。良いニュースは、殆どの良く知られたアプリケーションにとって、Officeバイナリファイルフォーマットを読み書きしようと試みることは誤った決定だということだ。あなたが真剣に考えなくてはいけない代案が2つある。Officeそのものにそれをやらせるか、書き込むのが簡単なファイルフォーマットを使うかだ。

ヘビーな仕事Officeにやらせよう。WordExcelは実に完全なオブジェクトモデルを持っており、COMオートメーションの手段が可能で、これであなたは何でもプログラムでやるようにできる。多くのシチュエーションでは、Office内のコードを再利用するほうがそれを実装しようとするよりも良い。ここにいくつか例がある。

  1. Webベースアプリケーションがあって、それが既存のWordファイルPDFフォーマットに出力するようにする必要がある場合、それを実装するにはこうする: ファイルを読み込んでからWord 2007のビルトインのPDFエクスポーターを使ってそれをPDFとして保存する、数行のWord VBAコードだ。あなたはこのコードIISで動作しているASPASP.NETコードから直接呼び出す。これでうまくいく。最初にWordを立ち上げるときは数秒かかる。2回目はCOMサブシステムによりWordはまたあなたがそれを必要としたときのためにメモリ中にキープされている。それは通常のWebベースアプリケーションにとっては十分に速い。
  2. 上と同じ。ただしあなたのWebホスティング環境Linuxだった場合。フルライセンスWordインストールされたWindows 2003サーバを買う。そしてその仕事をする小さなWebサービスを構築する。C#ASP.NETでの半日の作業だ。
  3. 上と同じ、ただしあなたがよりスケールさせたいと望む場合。ステップ2で構築した全部のボックスの前にロードバランサーを置きなさい。コードは必要ない。

この手のアプローチは、全ての種類の一般的なOfficeタイプについての、サーバ上であなたがやりたいと思うであろうアプリケーションで、うまくいくだろう。例えば:

これらのケースの全てにおいて、Officeオブジェクトインタラクティブ動作でないことを教えてやる方法があり、だから表示をアップデートするのに煩わされたり、ユーザ入力を促す必要はない。ところで、このようなやりかたでいく場合には、gotchas(?)がいくつかあり、そしてそれはMicrosoftは公式にサポートしているものではない。だからあなたがそれを始める前にはKnowledge baseの記事を読むように。

書き込むファイルにはもっとシンプルフォーマットを使いなさい。単にOfficeドキュメントプログラムで生成したいなら、殆どいつでもOfficeバイナリフォーマットよりももっと良いフォーマットWordExcelでも問題なく開くことができるようなフォーマット存在する。

いずれにせよ、全てのOfficeファイルを完全に読み書きできるような、文字通りのOffice競合製品を作ろうとする(その場合には、何千年もの作業があなたに予約される) のでない限り、Officeバイナリフォーマットの読み書きをするというのは、何であれあなたが解決しようとしている問題を解決するためのもっとも労働集約的な方法だ。

2008-02-07

twitter

━━ n., v. さえずり[る]; わななき[く]; くすくす笑い[う]; そわそわ(する); さえずるように[ぺちゃくちゃ]しゃべる ((on, about)).

be all of a twitter ひどくそわそわしている.

twit・ter・er ━━ n.

twit・ter・y ━━ a. そわそわ[いらいら]した; よくさえずる.

(http://dictionary.goo.ne.jp/search.php?MT=twit&kind=ej&mode=0&base=1&row=5)

twit

━━ n., vt. (-tt-) 非難(する), なじる(こと); あざける[り] ((about, on, with)).

━━ n. 〔俗〕 くだらない人間, ばか.

(http://dictionary.goo.ne.jp/search.php?MT=twit&kind=ej&mode=0&base=1&row=0)

(http://dictionary.goo.ne.jp/search.php?MT=twit&kind=ej&mode=0&base=1&row=1)

2007-11-13

Re: anond:20071113180745

un alimento a base di semola o farina、つまりセモリナ小麦粉からできたマンマです。

麺はpastasciuttaということばがあります。

2007-11-08

Re: オブジェクト指向におけるFizzBuzz問題

http://blogs.wankuma.com/episteme/archive/2007/11/08/106927.aspx

かなりテキトー。エラー処理とかしない。


package Animal;
sub new      { bless { cnt => 1 } , $_[0] }
sub Sound    { printf "%s\n", $_[0]->{voice} x $_[0]->{cnt}  }
sub SetCount { $_[0]->{cnt}   = $_[1]; $_[0] }
sub SetVoice { $_[0]->{voice} = $_[1]; $_[0] }

package Dog;
use base qw/Animal/;
sub new { $_[0]->SUPER::new->SetVoice('Wan') }

package Cat;
use base qw/Animal/;
sub new { $_[0]->SUPER::new->SetVoice('Nya-') }

my $animal;
$animal = Dog->new;
$animal->Sound;
$animal->SetCount(3);
$animal->Sound;
$animal = Cat->new;
$animal->Sound;

わん、にゃーが文字化けしたのでローマ字で。

2007-11-01

PerlClass::Data::Inheritableの解析

唐突にClass::Data::Inheritableのソースコードについて説明してやんよ。

使い方とかの説明はこの辺でも読んでから出直して来い、ごるぁ!

まぁとりあえずソース見てみろ、下記にはっつけてやっからよぉ!


 1: package Class::Data::Inheritable;
 2:
 3: use strict qw(vars subs);
 4: use vars qw($VERSION);
 6: $VERSION = '0.06';
 7: 
 8: sub mk_classdata {
 9:     my ($declaredclass, $attribute, $data) = @_;
10: 
11:     if( ref $declaredclass ) {
12:         require Carp;
13:         Carp::croak("mk_classdata() is a class method, not an object method");
14:     }
15: 
16:     my $accessor = sub {
17:         my $wantclass = ref($_[0]) || $_[0];
18: 
19:         return $wantclass->mk_classdata($attribute)->(@_)
20:           if @_>1 &amp;&amp; $wantclass ne $declaredclass;
21: 
22:         $data = $_[1] if @_>1;
23:         return $data;
24:     };
25: 
26:     my $alias = "_${attribute}_accessor";
27:     *{$declaredclass.'::'.$attribute} = $accessor;
28:     *{$declaredclass.'::'.$alias}     = $accessor;
29: }
30: 
31: 1;

短いソースだなーこれ。でもな、なめんじゃねーぞ。短いけど色々な技術が盛り込まれてんだよコレはよぉ。

ハイ、まず3行目。

かるくstrictについて説明してやんよ。心して聞けよオマエラ。

strictっつーのはだな、つまりPerlにおける曖昧な部分をすこーしだけチェックしてくれるスグレモノなんだなコレが。

とりあえずざっくり言うと三つの機能があってだな、下記のよーに書くわけだ。


 use strict 'vars';
 use strict 'subs';
 use strict 'refs';

varsってーのは簡単に言うとmyとかourとか宣言しろボケってやつですわ。

subsは裸体は許さんってやつですの、$とか%とかついていない裸の文字列をエラーにしてくれんだよ。

refsってのが一番やっかいな代物でな、これはムツカシイ言葉で言うとシンボリックリファレンスってんだが、要は変数名に変数を使うとエラーにしてくれるってこったよ。

で、これら全部ひっくるめてuse strict;なんだな。わかったか?オラ!

ちゅーことはだ、3行目を見ると意図的にrefsだけ外してるのがわかるよな。

つまりコレはこのコードのどこかで変数名に変数を使うってことを明示していることにもなるわけだ。けけけ。

あーもういいもういい、次だ、次。

4,5行目を見てみろよ。今時our使わずにuse vars使うなんてどんだけー

ははは、まぁまてよ。

ourってのは明示的にグローバル変数を定義するもんなんだが、このourってやつが導入されたのがPerl5.6からなんだよ。

Perl5.5のころはourなんてなかったからグローバル変数定義すんのにこのuse varsを使っていたわけだ。

つまりこのモジュールはPerl5.5環境でも動くように配慮しているわけなんだな、ちゃんちゃん。ほほほ。

あーもう全然すすまねーよ。チクショウ、が、ま・・・・。

で、11-14行目。これはref関数使って$declaredclassがオブジェクトだったら死ぬって処理だ。

require CarpっつーのはCarpモジュールを動的にロードしてるっていうことだよぅ。

で、Carp::croak関数使ってエラー文はいて死ぬ、と。ちなみにこのCarp::croakってはまぁdie関数みたいなもんなんだ。

違いとしてはエラーの発生した原因を呼び出し元の奴のせいにして自分は悪くないんだよってアピールすることかな。まぁ実際使ってみりゃわかるよ。

さぁ、16行目。本編突入だ。長かった。長い道のりだったなお前ら。

sub {}ってのは無名サブルーチン(関数リファレンス)ってやつだ。で、ここで注目すべき点はただひとつ!!!!!

19-23行目あたりをぼーっとみてると$declaredclass, $attribute, $dataっていう変数を使用していることがわかる。

これらの変数は9行目で受け取ったmk_classdataへの引数だ。

ここで問題が発生する。

ダダダダン!ダダダダン!ここで問題が発生する!

myで宣言された変数賞味期限スコープの終端だ。それはわかるな?

つまり9行目で宣言された$declaredclass, $attribute, $dataといった変数どもは29行目のスコープの終端で消滅してしまうわけだ。

しかし!その消えてしまうはずの変数どもをsub {}という無名サブルーチンの中で使用してしまっている!!!

これが世間一般に語られているクロージャという仕組みなのだ!!!!!!うはははははははh!!!

本来生涯をまっとうするはずだった変数たちが別のサブルーチンの中にまぎれてしまうとその別のサブルーチンが消えてなくなるまでは死ぬことを許されなくなるのである!!!ざ・不☆老☆不☆死!

なんたる奇妙奇天烈なことであるが、この現実を受け入れることによってお前らの道が開けるんだ!!!すげーだろぉがよぉ!!

ボクはッ、キミがッ、クロージャを受け入れるまでッ、殴るのをやめないッ!

さて、肝心の16-24行目のアクセサ部分の処理の解説だけども、

引数が渡されてなければ特になんの処理もせずに$dataを返している。$dataってのは死ぬことを許されなくなったカワイソウな変数君だ。

つまり、Class::Data::Inheritableってやつはアクセサに渡された値をどこで保存してるのかというと、紛れも無いこの$data君に他ならない。

$data君がニート君になっちゃうとたちまちデータの読み書きができなくなるのであまり働かせ過ぎないように注意しよーね!

ハイ、次はアクセサに引数が渡された時の処理だけどな、20行目を見てみろ。$declaredclassに格納されてる値はmk_classdataメソッドを使用したときに格納された値になる。


 package Hoge;
 use base qw/Class::Data::Inheritable/;
 Hoge->mk_classdata('hoge_accessor');

つまり上記の処理で例えると、$declaredclassには'Hoge'という文字列が入ってることになんだな。

で、この'Hoge'と$wantclassに入ってる値を比較しているわけだが、


 package Hoge;
 use base qw/Class::Data::Inheritable/;
 Hoge->mk_classdata('hoge_accessor');
 
 Hoge->hoge_accessor('aaa');

上記の処理で例えると$wantclassには$declaredclassと同じく'Hoge'が入ってくることになんだな。うっひょー。

んで、20行目のif文は$wantclassと$declaredclasが違う場合にだけ19行目の処理を実行しているわけだからこの場合はスルーするわけだぁ。ひょひょひょ。

じゃあだな、$wantclassと$declaredclasが違う場合ってどんな場合?ってことだが、下記に例を示すから目ん玉引ん剥いて網膜から直接見てみろよこのボケ野郎どもが。


 package Hoge;
 use base qw/Class::Data::Inheritable/;
 Hoge->mk_classdata('hoge_accessor');
 
 package Foo;
 use base qw/Hoge/;
 
 Foo->hoge_accessor('bbb');

HA!HA!HA!こういう場合だよ米ベー。$wantclass=Fooで$declaredclas=Hogeになるんで19行を実行し、Fooをベースにしてmk_classdataを呼ぶことでFooに同じ名前の新たなアクセサを提供し、元クラスHogeの値を壊さないようにするわけですなぁ。

考えた人すごいですなぁ。これがClass::Data::Inheritableが継承可能なクラス変数といわれる由縁でするまする。

で、最後の26-28行目はコレらの便利な処理をしてくれる$accessorさんをクラスに登録するというわけですよぉ。

27,28行目の*ってのは型グロブ変数ってという奴で、型グロブに対して無名サブルーチンを突っ込むと動的に関数を定義できるんだなぁコレが。

でここで、初めに俺が語った話を覚えてるか?へっ、オマエラなら覚えてないだろうなけっけ。use strictの話だよ。refsだよrefs。

ここでrefsを省いていたのが利いて来るんだ。refsって何だった?ホラ言ってミソ?

うんうん。変数名に変数を使えないようにするだったね。

で良く見てみると型グロブ変数に対して「$declaredclass.'::'.$attribute」っていう変数を使おうとしているよね?これをしたかったからrefsだけ仲間外れにしてたわけですね。

はは。

あー、あー、あー。

これで終わりだよぅ。みんなわかったかな!?

コレ読んでもわからんやつはもう死ぬか、もしくはわからん用語について死ぬほど調べてもっかい読みなおしてみろこのド低のぅッ・・・ごふんごふん、このクサレ脳みそがぁ!!!!!!!!!!!!11

プログラ増田のあなぐら

2007-08-25

Diary/2007-08-24 - August Dojin Data Base

Blog主への連絡は済んでいる様だから、次は

Niftyに連絡してみればいいんじゃないかと思った

多分画像削除される

2007-08-22

http://anond.hatelabo.jp/20070822165701

@data=(a,b,c);print@data
#!/usr/bin/perl
use strict;
my @data = qw(a b c);

my $cx = scalar @data;
my $si = 0;
my $ax;
LOOP:
    $ax = $data[$si];
    print $ax;
    $si++;
not --$cx or goto LOOP;
#!/usr/bin/perl
use strict;
my @data = qw(a b c);

package AtoH;
use base qw(Tie::Handle);
sub TIEHANDLE {
    my $class = shift;
    return bless {data => [@_]}, $class;
}
sub READLINE {
    return shift @{shift->{data}};
}

package main;
tie *ARGV, 'AtoH', @data;
while (<>) {
    print;
}

2007-08-14

Base Ball Baerのレーベル内ページで「ドラマチック」のブラバンスコアが配布されてるの、気づかれてるのだろうか

2007-07-19

/* Ten */
if (typeof(Ten) == 'undefined') {
    Ten = {};
}
Ten.NAME = 'Ten';
Ten.VERSION = 0.06;

/* Ten.Class */
Ten.Class = function(klass, prototype) {
    if (klass && klass.initialize) {
	var c = klass.initialize;
    } else if(klass && klass.base) {
        var c = function() { return klass.base[0].apply(this, arguments) };
    } else {
	var c = function() {};
    }
    c.prototype = prototype || {};
    c.prototype.constructor = c;
    Ten.Class.inherit(c, klass);
    if (klass && klass.base) {
        for (var i = 0;  i < klass.base.length; i++) {
	    var parent = klass.base[i];
            if (i == 0) {
                c.SUPER = parent;
                c.prototype.SUPER = parent.prototype;
            }
            Ten.Class.inherit(c, parent);
            Ten.Class.inherit(c.prototype, parent.prototype);
        }
    }
    return c;
}
Ten.Class.inherit = function(child,parent) {
    for (var prop in parent) {
        if (typeof(child[prop]) != 'undefined' || prop == 'initialize') continue;
        child[prop] = parent[prop];
    }
}

/*
// Basic Ten Classes
**/

/* Ten.JSONP */
Ten.JSONP = new Ten.Class({
    initialize: function(uri,obj,method) {
        if (Ten.JSONP.Callbacks.length) {
            setTimeout(function() {new Ten.JSONP(uri,obj,method)}, 500);
            return;
        }
        var del = uri.match(/\?/) ? '&' : '?';
        uri += del + 'callback=Ten.JSONP.callback';
        if (!uri.match(/timestamp=/)) {
            uri += '&' + encodeURI(new Date());
        }
        if (obj && method) Ten.JSONP.addCallback(obj,method);
        this.script = document.createElement('script');
        this.script.src = uri;
        this.script.type = 'text/javascript';
        document.getElementsByTagName('head')[0].appendChild(this.script);
    },
    addCallback: function(obj,method) {
        Ten.JSONP.Callbacks.push({object: obj, method: method});
    },
    callback: function(args) {
        // alert('callback called');
        var cbs = Ten.JSONP.Callbacks;
        for (var i = 0; i < cbs.length; i++) {
            var cb = cbs[i];
            cb.object[cb.method].call(cb.object, args);
        }
        Ten.JSONP.Callbacks = [];
    },
    MaxBytes: 8000,
    Callbacks: []
});

/* Ten.XHR */
Ten.XHR = new Ten.Class({
    initialize: function(uri,opts,obj,method) {
        if (!uri) return;
        this.request = Ten.XHR.getXMLHttpRequest();
        this.callback = {object: obj, method: method};
        var xhr = this;
        var prc = this.processReqChange;
        this.request.onreadystatechange = function() {
            prc.apply(xhr, arguments);
        }
        var method = opts.method || 'GET';
        this.request.open(method, uri, true);
        if (method == 'POST') {
            this.request.setRequestHeader('Content-Type',
                                          'application/x-www-form-urlencoded');
        }
        var data = opts.data ? Ten.XHR.makePostData(opts.data) : null;
        this.request.send(data);
    },
    getXMLHttpRequest: function() {
        var xhr;
        var tryThese = [
            function () { return new XMLHttpRequest(); },
            function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
            function () { return new ActiveXObject('Microsoft.XMLHTTP'); },
            function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); },
        ];
        for (var i = 0; i < tryThese.length; i++) {
            var func = tryThese[i];
            try {
                xhr = func;
                return func();
            } catch (e) {
                //alert(e);
            }
        }
        return xhr;
    },
    makePostData: function(data) {
        var pairs = [];
        var regexp = /%20/g;
        for (var k in data) {
            var v = data[k].toString();
            var pair = encodeURIComponent(k).replace(regexp,'+') + '=' +
                encodeURIComponent(v).replace(regexp,'+');
            pairs.push(pair);
        }
        return pairs.join('&');
    }
},{
    processReqChange: function() {
        var req = this.request;
        if (req.readyState == 4) {
            if (req.status == 200) {
                var cb = this.callback;
                cb.object[cb.method].call(cb.object, req);
            } else {
                alert("There was a problem retrieving the XML data:\n" +
                      req.statusText);
            }
        }
    }
});

/* Ten.Observer */
Ten.Observer = new Ten.Class({
    initialize: function(element,event,obj,method) {
        var func = obj;
        if (typeof(method) == 'string') {
            func = obj[method];
        }
        this.element = element;
        this.event = event;
        this.listener = function(event) {
            return func.call(obj, new Ten.Event(event || window.event));
        }
        if (this.element.addEventListener) {
            if (this.event.match(/^on(.+)$/)) {
                this.event = RegExp.$1;
            }
            this.element.addEventListener(this.event, this.listener, false);
        } else if (this.element.attachEvent) {
            this.element.attachEvent(this.event, this.listener);
        }
    }
},{
    stop: function() {
        if (this.element.removeEventListener) {
            this.element.removeEventListener(this.event,this.listener,false);
        } else if (this.element.detachEvent) {
            this.element.detachEvent(this.event,this.listener);
        }
    }
});

/* Ten.Event */
Ten.Event = new Ten.Class({
    initialize: function(event) {
        this.event = event;
    },
    keyMap: {
        8:"backspace", 9:"tab", 13:"enter", 19:"pause", 27:"escape", 32:"space",
        33:"pageup", 34:"pagedown", 35:"end", 36:"home", 37:"left", 38:"up",
        39:"right", 40:"down", 44:"printscreen", 45:"insert", 46:"delete",
        112:"f1", 113:"f2", 114:"f3", 115:"f4", 116:"f5", 117:"f6", 118:"f7",
        119:"f8", 120:"f9", 121:"f10", 122:"f11", 123:"f12",
        144:"numlock", 145:"scrolllock"
    }
},{
    mousePosition: function() {
        if (!this.event.clientX) return;
        return Ten.Geometry.getMousePosition(this.event);
    },
    isKey: function(name) {
        var ecode = this.event.keyCode;
        if (!ecode) return;
        var ename = Ten.Event.keyMap[ecode];
        if (!ename) return;
        return (ename == name);
    },
    targetIsFormElements: function() {
        var target = this.event.target;
        if (!target) return;
        var T = (target.tagName || '').toUpperCase();
        return (T == 'INPUT' || T == 'SELECT' || T == 'OPTION' ||
                T == 'BUTTON' || T == 'TEXTAREA');
    },
    stop: function() {
        var e = this.event;
        if (e.stopPropagation) {
            e.stopPropagation();
            e.preventDefault();
        } else {
            e.cancelBubble = true;
            e.returnValue = false;
        }
    }
});

/* Ten.DOM */
Ten.DOM = new Ten.Class({
    getElementsByTagAndClassName: function(tagName, className, parent) {
        if (typeof(parent) == 'undefined') {
            parent = document;
        }
        var children = parent.getElementsByTagName(tagName);
        if (className) { 
            var elements = [];
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                var cls = child.className;
                if (!cls) {
                    continue;
                }
                var classNames = cls.split(' ');
                for (var j = 0; j < classNames.length; j++) {
                    if (classNames[j] == className) {
                        elements.push(child);
                        break;
                    }
                }
            }
            return elements;
        } else {
            return children;
        }
    },
    removeEmptyTextNodes: function(element) {
        var nodes = element.childNodes;
        for (var i = 0; i < nodes.length; i++) {
            var node = nodes[i];
            if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) {
                node.parentNode.removeChild(node);
            }
        }
    },
    nextElement: function(elem) {
        do {
            elem = elem.nextSibling;
        } while (elem && elem.nodeType != 1);
        return elem;
    },
    prevElement: function(elem) {
        do {
            elem = elem.previousSibling;
        } while (elem && elem.nodeType != 1);
        return elem;
    },
    scrapeText: function(node) {
        var rval = [];
        (function (node) {
            var cn = node.childNodes;
            if (cn) {
                for (var i = 0; i < cn.length; i++) {
                    arguments.callee.call(this, cn[i]);
                }
            }
            var nodeValue = node.nodeValue;
            if (typeof(nodeValue) == 'string') {
                rval.push(nodeValue);
            }
        })(node);
        return rval.join('');
    },
    onLoadFunctions: [],
    loaded: false,
    timer: null,
    addEventListener: function(event,func) {
        if (event != 'load') return;
        Ten.DOM.onLoadFunctions.push(func);
        Ten.DOM.checkLoaded();
    },
    checkLoaded: function() {
        var c = Ten.DOM;
        if (c.loaded) return true;
        if (document && document.getElementsByTagName &&
            document.getElementById && document.body) {
            if (c.timer) {
                clearInterval(c.timer);
                c.timer = null;
            }
            for (var i = 0; i < c.onLoadFunctions.length; i++) {
                    c.onLoadFunctions[i]();
            }
            c.onLoadFunctions = [];
            c.loaded = true;
        } else {
            c.timer = setInterval(c.checkLoaded, 13);
        }
    }
});

/* Ten.Style */
Ten.Style = new Ten.Class({
    applyStyle: function(elem, style) {
        for (prop in style) {
            elem.style[prop] = style[prop];
        }
    }
});

/* Ten.Geometry */
Ten.Geometry = new Ten.Class({
    initialize: function() {
        if (Ten.Geometry._initialized) return;
        var func = Ten.Geometry._functions;
        var de = document.documentElement;
        if (window.innerWidth) {
            func.getWindowWidth = function() { return window.innerWidth; }
            func.getWindowHeight = function() { return window.innerHeight; }
            func.getXScroll = function() { return window.pageXOffset; }
            func.getYScroll = function() { return window.pageYOffset; }
        } else if (de && de.clientWidth) {
            func.getWindowWidth = function() { return de.clientWidth; }
            func.getWindowHeight = function() { return de.clientHeight; }
            func.getXScroll = function() { return de.scrollLeft; }
            func.getYScroll = function() { return de.scrollTop; }
        } else if (document.body.clientWidth) {
            func.getWindowWidth = function() { return document.body.clientWidth; }
            func.getWindowHeight = function() { return document.body.clientHeight; }
            func.getXScroll = function() { return document.body.scrollLeft; }
            func.getYScroll = function() { return document.body.scrollTop; }
        }
        Ten.Geometry._initialized = true;
    },
    _initialized: false,
    _functions: {},
    getScroll: function() {
        if (!Ten.Geometry._initialized) new Ten.Geometry;
        return {
            x: Ten.Geometry._functions.getXScroll(),
            y: Ten.Geometry._functions.getYScroll()
        };
    },
    getMousePosition: function(pos) {
        // pos should have clientX, clientY same as mouse event
        if ((navigator.userAgent.indexOf('Safari') > -1) &&
            (navigator.userAgent.indexOf('Version/') < 0)) {
            return {
                x: pos.clientX,
                y: pos.clientY
            };
        } else {
            var scroll = Ten.Geometry.getScroll();
            return {
                x: pos.clientX + scroll.x,
                y: pos.clientY + scroll.y
            };
        }
    },
    getElementPosition: function(e) {
        return {
            x: e.offsetLeft,
            y: e.offsetTop
        };
    },
    getWindowSize: function() {
        if (!Ten.Geometry._initialized) new Ten.Geometry;
        return {
            w: Ten.Geometry._functions.getWindowWidth(),
            h: Ten.Geometry._functions.getWindowHeight()
        };
    }
});

/* Ten.Position */
Ten.Position = new Ten.Class({
    initialize: function(x,y) {
        this.x = x;
        this.y = y;
    },
    subtract: function(a,b) {
        return new Ten.Position(a.x - b.x, a.y - b.y);
    }
});

/*
// require Ten.js
**/

/* Ten.SubWindow */
Ten.SubWindow = new Ten.Class({
    initialize: function() {
        var c = this.constructor;
        if (c.singleton && c._cache) {
            return c._cache;
        }
        var div = document.createElement('div');
        Ten.Style.applyStyle(div, Ten.SubWindow._baseStyle);
        Ten.Style.applyStyle(div, c.style);
        this.window = div;
        this.addContainerAndCloseButton();
        document.body.appendChild(div);
        if (c.draggable) {
            this._draggable = new Ten.Draggable(div, this.handle);
        }
        if (c.singleton) c._cache = this;
        return this;
    },
    _baseStyle: {
        color: '#000',
        position: 'absolute',
        display: 'none',
        zIndex: 2,
        left: 0,
        top: 0,
        backgroundColor: '#fff',
        border: '1px solid #bbb'
    },
    style: {
        padding: '2px',
        textAlign: 'center',
        borderRadius: '6px',
        MozBorderRadius: '6px',
        width: '100px',
        height: '100px'
    },
    handleStyle: {
        position: 'absolute',
        top: '0px',
        left: '0px',
        backgroundColor: '#f3f3f3',
        borderBottom: '1px solid #bbb',
        width: '100%',
        height: '30px'
    },
    containerStyle: {
        margin: '32px 0 0 0',
        padding: '0 10px'
    },
    // closeButton: 'close.gif',
    closeButton: 'http://s.hatena.com/images/close.gif',
    closeButtonStyle: {
        position: 'absolute',
        top: '8px',
        right: '10px',
        cursor: 'pointer'
    },
    _baseScreenStyle: {
        position: 'absolute',
        top: '0px',
        left: '0px',
        display: 'none',
        zIndex: 1,
        overflow: 'hidden',
        width: '100%',
        height: '100%'
    },
    screenStyle: {},
    showScreen: true,
    singleton: true,
    draggable: true,
    _cache: null
},{
    screen: null,
    windowObserver: null,
    visible: false,
    addContainerAndCloseButton: function() {
        var win = this.window;
        var c = this.constructor;
        var div = document.createElement('div');
        win.appendChild(div);
        Ten.Style.applyStyle(div, c.containerStyle);
        this.container = div;
        if (c.handleStyle) {
            var handle = document.createElement('div');
            Ten.Style.applyStyle(handle, c.handleStyle);
            win.appendChild(handle);
            this.handle = handle;
        }
        if (c.closeButton) {
	    var btn = document.createElement('img');
            btn.src = c.closeButton;
            btn.alt = 'close';
            Ten.Style.applyStyle(btn, c.closeButtonStyle);
            win.appendChild(btn);
            new Ten.Observer(btn, 'onclick', this, 'hide');
            this.closeButton = btn;
        }
        if (c.showScreen) {
            var screen = document.createElement('div');
            Ten.Style.applyStyle(screen, Ten.SubWindow._baseScreenStyle);
            Ten.Style.applyStyle(screen, c.screenStyle);
            document.body.appendChild(screen);
            this.screen = screen;
            new Ten.Observer(screen, 'onclick', this, 'hide');
        }
    },
    show: function(pos) {
        pos = (pos.x && pos.y) ? pos : {x:0, y:0};
        with (this.window.style) {
            display = 'block';
            left = pos.x + 'px';
            top = pos.y + 'px';
        }
        if (this.screen) {
            with (this.screen.style) {
                display = 'block';
                left = Ten.Geometry.getScroll().x + 'px';
                top = Ten.Geometry.getScroll().y + 'px';
            }
        }
        this.windowObserver = new Ten.Observer(document.body, 'onkeypress', this, 'handleEscape');
        this.visible = true;
    },
    handleEscape: function(e) {
        if (!e.isKey('escape')) return;
        this.hide();
    },
    hide: function() {
        if (this._draggable) this._draggable.endDrag();
        this.window.style.display = 'none';
        if (this.screen) this.screen.style.display = 'none';
        if (this.windowObserver) this.windowObserver.stop();
        this.visible = false;
    }
});

/* Ten.Draggable */
Ten.Draggable = new Ten.Class({
    initialize: function(element,handle) {
        this.element = element;
        this.handle = handle || element;
        this.startObserver = new Ten.Observer(this.handle, 'onmousedown', this, 'startDrag');
        this.handlers = [];
    }
},{
    startDrag: function(e) {
        if (e.targetIsFormElements()) return;
        this.delta = Ten.Position.subtract(
            e.mousePosition(),
            Ten.Geometry.getElementPosition(this.element)
        );
        this.handlers = [
            new Ten.Observer(document, 'onmousemove', this, 'drag'),
            new Ten.Observer(document, 'onmouseup', this, 'endDrag'),
            new Ten.Observer(this.element, 'onlosecapture', this, 'endDrag')
        ];
        e.stop();
    },
    drag: function(e) {
        var pos = Ten.Position.subtract(e.mousePosition(), this.delta);
        Ten.Style.applyStyle(this.element, {
            left: pos.x + 'px',
            top: pos.y + 'px'
        });
        e.stop();
    },
    endDrag: function(e) {
        for (var i = 0; i < this.handlers.length; i++) {
            this.handlers[i].stop();
        }
        if(e) e.stop();
    }
});

/* Hatena */
if (typeof(Hatena) == 'undefined') {
    Hatena = {};
}

/* Hatena.User */
Hatena.User = new Ten.Class({
    initialize: function(name) {
        this.name = name;
    },
    getProfileIcon: function(name) {
        if (!name) name = 'user';
        var pre = name.match(/^[\w-]{2}/)[0];
        var img = document.createElement('img');
        img.src = 'http://www.hatena.ne.jp/users/' + pre + '/' + name + '/profile_s.gif';
        img.alt = name;
        img.setAttribute('class', 'profile-icon');
        img.setAttribute('width','16px');
        img.setAttribute('height','16px');
        with (img.style) {
            margin = '0 3px';
            border = 'none';
            verticalAlign = 'middle';
        }
        return img;
    }
}, {
    profileIcon: function() {
        return Hatena.User.getProfileIcon(this.name);
    }
});

/* Hatena.Star */
if (typeof(Hatena.Star) == 'undefined') {
    Hatena.Star = {};
}

/*
// Hatena.Star.* classes //
**/
if (window.location && window.location.host.match(/hatena\.com/)) {
    Hatena.Star.BaseURL = 'http://s.hatena.com/';
} else {
    Hatena.Star.BaseURL = 'http://s.hatena.ne.jp/';
}
Hatena.Star.Token = null;

/* Hatena.Star.User */
Hatena.Star.User = new Ten.Class({
    base: [Hatena.User],
    initialize: function(name) {
        if (Hatena.Star.User._cache[name]) {
            return Hatena.Star.User._cache[name];
        } else {
            this.name = name;
            Hatena.Star.User._cache[name] = this;
            return this;
        }
    },
    _cache: {}
},{
    userPage: function() {
        return Hatena.Star.BaseURL + this.name + '/';
    }
});

/* Hatena.Star.Entry */
Hatena.Star.Entry = new Ten.Class({
    initialize: function(e) {
        this.entry = e;
        this.uri = e.uri;
        this.title = e.title;
        this.star_container = e.star_container;
        this.comment_container = e.comment_container;
        this.stars = [];
        this.comments = [];
    },
    maxStarCount: 11
},{
    flushStars: function() {
        this.stars = [];
        this.star_container.innerHTML = '';
    },
    bindStarEntry: function(se) {
        this.starEntry = se;
        for (var i = 0; i < se.stars.length; i++) {
            if (typeof(se.stars[i]) == 'number') {
                this.stars.push(new Hatena.Star.InnerCount(se.stars[i],this));
            } else {
                this.stars.push(new Hatena.Star.Star(se.stars[i]));
            }
        }
        if (se.comments && !this.comments.length) {
            for (var i = 0; i < se.comments.length; i++) {
                this.comments.push(new Hatena.Star.Comment(se.comments[i]));
            }
        }
        this.can_comment = se.can_comment;
    },
    setCanComment: function(v) {
        this.can_comment = v;
    },
    showButtons: function() {
        this.addAddButton();
        this.addCommentButton();
    },
    addAddButton: function() {
        if (this.star_container) {
            this.addButton = new Hatena.Star.AddButton(this);
            this.star_container.appendChild(this.addButton);
        }
    },
    addCommentButton: function() {
        if (this.comment_container) {
            this.commentButton = new Hatena.Star.CommentButton(this);
            this.comment_container.appendChild(this.commentButton.img);
        }
    },
    showStars: function() {
        var klass = this.constructor;
        // if (this.stars.length > klass.maxStarCount) {
        //     var ic = new Hatena.Star.InnerCount(this.stars.slice(1,this.stars.length));
        //     this.star_container.appendChild(this.stars[0]);
        //     this.star_container.appendChild(ic);
        //     this.star_container.appendChild(this.stars[this.stars.length - 1]);
        // } else {
        for (var i = 0; i < this.stars.length; i++) {
            this.star_container.appendChild(this.stars[i]);
        }
    },
    showCommentButton: function() {
        if (this.can_comment) {
            this.commentButton.show();
            if (this.comments.length) this.commentButton.activate();
        } else {
            // this.commentButton.hide();
        }
    },
    addStar: function(star) {
        this.stars.push(star);
        this.star_container.appendChild(star);
    },
    addComment: function(com) {
        if (!this.comments) this.comments = [];
        if (this.comments.length == 0) {
            this.commentButton.activate();
        }
        this.comments.push(com);
    },
    showCommentCount: function() {
        this.comment_container.innerHTML += this.comments.length;
    }
});

/* Hatena.Star.Button */
Hatena.Star.Button = new Ten.Class({
    createButton: function(args) {
        var img = document.createElement('img');
        img.src = args.src;
        img.alt = img.title = args.alt;
        with (img.style) {
	    cursor = 'pointer';
	    margin = '0 3px';
            padding = '0';
            border = 'none';
            verticalAlign = 'middle';
        }
        return img;
    }
});

/* Hatena.Star.AddButton */
Hatena.Star.AddButton = new Ten.Class({
    base: ['Hatena.Star.Button'],
    initialize: function(entry) {
        this.entry = entry;
        this.lastPosition = null;
        var img = Hatena.Star.Button.createButton({
            src: Hatena.Star.AddButton.ImgSrc,
            alt: 'Add Star'
        });
        this.observer = new Ten.Observer(img,'onclick',this,'addStar');
        this.img = img;
        return img;
    },
    ImgSrc: Hatena.Star.BaseURL + 'images/add.gif'
},{
    addStar: function(e) {
        this.lastPosition = e.mousePosition();
        var uri = Hatena.Star.BaseURL + 'star.add.json?uri=' + encodeURIComponent(this.entry.uri) +
            '&title=' + encodeURIComponent(this.entry.title);
        if (Hatena.Star.Token) {
            uri += '&token=' + Hatena.Star.Token;
        }
        new Ten.JSONP(uri, this, 'receiveResult');
    },
    receiveResult: function(args) {
        var name = args ? args.name : null;
        if (name) {
            this.entry.addStar(new Hatena.Star.Star({name: name}));
            //alert('Succeeded in Adding Star ' + args);
        } else if (args.errors) {
            var pos = this.lastPosition;
            pos.x -= 10;
            pos.y += 25;
            var scroll = Ten.Geometry.getScroll();
            var scr = new Hatena.Star.AlertScreen();
            var alert = args.errors[0];
            scr.showAlert(alert, pos);
        }
    }
});

/* Hatena.Star.CommentButton */
Hatena.Star.CommentButton = new Ten.Class({
    base: ['Hatena.Star.Button'],
    initialize: function(entry) {
        this.entry = entry;
        this.lastPosition = null;
        var img = Hatena.Star.Button.createButton({
            src: Hatena.Star.CommentButton.ImgSrc,
            alt: 'Comments'
        });
        img.style.display = 'none';
        this.observer = new Ten.Observer(img,'onclick',this,'showComments');
        this.img = img;
    },
    ImgSrc: Hatena.Star.BaseURL + 'images/comment.gif',
    ImgSrcActive: Hatena.Star.BaseURL + 'images/comment_active.gif'
},{
    showComments: function(e) {
        if (!this.screen) this.screen = new Hatena.Star.CommentScreen();
        this.screen.bindEntry(this.entry);
        var pos = e.mousePosition();
        pos.y += 25;
        this.screen.showComments(this.entry, pos);
    },
    hide: function() {
        this.img.style.display = 'none';
    },
    show: function() {
        this.img.style.display = 'inline';
    },
    activate: function() {
        this.show();
        this.img.src = Hatena.Star.CommentButton.ImgSrcActive;
    }
});

/* Hatena.Star.Star */
Hatena.Star.Star = new Ten.Class({
    initialize: function(args) {
        if (args.img) {
            this.img = args.img;
            this.name = this.img.getAttribute('alt');
        } else {
            this.name = args.name;
            var img = document.createElement('img');
            img.src = Hatena.Star.Star.ImgSrc;
            img.alt = this.name;
            with (img.style) {
                padding = '0';
                border = 'none';
            }
            this.img = img;
        }
	new Ten.Observer(this.img,'onmouseover',this,'showName');
	new Ten.Observer(this.img,'onmouseout',this,'hideName');
	if (this.name) {
            this.user = new Hatena.Star.User(this.name);
            this.img.style.cursor = 'pointer';
            new Ten.Observer(this.img,'onclick',this,'goToUserPage');
        }
        if (args.count && args.count > 1) {
            var c = document.createElement('span');
            c.setAttribute('class', 'hatena-star-inner-count');
            Ten.Style.applyStyle(c, Hatena.Star.InnerCount.style);
            c.innerHTML = args.count;
            var s = document.createElement('span');
            s.appendChild(img);
            s.appendChild(c);
            return s;
        } else {
            return this.img;
        }
    },
    ImgSrc: Hatena.Star.BaseURL + 'images/star.gif'
},{
    showName: function(e) {
        if (!this.screen) this.screen = new Hatena.Star.NameScreen();
        var pos = e.mousePosition();
        pos.x += 10;
        pos.y += 25;
        this.screen.showName(this.name, pos);
    },
    hideName: function() {
        if (!this.screen) return;
        this.screen.hide();
    },
    goToUserPage: function() {
        window.location = this.user.userPage();
    }
});

/* Hatena.Star.InnerCount */
Hatena.Star.InnerCount = new Ten.Class({
    initialize: function(count, e) {
        this.count = count;
        this.entry = e;
        var c = document.createElement('span');
        c.setAttribute('class', 'hatena-star-inner-count');
        Ten.Style.applyStyle(c, Hatena.Star.InnerCount.style);
        c.style.cursor = 'pointer';
        c.innerHTML = count;
        new Ten.Observer(c,'onclick',this,'showInnerStars');
        this.container = c;
        return c;
    },
    style: {
        color: '#f4b128',
        fontWeight: 'bold',
        fontSize: '80%',
        fontFamily: '"arial", sans-serif',
        margin: '0 2px'
    }
},{
    showInnerStars: function() {
        var url = Hatena.Star.BaseURL + 'entry.json?uri=' +
        encodeURIComponent(this.entry.uri);
        new Ten.JSONP(url, this, 'receiveStarEntry');
    },
    receiveStarEntry: function(res) {
        var se = res.entries[0];
        var e = this.entry;
        if (encodeURIComponent(se.uri) != encodeURIComponent(e.uri)) return;
        e.flushStars();
        e.bindStarEntry(se);
        e.addAddButton();
        e.showStars();
    }
});

/* Hatena.Star.Comment */
Hatena.Star.Comment = new Ten.Class({
    initialize: function(args) {
        this.name = args.name;
        this.body = args.body;
    }
},{
    asElement: function() {
        var div = document.createElement('div');
        with (div.style) {
            margin = '0px 0';
            padding = '5px 0';
            borderBottom = '1px solid #ddd';
        }
        var ico = Hatena.User.getProfileIcon(this.name);
        div.appendChild(ico);
        var span = document.createElement('span');
        with(span.style) {
            fontSize = '90%';
        }
        span.innerHTML = this.body;
        div.appendChild(span);
        return div;
    }
});

/* Hatena.Star.NameScreen */
Hatena.Star.NameScreen = new Ten.Class({
    base: [Ten.SubWindow],
    style: {
        padding: '2px',
        textAlign: 'center'
    },
    containerStyle: {
        margin: 0,
        padding: 0
    },
    handleStyle: null,
    showScreen: false,
    closeButton: null,
    draggable: false
},{
    showName: function(name, pos) {
        this.container.innerHTML = '';
        this.container.appendChild(Hatena.User.getProfileIcon(name));
        this.container.appendChild(document.createTextNode(name));
        this.show(pos);
    }
});

/* Hatena.Star.AlertScreen */
Hatena.Star.AlertScreen = new Ten.Class({
    base: [Ten.SubWindow],
    style: {
        padding: '2px',
        textAlign: 'center',
        borderRadius: '6px',
        MozBorderRadius: '6px',
        width: '240px',
        height: '120px'
    },
    handleStyle: {
        position: 'absolute',
        top: '0px',
        left: '0px',
        backgroundColor: '#f3f3f3',
        borderBottom: '1px solid #bbb',
        width: '100%',
        height: '30px',
        borderRadius: '6px 6px 0 0',
        MozBorderRadius: '6px 6px 0 0'
    }
},{
    showAlert: function(msg, pos) {
        this.container.innerHTML = msg;
        var win = Ten.Geometry.getWindowSize();
        var scr = Ten.Geometry.getScroll();
        var w = parseInt(this.constructor.style.width) + 20;
        if (pos.x + w > scr.x + win.w) pos.x = win.w + scr.x - w;
        this.show(pos);
    }
});

/* Hatena.Star.CommentScreen */
Hatena.Star.CommentScreen = new Ten.Class({
    base: [Ten.SubWindow],
    initialize: function() {
        var self = this.constructor.SUPER.call(this);
        if (!self.commentsContainer) self.addCommentsContainer();
        return self;
    },
    style: {
        width: '280px',
        height: '280px',
        overflowY: 'auto',
        padding: '2px',
        textAlign: 'center',
        borderRadius: '6px',
        MozBorderRadius: '6px'
    },
    handleStyle: {
        position: 'absolute',
        top: '0px',
        left: '0px',
        backgroundColor: '#f3f3f3',
        borderBottom: '1px solid #bbb',
        width: '100%',
        height: '30px',
        borderRadius: '6px 6px 0 0',
        MozBorderRadius: '6px 6px 0 0'
    },
    containerStyle: {
        margin: '32px 0 0 0',
        textAlign: 'left',
        padding: '0 10px'
    },
    getLoadImage: function() {
        var img = document.createElement('img');
        img.src = Hatena.Star.BaseURL + 'images/load.gif';
        img.setAttribute('alt', 'Loading');
        with (img.style) {
            verticalAlign = 'middle';
            margin = '0 2px';
        }
        return img;
    }
},{
    addCommentsContainer: function() {
        var div = document.createElement('div');
        with (div.style) {
            marginTop = '-3px';
        }
        this.container.appendChild(div);
        this.commentsContainer = div;
    },
    showComments: function(e, pos) {
        var comments = e.comments;
        if (!comments) comments = [];
        this.commentsContainer.innerHTML = '';
        for (var i=0; i<comments.length; i++) {
            this.commentsContainer.appendChild(comments[i].asElement());
        }
        if (e.starEntry && !e.can_comment) {
            this.hideCommentForm();
        } else {
            this.addCommentForm();
        }
        var win = Ten.Geometry.getWindowSize();
        var scr = Ten.Geometry.getScroll();
        var w = parseInt(this.constructor.style.width) + 20;
        if (pos.x + w > scr.x + win.w) pos.x = win.w + scr.x - w;
        this.show(pos);
    },
    bindEntry: function(e) {
        this.entry = e;
    },
    sendComment: function(e) {
        if (!e.isKey('enter')) return;
        var body = this.commentInput.value;
        if (!body) return;
        this.commentInput.disabled = 'true';
        this.showLoadImage();
        var url = Hatena.Star.BaseURL + 'comment.add.json?body=' + encodeURIComponent(body) +
            '&uri=' + encodeURIComponent(this.entry.uri) +
            '&title=' + encodeURIComponent(this.entry.title);
        new Ten.JSONP(url, this, 'receiveResult');
    },
    receiveResult: function(args) {
        if (!args.name || !args.body) return;
        this.commentInput.value = ''; 
        this.commentInput.disabled = '';
        this.hideLoadImage();
        var com = new Hatena.Star.Comment(args);
        this.entry.addComment(com);
        this.commentsContainer.appendChild(com.asElement());
    },
    showLoadImage: function() {
        if (!this.loadImage) return; 
        this.loadImage.style.display = 'inline';
    },
    hideLoadImage: function() {
        if (!this.loadImage) return; 
        this.loadImage.style.display = 'none';
    },
    hideCommentForm: function() {
        if (!this.commentForm) return;
        this.commentForm.style.display = 'none';
    },
    addCommentForm: function() {
        if (this.commentForm) {
            this.commentForm.style.display = 'block';
            return;
        }
        var form = document.createElement('div');
        this.container.appendChild(form);
        this.commentForm = form;
        with (form.style) {
            margin = '0px 0';
            padding = '5px 0';
            // borderTop = '1px solid #ddd';
        }
        //if (Hatena.Visitor) {
        //    form.appendChild(Hatena.Visitor.profileIcon());
        //} else {
        //    form.appendChild(Hatena.User.getProfileIcon());
        //}
        var input = document.createElement('input');
        input.type = 'text';
        with (input.style) {
            width = '215px';
	    border = '1px solid #bbb';
            padding = '3px';
        }
        form.appendChild(input);
        this.commentInput = input;
        var img = this.constructor.getLoadImage();
        this.loadImage = img;
        this.hideLoadImage();
        form.appendChild(img);
        new Ten.Observer(input,'onkeypress',this,'sendComment');
    }
});

/* Hatena.Star.EntryLoader */
Hatena.Star.EntryLoader = new Ten.Class({
    initialize: function() {
        var entries = Hatena.Star.EntryLoader.loadEntries();
        this.entries = [];
        for (var i = 0; i < entries.length; i++) {
            var e = new Hatena.Star.Entry(entries[i]);
            e.showButtons();
            this.entries.push(e);
        }
        this.getStarEntries();
    },
    createStarContainer: function() {
        var sc = document.createElement('span');
        sc.setAttribute('class', 'hatena-star-star-container');
        sc.style.marginLeft = '1px';
        return sc;
    },
    createCommentContainer: function() {
        var cc = document.createElement('span');
        cc.setAttribute('class', 'hatena-star-comment-container');
        cc.style.marginLeft = '1px';
        return cc;
    },
    scrapeTitle: function(node) {
        var rval = [];
        (function (node) {
            if (node.tagName == 'SPAN' &&
                (node.className == 'sanchor' ||
                 node.className == 'timestamp')) {
                     return;
            } else if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) {
                return;
            }
            var cn = node.childNodes;
            if (cn) {
                for (var i = 0; i < cn.length; i++) {
                    arguments.callee.call(this, cn[i]);
                }
            }
            var nodeValue = node.nodeValue;
            if (typeof(nodeValue) == 'string') {
                rval.push(nodeValue);
            }
        })(node);
        return rval.join('');
    },
    headerTagAndClassName: ['h3',null],
    getHeaders: function() {
        var t = Hatena.Star.EntryLoader.headerTagAndClassName;
        return Ten.DOM.getElementsByTagAndClassName(t[0],t[1],document);
    },
    loadEntries: function() {
        var entries = [];
        //var headers = document.getElementsByTagName('h3');
        var c = Hatena.Star.EntryLoader;
        var headers = c.getHeaders();
        for (var i = 0; i < headers.length; i++) {
            var header = headers[i];
            var a = header.getElementsByTagName('a')[0];
            if (!a) continue;
            var uri = a.href;
            var title = '';
            // Ten.DOM.removeEmptyTextNodes(header);
            var cns = header.childNodes;
            title = c.scrapeTitle(header);
            var cc = c.createCommentContainer();
            header.appendChild(cc);
            var sc = c.createStarContainer();
            header.appendChild(sc);
            entries.push({
                uri: uri,
                title: title,
                star_container: sc,
                comment_container: cc
            });
        }
        return entries;
    }
},{
    getStarEntries: function() {
        var url = Hatena.Star.BaseURL + 'entries.json?';
        for (var i = 0; i < this.entries.length; i++) {
            if (url.length > Ten.JSONP.MaxBytes) {
                new Ten.JSONP(url, this, 'receiveStarEntries');
                url = Hatena.Star.BaseURL + 'entries.json?';
            }
            url += 'uri=' + encodeURIComponent(this.entries[i].uri) + '&';
        }
        new Ten.JSONP(url, this, 'receiveStarEntries');
    },
    receiveStarEntries: function(res) {
        var entries = res.entries;
        if (!entries) entries = [];
        for (var i = 0; i < this.entries.length; i++) {
            var e = this.entries[i];
            for (var j = 0; j < entries.length; j++) {
                var se = entries[j];
                if (!se.uri) continue;
                if (encodeURIComponent(se.uri) == encodeURIComponent(e.uri)) {
                    e.bindStarEntry(se);
                    entries.splice(j,1);
                    break;
                }
            }
            if (typeof(e.can_comment) == 'undefined') {
                e.setCanComment(res.can_comment);
            }
            e.showStars();
            e.showCommentButton();
        }
    }
});

/* Hatena.Star.WindowObserver */
Hatena.Star.WindowObserver = new Ten.Class({
    initialize: funct


  

2007-07-13

KEREM SHALOM, Israel, July 11 ?? Real life has a way of intruding into the airy absolutes of the Israeli-Palestinian conflict. Each side may deny the other’s historical legitimacy, or plot the other’s demise, but somehow, the gritty business of coexistence marches on.

Skip to next paragraph

Enlarge This Image

Rina Castelnuovo for The New York Times

An Israeli man signaled for a truck to move toward Gaza at Sufa on Wednesday. Commerce continues despite the Hamas takeover.

The New York Times

For the past month, since the Islamic militants of Hamas took over the Gaza Strip, Israel has kept the main commercial crossing point at Karni shuttered, squeezing the life out of the limp Gazan economy. Israel bans contact with Hamas, and Hamas seeks Israel’s destruction, making border crossing etiquette more precarious than elsewhere.

Yet at this small crossing near the Egyptian border on Wednesday, between mortar attacks by Hamas and other militants, about 20 truckloads of milk products, meat, medicines and eggs passed from Israel into Gaza, part of the effort to keep basic commodities reaching the 1.5 million Palestinians of the largely isolated strip. Most of the supplies are not humanitarian relief, but are ordered by Palestinian merchants from Israeli suppliers, relying on contacts built up over years.

The mechanics of the crossover manage to answer Israel’s security needs while avoiding contact with Hamas. At Kerem Shalom, Israeli trucks transfer their goods to what Israeli military officials describe as a “sterile” Palestinian truck. Driven by a carefully vetted Palestinian driver, the truck never leaves the terminal, carrying the goods to the Palestinian side, where they are transferred onto ordinary Palestinian trucks that drive into Gaza.

Kerem Shalom, which means “vineyard of peace,” is surrounded by fences and concrete barriers. It can process only about 20 trucks a day, so it is reserved for products that require refrigeration.

The hardier goods, which make up the bulk of the supplies, go through another crossing, at Sufa, to the north. About 100 Israeli trucks a day come from Israel, swirling up clouds of dust before dumping thousands of tons of dry products, bales of straw and crates of fruit on “the platform,” a fenced-in patch of baked earth. At 3 p.m. the Israeli suppliers leave. Like drug dealers picking up a “drop,” the Gaza merchants send in trucks from a gate on the other side and take the products away.

Other products make their way into Gaza with virtually no human interaction. At the fuel depot at Nahal Oz, Israeli tankers pour diesel, gasoline and cooking gas into Gaza through pipes that run beneath the border. And even at Karni, the main crossing that closed for normal operations on June 12, the Israelis have adapted a 650-foot-long conveyor belt, which was previously used for gravel, to send in grain.

“It is better all around from a security point of view that commodities go in,” said Maj. Peter Lerner of the Coordination and Liaison Administration, the Israeli military agency that deals with the civilian aspects of the Gaza border. “More despair doesn’t serve anyone.”

Israeli officials cite security reasons for having shut Karni, the only crossing equipped to send containers into Gaza, or to handle exports out of the strip. “Karni was based on the concept of two sides operating together,” said Col. Nir Press, the head of the coordination agency.

Colonel Press noted that in April 2006, a vehicle loaded with half a ton of explosives got through three of four checkpoints on the Palestinian side of Karni, and was stopped at the last security position by members of the American-backed Presidential Guard, loyal to the Palestinian president, Mahmoud Abbas of Fatah.

But the Presidential Guard is no longer there, having been routed, along with all other Fatah forces in Gaza, by Hamas.

Instead, the military wing of Hamas and other Palestinian factions have been firing mortar shells at Kerem Shalom. On Tuesday, 10 of them landed in and around the terminal as two trucks of milk were passing. The crossing was closed for the rest of the day. [Another barrage of mortar shells hit areas around Kerem Shalom on Thursday.]

Hamas suspects that Israel wants to use Kerem Shalom to replace the Rafah crossing on the Egypt-Gaza border, which has been closed since June 9. The Palestinians had symbolic control at Rafah. At Kerem Shalom, Israel can better supervise who ?? and what ?? is going in and out of the strip.

“Kerem Shalom is a military post, a place from which Israeli tanks begin their incursions into Gaza,” said Fawzi Barhoum, a Hamas spokesman, justifying the mortar attacks. “How can we consider it a safe and legitimate crossing to replace Rafah?”

But when it comes to food, rather than principle, Hamas is proving itself pragmatic as well. On Sunday, Palestinian merchants, trying to press Israel to reopen Karni, told the Israelis that Hamas had barred the import of Israeli fruit. But by Wednesday, the Israeli fruit was ordered again. “Hamas does not want to lose the private sector,” a Gaza businessman explained.

Tellingly, the exposed Sufa crossing, through which most of the food comes, has not been attacked with mortars so far. Without Karni, however, and with the smaller crossings operating on a one-way basis, Gaza can barely subsist. With hardly any raw materials going in, and no products from Gazan farms, greenhouses and factories so far allowed out, Gaza’s tiny industrial base is on the verge of collapse.

Hamas officials say they want to start negotiations with Israel about reopening the formal crossings. Major Lerner said that Hamas had “a few things to do” first, including recognizing Israel’s right to exist and freeing Gilad Shalit, the Israeli soldier captured and taken to Gaza in a raid more than a year ago.

But the ultimate test of pragmatism may come in September when the Hebrew calendar enters what is known in Jewish law as a “shmita” year. Then the fields of Israel are supposed to lie fallow, and observant Jews seek agricultural products grown elsewhere. Before the Hamas takeover, Israel’s rabbis had reached agreements with Palestinians to import vegetables from Gaza, Major Lerner said. Given the needs of both sides, it may still happen.

ログイン ユーザー登録
ようこそ ゲスト さん