「open」を含む日記 RSS

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

2007-12-10

プローチが腐ってるのかもしれないなあ

なんかデーターが見つからない危険性を感じるというか。ファイルがでかいからreadlinesとか使いたくないんだけれども無理かな。

class Id_sorted_data
  def initialize path, avarage_bytes_by_one_data, search_margin
    @f = File.open(path);
    @v = avarage_bytes_by_one_data;
    @cash = {};
    @margin = search_margin;
    return self
  end
  def read number
    if @cash.member?(number)
      return @cash[number];
    end
    @f.seek([(number - @margin) * @v, 0].max);
    for i in 1..20
      @f.readline;
      temp = @f.readline;
      @cash[temp.to_i] = temp;
      if temp.to_i == number
        return @cash[number];
      elsif (number - @margin .. number).include?(temp.to_i)
        return near(number);
      end
      @f.seek((number - temp.to_i - @margin) * (@v * (20 - i) / 20), IO::SEEK_CUR);
    end
  end
  def near number
    for i in 1..@margin
      temp = @f.readline;
      @cash[temp.to_i] = temp;
      if temp.to_i == number
        return @cash[number];
      end
    end
  end
end

2007-11-02

Plone(ブロググループウェア)入門 - Python

plone.jpへようこそ — plone.jp portal  

Plone CMS: Open Source Content Management  JZUG Wiki - PloneSiteInJapan

http://localhost/

管理者でログイン

Site Setup

Language

Japanese


もっと知りたいPython:第2回 高機能WebフレームワークPlone|gihyo.jp

Ploneは,必要な機能をすべて備えたオールインワンパッケージとして作られています。

データベースWebサーバPloneに内蔵されていますので,ApacheMySQLなどを別途インストールする必要がありません。

このため,インストール運用がとても楽なのです。

Linuxなどのサーバを特別にたてる必要はなく,使っていないWindowsインストールされたPCに,Ploneインストールしておきます。

アカウントを作るとユーザ専用のスペースが割り当てられますので,文書やファイルアップロードすれば情報共有ができます。

WebDAVを使って画像アップロードし,フォトアルバムとして使ってもいいですし,

Ploneで動くブログインストールして日報をつけてもよいでしょう。

Plone3をリモートフォルダとして使う — Papasan's Home

Plone3のWindowsパッケージは数回のクリックWebサーバーFTPサーバーデータベースなど全てが構築できます。楽チン!!

Plone 3.0 を Windows 環境にインストール - tkykhgの日記

dev blog/CMS インストールガイド:Plone 2

Blogのインストール

Plone用Blogプロダクト,COREBlog2について — Blog on Plone ! : coreblog.org

Plone on Windows

PloneのSMTP設定にGMailを指定 - 清水川Web

Zope/Ploneサイトの構築 - 蓄積したTipsを公開するサイト(京大情報系技術職員)

【特選フリーソフト】安倍晋三氏の公式サイトが採用したオープンソースCMS Plone:ITpro

【コラム】Yet Another 仕事のツール (68) ZMIの日本語化とデザインのカスタマイズ | エンタープライズ | マイコミジャーナル

Plone Book

Amazon.co.jp: 開発のプロが教える標準Plone完全解説 (デベロッパー・ツール・シリーズ): 本: アンディ マッケイ,Andy McKay,クイープ,システムサポート

Amazon.co.jp: オープンソース徹底活用 Ploneによる簡単Webコンテンツ管理 (オープンソース徹底活用): 本: 寺田 学,伏見 潤,永井 孝,CMSコミュニケーションズ

2007-10-30

40行で作るPerlテンプレートエンジン

60行で作るPHP用テンプレートエンジン

やってしまった・・・。

方針:

  • PHPのように<?php・・・?>が無いのでそのまま表示と(foreach|if|unless)に対応。
  • [% $c{title} %]で普通に表示(TTっぽい?)
  • [# $c{title} #]でHTMLエスケープ表示

package SixtyLinesTemplate;

use strict;
use warnings;
our $VERSION = '0.01';

sub convert {
    return unless defined(my $str = shift);
    $str =~ s{&}{&}gso;
    $str =~ s{<}{&lt;}gso;
    $str =~ s{>}{&gt;}gso;
    $str =~ s{\"}{&quot;}gso;
    $str;
}

sub include_template {
    my $tmpl = shift;
    my %c = %{+shift};
    eval convert_template($tmpl);
    die $@ if $@;
}

sub convert_template {
    my $tmpl = shift;
    my $cache = $tmpl.'.cache';
    return scalar do { open my ($FH) , $cache; local $/; <$FH> }
        if ( -f $cache &amp;&amp; (stat($tmpl))[9] <= (stat($cache))[9] );
    my $out = do { open my ($FH) , $tmpl; local $/; <$FH> };
    $out =~ tr/()/\x28\x29/;
    $out =~ s/\[%\s*(foreach|if|unless|end)\s*(.+?)\s*{?\s*%\]/");".(lc($1) eq 'end' ? '} print q(' : "$1 $2 { print q(")/ige;
    $out =~ s/\[%(.+?)%\]/);print $1; print q(/g;
    $out =~ s/\[#(.+?)#\]/);print SixtyLinesTemplate::convert($1); print q(/g;
    $out = 'print q('.$out.');';
    open my ($FH) , '>' , $cache;
    print $FH $out;
    $out;
}

1;

サンプルコード


use SixtyLinesTemplate;

my $context = {
    'title' => 'Example',
    'list'  => [10,'<A&amp;B>']
};

SixtyLinesTemplate::include_template('template.tmpl',$context);

サンプルテンプレート


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head&gt;
    <title>[# $c{title} #]</title>
  </head&gt;
  <body>
    <h1>[# $c{title} #]</h1>
    <table>
[% foreach my $i (0..@{$c{list}}-1) %]
      <tr bgcolor="[% $i % 2 ? '#FFCCCC' : '#CCCCFF' %]">
        <td&gt;[% $i %]</td&gt;
        <td&gt;[# $c{list}[$i] #]</td&gt;
      </tr>
[% end %]
    </table>
  </body>
</html>

出力例:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Example</title>
  </head>
  <body>
    <h1>Example</h1>
    <table>

      <tr bgcolor="#CCCCFF">
        <td>0</td>
        <td>10</td>
      </tr>

      <tr bgcolor="#FFCCCC">
        <td>1</td>
        <td>&lt;A&amp;amp;B&gt;</td>
      </tr>

    </table>
  </body>
</html>

foreachんところが汚く見えるかもしれませんが、あれは添え字を取ろうとするとああなるんでご勘弁を。

普通ループするだけならforeach my $item (@$c{title}) でいけますゆえ。

あと存在しない変数とか使うと死んだり警告でたりするのでevalの前にno strictとno warningsをやった方がいいかもねぇ。

って何まじめに検証してんだ俺・・・orz

追記:

SixtyじゃなくてFortyだね。恥ずかし!

追追記:

danさんに添削頂いたYO!

でも&amp;の奴はちゃんと書いてるんだけども投稿すると勝手エスケープされてしまってるんだよね。何でだろ?

ちなみにこのconvertの処理はCGI::Utilから拝借しました。

2007-10-22

http://anond.hatelabo.jp/20071022182413

openβからというとチャオズ鯖かな?

同じような時期からずーっとやってるよ。

ずーーっとやってるのにまだオーラキャラがいっこもない。

ずーーーと同じキャラなのに。

BOTRTMもつかわず100Mとかいうのが信じられんよ。

単純にプレイ時間の違いですか?

そうですか……。

ケイオスなら適当ギルドはいればそれくらい補完してくれるやつおっただろうに。

君は早く駆け抜けるタイプの人なのね。

2007-10-19

http://anond.hatelabo.jp/20071018142959

解説ありがとう

いや、書き込むっぽいなとは思ったんだけど、

entry = diary.entry('20070712231804')

エントリー指定してたからなんなんだろうと思って。

editもできるってことなのかな?

それともdiary.rawあたりでよみこむアンカーかなにか?

で、そもそもRubyに詳しくない自分からするとちゃんとした使い方がそれでもわからない。

バカでごめんねなんだけど、どうやって使えばいいの?

例えば自分windowsなんで、使い方に書かれてるスクリプト拡張子rbにして保存して、

masuda.rbの保存されているところにぶっこんでコマンドラインから実行してみた。

ずらーっと増田らしきものを読み込む。

そりゃそうだわなと思いながら文字化けの山。

diary.login('my_id', 'my_pass')

diary.my_entries.each {|entry| puts entry.content }

diary.post('Ruby is ...', <<EOS)</p&gt;

A dynamic, open source

programming language with a

#...

EOS

ここらへんにid/passやらタイトル、本文を書けば書き込めるのかもしれないけど、

毎回スクリプトを書き換えるって感じなのかな?

書き込みに成功|失敗したらその日の増田が表示されるのかな?

あと

session[:diary] = diary.raw

...

diary = Masuda::Diary.restore(session[:diary])

の...って何でしょうか??

2007-10-18

http://anond.hatelabo.jp/20071018141259

これは何をするための?

単にRubyから増田を読み書きするためのライブラリだけど、分かりづらかったかな。。。

バックアップとってくれるのかな?

自分のエントリバックアップするんだったら

diary = Masuda::Diary.new

diary.login('my_id', 'my_pass')
diary.my_entries.each do |entry|
  open("#{entry.id}.txt", 'w') do |f|
    f << entry.content
  end
end

とか。

Ruby Masuda Library

http://rubyforge.org/projects/masuda/

作った。

インストール
gem install masuda
使い方
require 'rubygems'
require 'masuda'

diary = Masuda::Diary.new
diary.entries.each {|entry| puts entry.content }
entry = diary.entry('20070712231804')
puts <<EOS
  #{entry.title}
  #{entry.content}
EOS
entry.trackbacks.each {|trackback| puts trackback.snippet }

diary.login('my_id', 'my_pass')
diary.my_entries.each {|entry| puts entry.content }
diary.post('Ruby is ...', <<EOS)
A dynamic, open source
programming language with a
...
EOS

session[:diary] = diary.raw
...
diary = Masuda::Diary.restore(session[:diary])

2007-10-09

http://anond.hatelabo.jp/20071009171336

http://anond.hatelabo.jp/20071009142256 の人ですが、ごめん、結構適当書いてました。余計な事してました。ぜんぜん確認してませんでした。という事でバグフィクス版。

javascript:l=location;w=window;u=l.pathname;(function(){wd='/product/';st=u.indexOf(wd);if(st==-1){wd='/ASIN/';st=u.indexOf(wd);}if(st==-1){wd='/dp/';st=u.indexOf(wd);}if(st!=-1){asin=u.substring(st+wd.length,st+10+wd.length);if(prompt('Shortest Amazon URL and this open with Hatena','http://www.amazon.co.jp/dp/'+asin)){w.open('http://d.hatena.ne.jp/asin/'+asin,'_blank','');}}else{w.alert('no asin info');}}());

ただ、正規表現使えばもっとシンプルになる。って事で同じ動作を書きなおしてみました。

javascript:(function(){if(location.pathname.match(/\/(product|ASIN|dp)\/(.{10})/)){asin=RegExp.$2;if(prompt('Shortest Amazon URL and this open with Hatena','http://www.amazon.co.jp/dp/'+asin))open('http://d.hatena.ne.jp/asin/'+asin,'_blank')}else{alert('no asin info')}})();

さらに、はてなじゃなくて、アマゾンで開きなおす版も。

javascript:(function(){if(location.pathname.match(/\/(product|ASIN|dp)\/(.{10})/)){asin=RegExp.$2;if(prompt('Jump this shortest Amazon URL','http://www.amazon.co.jp/dp/'+asin))location.href='http://www.amazon.co.jp/dp/'+asin}else{alert('no asin info')}})();

最初はダイアログURLの修正が出来る様に、と思ってましたが、良く考えるとあまり意味なさそうなので止めました。

http://anond.hatelabo.jp/20071009131211

直接コピースマートじゃないけど、こんなんでどうでしょ。

[バグってます]
javascript:l=location;w=window;u=l.pathname;(function(){wd='/product/';st=u.indexOf(wd);if(st==-1){wd='/asin/';st=u.indexOf(wd);}if(st==-1){wd='/dp/';st=u.indexOf(wd);}if(st!=1){asin=u.substring(st+wd.length,st+10+wd.length);asin=prompt('Shortest Amazon URL and this open with Hatena','http://www.amazon.co.jp'+wd+asin);if(asin){w.open('http://d.hatena.ne.jp/asin/'+asin.replace('http://www.amazon.co.jp'+wd,''),'_blank','');}}else{w.alert('no asin info');}}());
[バグってます]

修正版は http://anond.hatelabo.jp/20071009203351# です。

http://anond.hatelabo.jp/20071009113829

http://www.hatena.ne.jp/tool/bookmarklet#diary

の「Amazonの商品ページ → はてなasinページブックマークレットASINページに飛んで、「amazon.co.jp詳細ページへ」のURLコピー、かなあ。

後ろをチョット削りたいなら、せめて[ctrl]+[shift]+カーソルキーで、単語ごとの範囲選択をしてから[delete]。

このブックマークレットの改良版が

http://tetsu23.my.land.to/bookmarklet.html#asin

にあるんだけれど、これは「/product/~」と「/asin/~」のみ対応であって「/dp/~」には非対応。

javascript:l=location;w=window;u=l.pathname;(function(){wd='/product/';st=u.indexOf(wd);if(st==-1){wd='/asin/';st=u.indexOf(wd);}if(st==-1){wd='/dp/';st=u.indexOf(wd);}if(st!=1){asin=u.substring(st+wd.length,st+10+wd.length);w.open('http://d.hatena.ne.jp/asin/'+asin,'_blank','');}else{w.alert('no asin info');}}());

にしたらうまくいった。

「いい感じのURLを作ってクリップボードに入れる」というのも、ちょっと直せばすぐできるよね。

たぶん「w.open();」をなにかに変えればいいんだよね。

でも、サンデープログラマですらない自分にはこれが限界です本当にありがとうございました

本格的に日本終わったな

第11回 文化庁メディア芸術祭 OPEN FORM 推薦作品 結果報告

http://plaza.bunka.go.jp/open/works.html

で、何故か東方Projectが入っているわけですががががが

えー、良いのかこれ?

文花帖文化庁と読み一緒だからって言う盛大なギャグじゃないよね?

アニメーション部門の「電脳コイル」は確かにその価値はあると思うが、「Darker than black」は正直どうだろう

とりあえず「らきすた」は入っていないようです。良かった

2007-10-01

http://anond.hatelabo.jp/20070930234731

仕方ねえ!べらぼうめぇ

423行目くらいのところから、

var Single_key_roles={

    j: 'view_down',
    k: 'view_up',
    l: 'right',
    h: 'left',

    y: 'msd',
    u: 'undo',
    r: 'redo',

    enter: 'open',
    space: 'scroll'
};

に書き換えると、ダブルキー操作が要らなくなる。こんな感じにアルファベットキーなら、重複しない限りどれに変更しても大丈夫。

必要なキーが増えるのと r のために左手を要するのとが気に食わないから、公式には変更しませんゴメンナサイ<>

あ、逆だ ><

本当は M でお気に入りエントリマークとか、’でその箇所に飛ぶとか色々やりたかったんだけど、面倒になってきてやめてしまった。これ実験サービスだし。

2007-09-14

http://anond.hatelabo.jp/20070914214806

ダウンロード必要じゃないですか。

http://anond.hatelabo.jp/20070914213754

http://anond.hatelabo.jp/20070914204359

この2つは直接ブックマークツールバー入力するだけですよ?

はてなブックマーカーなら「ブックマークする」のプロパティURL

javascript:window.open('http://b.hatena.ne.jp/add?mode=confirm&is_bm=1&title='+escape(document.title)+'&url='+escape(location.href),%20'_blank',%20'width=550,height=600,resizable=1,scrollbars=1');undefined;

ってなってるところを一部書き換えたような感じ。

http://anond.hatelabo.jp/20070913180648

RimoでそのページにはってあるYouTube自動的に再生するjavascript

javascript:window.open('http://rimo.tv/#/channel?url='+encodeURI(location.href),%20'_blank',%20'width=425,height=350,resizable=1,scrollbars=1');undefined;

途中で断念。

2007-08-12

RSSリーダーは使える!

完全に乗り遅れましたが、少し前にひろゆき氏の「RSSリーダー情報収集に使う理由がやっぱりわからない。」についての議論が盛り上がっていました。で、議論の流れを、軽く流し読みしてみて思ったのですが、なんだか、(RSSリーダーをそれほど使い込んでいない)自分が基本だと思っていたことが書かれていないな、というのが私の感想でした。ので、その辺について少し書きます。

まず、議論の一連の流れについては、下のURLを参考にしました。

はてブコメント欄のページは、その議論に対するまとめサイト的に使えるので便利ですね・・・)

http://b.hatena.ne.jp/entry/http://www.asks.jp/users/hiro/28353.html

それで、本論に入りますが、上の議論で抜け落ちている点を書きますと、「(特にIT)マスコミの記事を考慮に入れていない」のですね。と、書いても、ピンと来ない方もおられるかも知れませんが、実際使ってみれば分かることなので、試しに、はてなRSSで、各ITマスコミの記事を購読されてみてはいかがでしょうか?

私の場合、例えば、以下のITマスコミの記事を購読しています。

■Tech-On! モバイル

http://techon.nikkeibp.co.jp/mobile/

■Tech-On! デジタル家電

http://techon.nikkeibp.co.jp/d-ce/

■マイコミジャーナル

http://journal.mycom.co.jp/

■@IT

http://www.atmarkit.co.jp/

ITmedia Top Story 最新記事一覧

http://www.itmedia.co.jp/news/fortop/

■ITpro

http://itpro.nikkeibp.co.jp/index.html

Japan.internet.com

http://japan.internet.com/

日経パソコン オンライン

http://pc.nikkeibp.co.jp/pc/index.html

CNET Japan

http://japan.cnet.com/

デジタルARENA

http://arena.nikkeibp.co.jp/

INTERNET Watch

http://internet.watch.impress.co.jp/

PC Watch

http://pc.watch.impress.co.jp/

Open Tech Press

http://opentechpress.jp/

ZDNet Japan ニュース

http://japan.zdnet.com/news/

ASCII24

http://ascii.jp/cate/26/

私の場合、一週間に一度チェックしていますが、上記の記事を全部あわせると、一週間で、約1500エントリくらいたまります。ですので、現実的な話として、RSSリーダーなしには、ITマスコミ情報を網羅し、高速にチェックすることは難しいと思います(大体、ITマスコミサイトはページあたりの情報量が多すぎて、頭が痛くなってきますし)。

個人的に思うのは、RSSリーダーのそもそもの思想が、IT技術者の(というか、ギークが自分の)ニーズに合わせて作ってあるので、IT技術者が便利なように作ってある訳ですね。だから、最新技術の動向を追いかけるという面において、RSSリーダーは非常に相性がいい作りになっていると思います。

少なくとも、新聞のザッと読みみたいな感じで、業界全体の動向を見渡す、という面では使える技術だと思います。はてなブックマークの人気記事だけ見ても、業界全体の動向は分からないですし、ブックマークされていない記事でも自分が興味の引かれる記事は必ずあります。

まあ、アルファブックマーカーというのは、間違いなくRSSリーダーを使っているでしょうし、今さら言うべきことではないのかも知れませんが、どうも、似非技術者の端くれとしては、上の議論にこういった使い方が紹介されていないのは、違和感を感じます。

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-08

Live Earth

暇な奴一緒にライブアースを楽しもうぜ!

リアルタイム勝手にまとめておくので参考にしてください。僕は寝ますので、朝の8時から更新は止まってます。

残すはNYCとブラジルのみです。

個人的な流れ&お勧めの流れ、

JACK JOHNSON&KT TUNSTALL&JAMES BLUNTBEASTIE BOYSMANDO DIAOFOO FIGHTERSMADONNA→後はNYCを主体でブラジルポイントを抑える。

UK・NYC主体が王道です。

各所タイムスケジュール

http://www.liveearth.msn.com/about/factsheet

2chより。

ブラウザ重くて見れない人は Media Player を使ってみるといいかも

 「ファイル」→「URLを開く」→見たい会場のURLコピペ

アメリカ(NY)(日本時間:3:00??12:00):進行中

http://asx.liveearth.msn.com.edgesuite.net/US.asx

KENNA

KT TUNSTALL

TAKING BACK SUNDAY

KEITH URBAN

LUDACRIS

AFI

FALL OUT BOY

AKON

JOHN MAYER

↓今このあたり

MELISSA ETHERIDGE

ALICIA KEYS

DAVE MATTHEWS BAND

KELLY CLARKSON

KANYE WEST

BON JOVI

SMASHING PUMPKINS

ROGER WATERS

THE POLICE

ブラジル(4:00??11:00)

http://asx.liveearth.msn.com.edgesuite.net/Brazil.asx

XUXA

JOTA QUEST

MV BILL

MARCELO D2

PHARRELL WILLIAMS

↓今このあたり

O RAPPA

MACY GRAY

JORGE BEN JOR

LENNY KRAVITZ

南アフリカ日本時間:1:00??6:30):終了

http://asx.liveearth.msn.com.edgesuite.net/SouthAfrica.asx

アメリカ(DC):(日本時間:23:30??8日2:00予定):終わったらしい。

http://asx.liveearth.msn.com.edgesuite.net/US2.asx

オーストラリア:終了:再放送

http://asx.liveearth.msn.com.edgesuite.net/Australia.asx

BLUE KING BROWN

TONI COLLETTE & THE FINISH

SNEAKY SOUND SYSTEM

GHOSTWRITERS

PAUL KELLY

ESKIMO JOE

MISSY HIGGINS

JOHN BUTLER TRIO

WOLFMOTHER

JACK JOHNSON

CROWDED HOUSE

日本(ほとんど幕張の会場?/京都東寺):終了。再放送

http://asx.liveearth.msn.com.edgesuite.net/Japan.asx

GENKI ROCKETS

RIZE

AYAKA

AI OTSUKA

AI

XZIBIT

ABINGDON BOYS SCHOOL

COCCO

LINKIN PARK

KUMI KODA

RIHANNA

中国:終了:再放送

http://asx.liveearth.msn.com.edgesuite.net/China.asx

さっぱりわからんけど、一応貼っておく。中国の歌とかわからんけど、普通に聞けるかも。

EVONNE HSU

ANTHONY WONG

SOLER

HUANG XIAO MING

WANG CHUAN JUN AND WANG RUI

12 GIRLS BAND

JOEY YUNG

WINNIE HSIN

PU BA JIA

SARAH BRIGHTMAN

WANG XIA OKUN

EASON CHAN

イギリス日本時間:21:30??8日6:30):終了しました。再放送中。

http://asx.liveearth.msn.com.edgesuite.net/UK.asx

GENESIS

RAZORLIGHT

SNOW PATROL

DAMIEN RICE AND DAVID GRAY

KASABIAN

PAOLO NUTINI

BLACK EYED PEAS

JOHN LEGEND

DURAN DURAN

RED HOT CHILI PEPPERS

BLOC PARTY

CORINNE BAILEY RAE

TERRA NAOMI

KEANE

METALLICA

SPINAL TAP

JAMES BLUNT

BEASTIE BOYS

PUSSYCAT DOLLS

FOO FIGHTERS

MADONNA

ジェネシス「Turn It On Again」「No Son Of Mine」「Land Of Confusion」

レイザーライト「Before I Fall To Pieces」「America」

●スノウ・パトロールOpen Your Eyes」「Shut Your Eyes」「Chasing Cars」

ダミアン・ライス&デヴィッド・グレイ「Babylon」「The Blower's Daughter」「Que Sera Sera」

カサビアン「Empire」「Club Foot」「I.D.」

●パオロ・ヌティーニ「Wonderful World」「Last Request」「New Shoes」「Jenny Don't Be Hasty」

ブラック・アイド・ピーズ「Let's Get It Started」「Pump It」「Don't Phunk With My Heart」「Big Girls Don't Cry」「Where Is The Love?」

ジョン・レジェンド「Ordinary People」

デュラン・デュランPlanet Earth」「Ordinary World」「Night Runner」「Falling Down」

スヌープ・ドッグハンブルグより中継)「I Wanna Love You」

レッド・ホット・チリ・ペッパーズCan't Stop」「Dani California」「So Much I」「By The Way」

ブロック・パーティ「Hunting For Witches」「Banquet」「So Here We Are」「The Prayer」

コリーヌ・ベイリー・レイ「I'd Like To」「Mercy Mercy Me」「Put Your Records On」

キーン「Everybody's Changing」「Somewhere Only We Know」「Is It Any Wonder?」

シャキーラハンブルグより中継)「Hips Don't Lie」

メタリカ「Enter Sandman」「Nothing Else Matters」「Sad But True」「For Whom The Bell Tolls」

スパイナル・タップ「Stonehenge」「Warmer Than Hell」「Big Bottom」

ジェームスブラント「Same Mistake」「Wisemen」

キース・アーバンアリシア・キーズNYより中継?)「Gimme Shelter」

ビースティ・ボーイズ「Sabotage」「So What'cha Want」「Sure Shot」「Intergalactic」「Off The Grid」

●プッシーキャット・ドールズ「Buttons」「I Don't Need A Man」「Feelin' Good」「Don't Cha」

フー・ファイターズ「Best Of You」「All My Life」「My Hero」「Everlong」

マドンナ「Hey You」「Ray Of Light」「La Isla Bonita」「Hung Up」

ドイツ日本時間:21:00??8日6:00):終了しました。

http://asx.liveearth.msn.com.edgesuite.net/Germany.asx

SHAKIRA

SNOOP DOGG

ROGER CICERO

MIA.

SASHA

STEFAN GWILDIS

MARQUESS

MARIA MENA

SILBERMOND

MICHAEL MITTERMEIER

REAMONN

SAMY DELUXE

ENRIQUE IGLESIAS

JAN DELAY

KATIE MELUA

LOTTO KING KARL

REVOLVERHELD

MANDO DIAO

JULI

CHRIS CORNELL

YUSUF

■World:再放送らしい、美味しいアーティストだけ流してくれるかも?ちなみに、各放送局が終わったら再放送をするところもあるらしい。

http://asx.liveearth.msn.com.edgesuite.net/WorldCombination.asx

Green

http://asx.liveearth.msn.com.edgesuite.net/GreenClips.asx

QuickTimeURL

http://asx.liveearth.msn.com.edgesuite.net/37279/primary/Japan.mov

http://asx.liveearth.msn.com.edgesuite.net/37279/primary/Australia.mov

http://asx.liveearth.msn.com.edgesuite.net/37279/primary/China.mov

http://asx.liveearth.msn.com.edgesuite.net/37279/primary/UK.mov

http://asx.liveearth.msn.com.edgesuite.net/37279/primary/Germany.mov

http://asx.liveearth.msn.com.edgesuite.net/37279/primary/US.mov

http://asx.liveearth.msn.com.edgesuite.net/37279/primary/US2.mov

http://asx.liveearth.msn.com.edgesuite.net/37279/primary/SouthAfrica.mov

http://asx.liveearth.msn.com.edgesuite.net/37279/primary/Brazil.mov

このページからアーカイブが見れるらしい。

http://jp.video.msn.com/v/ja-jp/v.htm?g=d309d01d-aaec-4128-91bd-fd6e60315826&t=m939&p=Source_JAJP_SOS

2007-04-28

[]ガイナックス取締役死亡は東映のせいとの噂が2chで広まっている

http://www.itmedia.co.jp/news/articles/0704/27/news092.html

・3月末開催の『東京国際アニメフェア』で、子供たちが集まるプリキュアグレンラガン裏番組

のブースに向かって「プリキュアじゃなくてグレンラガン見ろ!」などと叫び、子供たちをびびらせる。

・公式制作ブログプリキュアマスコットキャラ虐待する漫画掲載。閲覧者に叱られて取り下げる。

http://www33.atwiki.jp/kimoiotaku?cmd=upload&act=open&pageid=1&file=cure.jpg

152:メロン名無しさん :2007/04/19(木) 00:21:43 ID:???0 [sage]

平素より、東映アニメーションウェブサイトをご利用いただき、誠にありがとうございます。

ウェブサイト上の不適切な画像表示に関するご連絡ありがとうございました。

問題の画像は弊社から警告する以前に、先方にて削除されたようですので今回はクレームを申し立てるようなことはいたしません。逆に、このような画像を掲載することで、先方の企業イメージが損なわれ、モラルが問われる形になるかと思います。

以上、よろしくお願いいたします。

--------------------------------------------------------------------------------

東映アニメーション

URL : http://www.toei-anim.co.jp/

2007-04-13

ASPファイル受信

'/** Requestオブジェクトから受信したデータを取り出します。
' * @return byte配列を格納した連想配列を返します。
' */
Function getRequestItem()

  If Request.TotalBytes <= 0 Then
    getRequestItem = Null
    Exit Function
  End If

  Dim data
  Dim separator
  Dim dataArray
  Dim buffer
  Dim filePath
  Dim fileName
  Dim ix
  Dim stringIndex
  Dim myCrLf
  Dim items
  Dim itemName

  myCrLf = convertAsc(vbCrLf)
  Set items = Server.CreateObject("Scripting.Dictionary")

  data = Request.BinaryRead(Request.TotalBytes)
  data = LeftB(data, UBound(data) - 3) & myCrLf

  separator = MidB(data, 1, InStrB(1, data, myCrLf) + 1)

  dataArray = SplitB(data, separator)

  For ix = 2 To UBound(dataArray) Step 1
   '1行読み込み
    buffer = MidB(dataArray(ix), 1, InStrB(1, dataArray(ix), myCrLf) - 1)

   'アイテム名の取得
    stringIndex = InStrB(1, buffer, convertAsc("name="))
    If stringIndex > 0 Then
      itemName = convertUnicode(MidB(buffer, stringIndex + 6, InStrB(stringIndex, buffer, ChrB(34)) - stringIndex))
     Else
      itemName = ""
    End If

   'ファイル名の取得
    stringIndex = InStrB(1, buffer, convertAsc("filename="))
    If stringIndex > 0 Then
      filePath = MidB(buffer, stringIndex + 10, InStrB(stringIndex, buffer, ChrB(34)) - stringIndex)
      fileName = RightB(filePath, LenB(filePath) - LastInStrB(0, filePath, convertAsc("\")))
     Else
      fileName = ""
    End If

   'データ部の取得、改行コードの切り捨て
    buffer = RightB(dataArray(ix), LenB(dataArray(ix)) - InStrB(1, dataArray(ix), myCrLf & myCrLf) - 3)
    buffer = LeftB(buffer, LenB(buffer) - 2)

    items.Item(itemName) = parseBytes(buffer)
  Next

  Set getRequestItem = items
  Set items = Nothing

End Function

'/** 文字列の最後尾から指定文字を検索します。
' * @param Start 検索する開始文字位置を指定します。
' * @param String1 検索対象の文字列を指定します。
' * @param String2 検索する文字列を指定します。
' */
Function LastInStrB(ByRef Start, ByRef String1, ByRef String2)

  Dim ix
  Dim lastIndex
  Dim searchLength

  searchLength = LenB(String2)
  lastIndex = LenB(String1) - searchLength + 1
  If Start > 0 And Start < lastIndex Then
    lastIndex = Start
  End If
  For ix = lastIndex To 1 Step -1
    If MidB(String1, ix, searchLength) = String2 Then
      LastInStrB = ix
      Exit Function
    End If
  Next

  LastInStrB = 0

End Function

'/** アスキー文字列に変換します。
' * @param String 対象の文字列を指定します。
' */
Function convertAsc(Byref String)

  Dim ix
  Dim ascii

  ascii = ""
  For ix = 1 To Len(String) Step 1
    ascii = ascii & ChrB(AscB(Mid(String, ix, 1)))
  Next

  convertAsc = ascii

End Function

'/** Unicode文字列に変換します。
' * @param AscString 対象のアスキー文字列を指定します。
' */
Function convertUnicode(Byref AscString)

  Dim ix
  Dim unicode

  unicode = ""
  For ix = 1 To LenB(AscString) Step 1
    unicode = unicode & Chr(AscB(MidB(AscString, ix, 1)))
  Next

  convertUnicode = unicode

End Function

'/** バイナリ対応版Split関数です。
' * @param String 対象の文字列を指定します。
' * @param Delimiter 区切り文字を指定します。
' */
Function SplitB(Byref String, Byref Delimiter)

  Dim ix
  Dim lastIndex
  Dim searchLength
  Dim start
  Dim datas()
  Dim dataIndex

  dataIndex = 1
  start = 1
  delimiterLength = LenB(Delimiter)
  lastIndex = LenB(String) - delimiterLength + 1

 '最初から1文字ずつ繰り返します。
  For ix = 1 To lastIndex Step 1
   'データを比較します。
    If MidB(String, ix, delimiterLength) = Delimiter Then
     'データを取り出せたら配列に格納します。
      ReDim Preserve datas(dataIndex)
      datas(dataIndex) = MidB(String, start, ix - start)
      dataIndex = dataIndex + 1
      start = ix + delimiterLength
    End If
  Next

  SplitB = datas

End Function

'/** Byte配列を返す関数です。
' * @param data 対象のデータを指定します。
' */
Function parseBytes(Byref data)

  Const adLongVarBinary = 205
  Dim recordset

  If LenB(data) <= 0 Then
    parseBytes = CByte(0)
    Exit Function
  End If

  Set recordset = Server.CreateObject("ADODB.Recordset")
  recordset.Fields.Append "UpLoadBinary", adLongVarBinary, LenB(data)
  recordset.Open
  recordset.AddNew
  recordset.Fields("UpLoadBinary").AppendChunk data
  recordset.Update

  parseBytes = recordset.Fields("UpLoadBinary").Value
  recordset.Close
  Set recordset = Nothing

End Function

2007-04-12

Re: Re: Re: Re:早速バグありましたかorz

おおすばらしいい。自分でなおさなくてもなおしてくれる人たちがいた。OSS!OSS!

最初に指摘された引用記法の問題も取り入れて、

javascript:Yid='ゆーざID';d=document;w=window;function bq(s){return s?'>>\n'+s+'\n<<':s;}function enc(s){return encodeURIComponent?encodeURIComponent(s):encodeURI(s);}if(d.selection){q=d.selection.createRange().text;}else if(d.getSelection){q=d.getSelection();}else if(w.getSelection){q=w.getSelection();}void(w.open('http://anond.hatelabo.jp/'+Yid+'/edit?title=Re: [anond:'+enc(location.href.slice(25,39))+':title];body='+enc(bq(q)),'_self',''));

Re: Re: Re:早速バグありましたかorz

確信なかったので、とりあえず書かずに実験したわけだけど、

Re: Re:早速バグありましたかorz


んじゃーこれでいいんじゃないかな?

javascript:Yid='ゆーざID';d=document;w=window;function bq(s){return '>>\n'+s+'\n<<';}function enc(s){return encodeURIComponent?encodeURIComponent(s):encodeURI(s);}if(d.selection){q=d.selection.createRange().text;}else if(d.getSelection){q=d.getSelection();}else if(w.getSelection){q=w.getSelection();}void(w.open('http://anond.hatelabo.jp/'+Yid+'/edit?title=Re: [anond:'+enc(location.href.slice(25,39))+':title];body='+enc(bq(q)),'_self',''));

Re:そんなあなたに

javascript:Yid='あなたのID';d=document;w=window;function bq(s){return '>>\n'+s+'\n<<';}function enc(s){return encodeURIComponent?encodeURIComponent(s):encodeURI(s);}if(d.selection){q=d.selection.createRange().text;}else if(d.getSelection){q=d.getSelection();}else if(w.getSelection){q=w.getSelection();}void(w.open('http://anond.hatelabo.jp/'+Yid+'/edit?title=anond:'+enc(location.href.slice(25,39))+':title=Re:'+d.title+'&amp;body='+enc(bq(q)),'_self',''));

上記のjavascriptの あなたのID 欄をはてラボでのIDに変えれば使えます。

返答したい増田エントリをひとつだけ表示してブックマークレットを実行すると、新しい記事のタイトルが Re:元のタイトル になり、元のエントリトラックバックが飛んで、選択していた領域を引用するように動きます。

おお、これは便利。これだと選択領域がなくても引用記法が入ってしまうので、

bq(s){return '>>\n'+s+'\n<<';}

部分を、

bq(s){return s?'>>\n'+s+'\n<<':s;}

にしてみました。

また、このブックマークレットで生成された記事にこのブックマークレットで言及すると、タイトル

anond:20070412014506:title=Re:anond:20070330101754:title=Re:そんなあなたに

なんてなってしまいましたが、直す方法がわからずorz

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