Changeset 5315 for lang

Show
Ignore:
Timestamp:
01/23/08 02:09:10 (5 years ago)
Author:
noriaki
Message:

lang/javascript/userscriptsheatthenicovideoup.user.js: fiexed compatibility for the GreaseMonkey?-0.7.20080121.0

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lang/javascript/userscripts/heatthenicovideoup.user.js

    r3517 r5315  
    77// @version        0.3.1 
    88// @released       2007-09-11 09:00:00 
    9 // @updated        2007-12-23 23:00:00 
     9// @updated        2008-01-23 02:00:00 
    1010// @compatible     Greasemonkey 
    1111// @include        http://www.nicovideo.jp/watch/* 
     
    2828*/ 
    2929 
    30 (function(){ 
    31  
    32     var COLOR_MAP = [ 
    33         '#060026', '#0f0082', '#181395', '#214dd6', 
    34         '#3b8cd2', '#36b9d3', '#34c5a5', '#41cc27', 
    35         '#8fd104', '#bfd70e', '#c8ab0b', '#c38509', 
    36         '#c65706', '#c22404', '#c51b20', '#c51b20' 
    37     ]; 
    38     var detail = false; 
    39  
    40  
    41     if(detail) { 
    42         var WIDTH = 2; 
    43         var DIVISION = 82; 
    44     } else { 
    45         var WIDTH = 3; 
    46         var DIVISION = 55; 
    47     } 
    48  
    49     var THERMOGRAPH_DATA = ['data:image/png;base64,', 
     30var COLOR_MAP = [ 
     31    '#060026', '#0f0082', '#181395', '#214dd6', 
     32    '#3b8cd2', '#36b9d3', '#34c5a5', '#41cc27', 
     33    '#8fd104', '#bfd70e', '#c8ab0b', '#c38509', 
     34    '#c65706', '#c22404', '#c51b20', '#c51b20' 
     35]; 
     36var detail = false; 
     37 
     38 
     39if(detail) { 
     40    var WIDTH = 2; 
     41    var DIVISION = 82; 
     42} else { 
     43    var WIDTH = 3; 
     44    var DIVISION = 55; 
     45} 
     46 
     47var THERMOGRAPH_DATA = ['data:image/png;base64,', 
    5048    'iVBORw0KGgoAAAANSUhEUgAAABcAAABTCAYAAAB045zaAAAABGdBTUEAAK/INwWK6QAAABl0RVh0', 
    5149    'U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAutSURBVHjahFltj11VFX723ufcOzN3pp1p', 
     
    103101    'SBqZoy4YjLfQVoxocTOexnm8wVt72bElfeLCRkHIzC/diF/9+nk8/czz43c98cPHcded35j/nwAD', 
    104102    'AIWqiQ5edPF+AAAAAElFTkSuQmCC'].join(''); 
    105     var ARROW_DATA = ['data:image/png;base64,', 
     103var ARROW_DATA = ['data:image/png;base64,', 
    106104    'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAABl0RVh0', 
    107105    'U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAJUExURWZmZszMzAAAACSsS6YAAAADdFJO', 
     
    110108    'WAEEAAGE4VuAAAMA5/wBqfT0mUsAAAAASUVORK5CYII='].join(''); 
    111109 
    112     var WIDTH_ = WIDTH; 
    113     var VIDEO_LENGTH; 
    114  
    115     var $ = function(id){ return unsafeWindow.document.getElementById(id); }; 
    116     var $$ = unsafeWindow.$$; 
    117     var Element = unsafeWindow.Element; 
    118  
    119     if(!document.getElementsByTagName('h1')[0]) return; 
    120  
    121     Element.scrollTo($$("p.TXT12").first()); 
    122  
    123     function heat_map() { 
    124         var output = document.createElement('div'); 
    125         output.id = 'heat_output'; 
    126         output.innerHTML = '<p>Loading...</p>'; 
    127  
    128         if(!$('WATCHFOOTER')) return; 
    129         $('WATCHFOOTER').parentNode.insertBefore(output, $('WATCHFOOTER')); 
    130  
    131         var flvplayer = $('flvplayer'); 
    132         flvplayer.get = function(target) { 
    133             return this.GetVariable(target); 
    134         }; 
    135  
    136         var video_info = flvplayer.get('o').split('&').inject({}, parseQueryString); 
    137  
    138         var thread_id = video_info.thread_id; 
    139         var vlsec = VIDEO_LENGTH = video_info.l; 
    140         var url = video_info.ms; 
    141         var download_url = video_info.url; 
    142         GM_xmlhttpRequest({ 
    143             method: 'POST', 
    144             headers: { 
    145                 'User-Agent': 'Mozilla/4.0 (compatible) Greasemonkey (Heat the Nicovideo up)', 
    146                 'Content-type': 'text/xml' 
    147             }, 
    148             url: url, 
    149             data: '<thread res_from="-1000" version="20061206" thread="' + thread_id + '" />', 
    150             onload: function(res){ extract(res); }, 
    151             onerror: function(res){ GM_log(res.status + ':' + res.responseText); } 
     110var WIDTH_ = WIDTH; 
     111var VIDEO_LENGTH; 
     112 
     113var $ = function(id){ return unsafeWindow.document.getElementById(id); }; 
     114var $$ = unsafeWindow.$$; 
     115var Element = unsafeWindow.Element; 
     116 
     117if(!document.getElementsByTagName('h1')[0]) return; 
     118 
     119Element.scrollTo($$("p.TXT12").first()); 
     120 
     121function heat_map() { 
     122    var output = document.createElement('div'); 
     123    output.id = 'heat_output'; 
     124    output.innerHTML = '<p>Loading...</p>'; 
     125 
     126    if(!$('WATCHFOOTER')) return; 
     127    $('WATCHFOOTER').parentNode.insertBefore(output, $('WATCHFOOTER')); 
     128 
     129    var flvplayer = $('flvplayer'); 
     130    flvplayer.get = function(target) { 
     131        return this.GetVariable(target); 
     132    }; 
     133 
     134    var video_info = flvplayer.get('o').split('&').inject({}, parseQueryString); 
     135 
     136    var thread_id = video_info.thread_id; 
     137    var vlsec = VIDEO_LENGTH = video_info.l; 
     138    var url = video_info.ms; 
     139    var download_url = video_info.url; 
     140    GM_wrap(GM_xmlhttpRequest)({ 
     141        method: 'POST', 
     142        headers: { 
     143            'User-Agent': 'Mozilla/4.0 (compatible) Greasemonkey (Heat the Nicovideo up)', 
     144            'Content-type': 'text/xml' 
     145        }, 
     146        url: url, 
     147        data: '<thread res_from="-1000" version="20061206" thread="' + thread_id + '" />', 
     148        onload: function(res){ extract(res); }, 
     149        onerror: function(res){ GM_log(res.status + ':' + res.responseText); } 
     150    }); 
     151 
     152    function extract(res) { 
     153        var responseXML = (new DOMParser).parseFromString(res.responseText, "application/xml"); 
     154        var comments = responseXML.getElementsByTagName('chat'); 
     155        var counts = new Array(DIVISION).fill(0); 
     156        if(/^sm(\d+)$/.test(unsafeWindow.video_id)) { 
     157            var sm_video_id = RegExp.$1; 
     158        } else { 
     159            var message = document.createElement('p'); 
     160            message.id = 'heat_message'; 
     161            message.innerHTML = 'Sorry, this video is unsupported.' 
     162            output.innerHTML = ''; 
     163            output.appendChild(message); 
     164            return; 
     165        } 
     166        var vlmsec = vlsec.to_i() * 100; 
     167        for(var i = 0, len = comments.length; i < len; i++) { 
     168            var pmsec = comments[i].getAttribute('vpos'); 
     169            if(vlmsec > pmsec) { 
     170                counts[~~(pmsec / vlmsec * DIVISION)]++; 
     171            } else if(vlmsec == pmsec){ 
     172                counts[DIVISION-1]++; 
     173            } 
     174        } 
     175        var max = counts.max(); 
     176        var per_msec = vlmsec / DIVISION; 
     177        var color_map_size = COLOR_MAP.length - 1; 
     178        output.innerHTML = ''; 
     179        for(var i = 0, len = counts.length; i < len; i++){ 
     180            var start_msec = per_msec * i; 
     181            var end_msec = start_msec + per_msec - 1; 
     182 
     183            var span = document.createElement('span'); 
     184            var index = ~~(counts[i] * color_map_size / max); 
     185            var color = COLOR_MAP[index]; 
     186            var comment_info_header = 'コメント数:'; 
     187            var comment_info_html = ['<span class="heat_level', index, '">', 
     188                counts[i], '</span>'].join(''); 
     189            var comment_info_footer = [ 
     190                '(', (~~(to_min(start_msec))).z(2), ':', 
     191                (~~(to_sec(start_msec) % 60)).z(2), '〜', 
     192                (~~(to_min(end_msec))).z(2), ':', 
     193                (~~(to_sec(end_msec) % 60)).z(2), ')'].join(''); 
     194            span.style.color = color; 
     195            span.style.backgroundColor = color; 
     196            span.title = comment_info_header + counts[i] + comment_info_footer; 
     197            span.innerHTML = comment_info_header + comment_info_html + comment_info_footer; 
     198            span.setAttribute('class', i); 
     199            output.appendChild(span); 
     200        } 
     201 
     202        var message = document.createElement('p'); 
     203        message.setAttribute('id', 'heat_message'); 
     204        message.innerHTML = 'Comment Heat Map for nicovideo おまけ機能\u2192 '; 
     205 
     206        var heat_comments_info = document.createElement('p'); 
     207        heat_comments_info.setAttribute('id', 'heat_info'); 
     208        var info_message = '色の上にマウスを乗せるとコメント数を表示します.'; 
     209        heat_comments_info.style.background = '#fff url('+ARROW_DATA+') no-repeat'; 
     210        heat_comments_info.innerHTML = info_message; 
     211        heat_comments_info.setAttribute('title', info_message); 
     212 
     213        var reload_link = document.createElement('a'); 
     214        reload_link.id = 'heat_reload_link'; 
     215        reload_link.appendChild(document.createTextNode('再読込み')); 
     216        reload_link.title = 'Reload Comment Heat Map' 
     217        Element.buttonize(reload_link, function() { 
     218            Element.remove(output); 
     219            heat_map(); 
    152220        }); 
    153221 
    154         function extract(res) { 
    155             var responseXML = (new DOMParser).parseFromString(res.responseText, "application/xml"); 
    156             var comments = responseXML.getElementsByTagName('chat'); 
    157             var counts = new Array(DIVISION).fill(0); 
    158             if(/^sm(\d+)$/.test(unsafeWindow.video_id)) { 
    159                 var sm_video_id = RegExp.$1; 
    160             } else { 
    161                 var message = document.createElement('p'); 
    162                 message.id = 'heat_message'; 
    163                 message.innerHTML = 'Sorry, this video is unsupported.' 
    164                 output.innerHTML = ''; 
    165                 output.appendChild(message); 
    166                 return; 
    167             } 
    168             var vlmsec = vlsec.to_i() * 100; 
    169             for(var i = 0, len = comments.length; i < len; i++) { 
    170                 var pmsec = comments[i].getAttribute('vpos'); 
    171                 if(vlmsec > pmsec) { 
    172                     counts[~~(pmsec / vlmsec * DIVISION)]++; 
    173                 } else if(vlmsec == pmsec){ 
    174                     counts[DIVISION-1]++; 
    175                 } 
    176             } 
    177             var max = counts.max(); 
    178             var per_msec = vlmsec / DIVISION; 
    179             var color_map_size = COLOR_MAP.length - 1; 
    180             output.innerHTML = ''; 
    181             for(var i = 0, len = counts.length; i < len; i++){ 
    182                 var start_msec = per_msec * i; 
    183                 var end_msec = start_msec + per_msec - 1; 
    184  
    185                 var span = document.createElement('span'); 
    186                 var index = ~~(counts[i] * color_map_size / max); 
    187                 var color = COLOR_MAP[index]; 
    188                 var comment_info_header = 'コメント数:'; 
    189                 var comment_info_html = ['<span class="heat_level', index, '">', 
    190                     counts[i], '</span>'].join(''); 
    191                 var comment_info_footer = [ 
    192                     '(', (~~(to_min(start_msec))).z(2), ':', 
    193                     (~~(to_sec(start_msec) % 60)).z(2), '〜', 
    194                     (~~(to_min(end_msec))).z(2), ':', 
    195                     (~~(to_sec(end_msec) % 60)).z(2), ')'].join(''); 
    196                 span.style.color = color; 
    197                 span.style.backgroundColor = color; 
    198                 span.title = comment_info_header + counts[i] + comment_info_footer; 
    199                 span.innerHTML = comment_info_header + comment_info_html + comment_info_footer; 
    200                 span.setAttribute('class', i); 
    201                 output.appendChild(span); 
    202             } 
    203  
    204             var message = document.createElement('p'); 
    205             message.setAttribute('id', 'heat_message'); 
    206             message.innerHTML = 'Comment Heat Map for nicovideo おまけ機能\u2192 '; 
    207  
    208             var heat_comments_info = document.createElement('p'); 
    209             heat_comments_info.setAttribute('id', 'heat_info'); 
    210             var info_message = '色の上にマウスを乗せるとコメント数を表示します.'; 
    211             heat_comments_info.style.background = '#fff url('+ARROW_DATA+') no-repeat'; 
    212             heat_comments_info.innerHTML = info_message; 
    213             heat_comments_info.setAttribute('title', info_message); 
    214  
    215             var reload_link = document.createElement('a'); 
    216             reload_link.id = 'heat_reload_link'; 
    217             reload_link.appendChild(document.createTextNode('再読込み')); 
    218             reload_link.title = 'Reload Comment Heat Map' 
    219             Element.buttonize(reload_link, function() { 
    220                 Element.remove(output); 
    221                 heat_map(); 
    222             }); 
    223  
    224             var filter_link = document.createElement('a'); 
    225             filter_link.setAttribute('id', 'heat_filter_link'); 
    226             filter_link.setAttribute('title', '設定されているフィルター一覧を表示する(ネタバレ注意)'); 
    227             filter_link.appendChild(document.createTextNode('フィルター')); 
    228             Element.buttonize(filter_link, function() { 
    229                 Element.toggle(filter_list) 
    230             }); 
    231  
    232             /*            var relational_video = document.createElement('a'); 
     222        var filter_link = document.createElement('a'); 
     223        filter_link.setAttribute('id', 'heat_filter_link'); 
     224        filter_link.setAttribute('title', '設定されているフィルター一覧を表示する(ネタバレ注意)'); 
     225        filter_link.appendChild(document.createTextNode('フィルター')); 
     226        Element.buttonize(filter_link, function() { 
     227            Element.toggle(filter_list) 
     228        }); 
     229 
     230        /*            var relational_video = document.createElement('a'); 
    233231            relational_video.setAttribute('id', 'heat_relational_video'); 
    234232            relational_video.setAttribute('title', 'この動画を見た人は,こんな動画も見ています'); 
     
    238236            }); 
    239237*/ 
    240             var download_link = document.createElement('a'); 
    241             download_link.setAttribute('id', 'heat_download_link'); 
    242             download_link.setAttribute('title', '動画をダウンロードする'); 
    243             download_link.appendChild(document.createTextNode('動画ダウンロード')); 
    244             Element.buttonize(download_link, function() {}); 
    245             download_link.setAttribute('href', download_url); 
    246  
    247             output.appendChild(reload_link); 
    248             output.appendChild(heat_comments_info); 
    249             if(WIDTH == WIDTH_) { 
    250                 message.appendChild(download_link); 
    251                 message.appendChild(filter_link); 
    252                 //              message.appendChild(relational_video); 
    253                 output.appendChild(message); 
    254             }; 
    255  
     238        var download_link = document.createElement('a'); 
     239        download_link.setAttribute('id', 'heat_download_link'); 
     240        download_link.setAttribute('title', '動画をダウンロードする'); 
     241        download_link.appendChild(document.createTextNode('動画ダウンロード')); 
     242        Element.buttonize(download_link, function() {}); 
     243        download_link.setAttribute('href', download_url); 
     244 
     245        output.appendChild(reload_link); 
     246        output.appendChild(heat_comments_info); 
     247        if(WIDTH == WIDTH_) { 
     248            message.appendChild(download_link); 
     249            message.appendChild(filter_link); 
     250            //              message.appendChild(relational_video); 
     251            output.appendChild(message); 
     252        }; 
     253 
     254        setSpanWidth(); 
     255 
     256        var filter_list = document.createElement('div'); 
     257        filter_list.setAttribute('id', 'heat_filter_list'); 
     258        Element.setStyle(filter_list, { 
     259            display: 'none', 
     260            top: output.offsetHeight + 10 + 'px', 
     261            left: filter_link.offsetLeft + 'px' 
     262        }); 
     263        if(video_info.ng_up) { 
     264            var filter_words = video_info.ng_up.split('&'); 
     265            var filters = ['<h3>フィルター一覧</h3>']; 
     266            filters.push('<ul>'); 
     267            for(var i=0,length=filter_words.length; i<length; i++) { 
     268                var filter = filter_words[i].split('='); 
     269                filters.push('<li><a href="javascript:void(0);" title="'); 
     270                filters.push(decodeURIComponent(filter[1])); 
     271                filters.push('" onclick="$(\'flvplayer\').SetVariable(\'ChatInput.text\', \''); 
     272                filters.push(decodeURIComponent(filter[0])); 
     273                filters.push('\'); return false;">'); 
     274                filters.push(decodeURIComponent(filter[0])); 
     275                filters.push('</a></li>'); 
     276            } 
     277            filters.push('</ul>'); 
     278            filters = filters.join(''); 
     279        } else { 
     280            var filters = '<h3>フィルターは設定されていません</h3>'; 
     281        } 
     282        var close = document.createElement('a'); 
     283        close.appendChild(document.createTextNode('x')); 
     284        close.setAttribute('title', '閉じる'); 
     285        close.setAttribute('href', 'javascript:void(0);'); 
     286        Element.addClassName(close, 'heat_close'); 
     287        close.addEventListener('click', function() { 
     288            Element.hide(this.parentNode); 
     289        }, false); 
     290        filter_list.innerHTML = filters; 
     291        filter_list.appendChild(close); 
     292        message.appendChild(filter_list); 
     293 
     294        var max_comment_num = document.createElement('p'); 
     295        max_comment_num.setAttribute('id', 'heat_max_comment_num'); 
     296        max_comment_num.innerHTML = max; 
     297        var min_comment_num = document.createElement('p'); 
     298        min_comment_num.setAttribute('id', 'heat_min_comment_num'); 
     299        min_comment_num.innerHTML = '0'; 
     300        output.appendChild(max_comment_num); 
     301        output.appendChild(min_comment_num); 
     302 
     303        $('heat_max_comment_num').title = $$('span.heat_level'+color_map_size).first().parentNode.title; 
     304        output.style.background = '#fff url('+THERMOGRAPH_DATA+') no-repeat scroll 10px 5px'; 
     305    } 
     306 
     307    function to_hour(msec) { 
     308        return(to_min(msec) / 60); 
     309    } 
     310 
     311    function to_min(msec) { 
     312        return(to_sec(msec) / 60); 
     313    } 
     314 
     315    function to_sec(msec) { 
     316        return(msec / 100); 
     317    } 
     318 
     319    function parseQueryString(hash, pair) { 
     320        if ((pair = pair.split('='))[0]) { 
     321            var name = decodeURIComponent(pair[0]); 
     322            var value = pair[1] ? decodeURIComponent(pair[1]) : undefined; 
     323 
     324            if (hash[name] !== undefined) { 
     325                if (hash[name].constructor != Array) 
     326                    hash[name] = [hash[name]]; 
     327                if (value) hash[name].push(value); 
     328            } 
     329            else hash[name] = value; 
     330        } 
     331        return hash; 
     332    } 
     333 
     334    Element.buttonize = function(elem, func) { 
     335        Element.addClassName(elem, 'button'); 
     336        elem.setAttribute('href', 'javascript:void(0);'); 
     337        elem.addEventListener('mouseout', function() { 
     338            Element.removeClassName(elem, 'click'); 
     339        }, false); 
     340        elem.addEventListener('mousedown', function() { 
     341            Element.addClassName(elem, 'click'); 
     342        }, false); 
     343        elem.addEventListener('mouseup', function() { 
     344            Element.removeClassName(elem, 'click'); 
     345        }, false); 
     346        elem.addEventListener('click', func, false); 
     347    } 
     348 
     349    unsafeWindow.fitPlayerToWindow = function() { 
     350        var seek_width = window.innerWidth - 339 - 77; 
     351        WIDTH = seek_width / (DIVISION - 1); 
     352        setSpanWidth(); 
     353        $("flvplayer").setStyle({width: "100%", height: "100%"}); 
     354        var player_height = $('PAGEBODY').offsetHeight - $('heat_output').offsetHeight - 1 + 'px'; 
     355        $('flvplayer_container').setStyle({height: player_height}); 
     356    } 
     357 
     358    unsafeWindow.toggleMaximizePlayer = function() { 
     359        if (unsafeWindow.playerMaximized) { 
     360            unsafeWindow.restorePlayer(); 
     361            $('heat_output').style.paddingLeft = '79px'; 
     362            WIDTH = WIDTH_; 
    256363            setSpanWidth(); 
    257  
    258             var filter_list = document.createElement('div'); 
    259             filter_list.setAttribute('id', 'heat_filter_list'); 
    260             Element.setStyle(filter_list, { 
    261                 display: 'none', 
    262                 top: output.offsetHeight + 10 + 'px', 
    263                 left: filter_link.offsetLeft + 'px' 
    264             }); 
    265             if(video_info.ng_up) { 
    266                 var filter_words = video_info.ng_up.split('&'); 
    267                 var filters = ['<h3>フィルター一覧</h3>']; 
    268                 filters.push('<ul>'); 
    269                 for(var i=0,length=filter_words.length; i<length; i++) { 
    270                     var filter = filter_words[i].split('='); 
    271                     filters.push('<li><a href="javascript:void(0);" title="'); 
    272                     filters.push(decodeURIComponent(filter[1])); 
    273                     filters.push('" onclick="$(\'flvplayer\').SetVariable(\'ChatInput.text\', \''); 
    274                     filters.push(decodeURIComponent(filter[0])); 
    275                     filters.push('\'); return false;">'); 
    276                     filters.push(decodeURIComponent(filter[0])); 
    277                     filters.push('</a></li>'); 
    278                 } 
    279                 filters.push('</ul>'); 
    280                 filters = filters.join(''); 
    281             } else { 
    282                 var filters = '<h3>フィルターは設定されていません</h3>'; 
    283             } 
    284             var close = document.createElement('a'); 
    285             close.appendChild(document.createTextNode('x')); 
    286             close.setAttribute('title', '閉じる'); 
    287             close.setAttribute('href', 'javascript:void(0);'); 
    288             Element.addClassName(close, 'heat_close'); 
    289             close.addEventListener('click', function() { 
    290                 Element.hide(this.parentNode); 
    291             }, false); 
    292             filter_list.innerHTML = filters; 
    293             filter_list.appendChild(close); 
    294             message.appendChild(filter_list); 
    295  
    296             var max_comment_num = document.createElement('p'); 
    297             max_comment_num.setAttribute('id', 'heat_max_comment_num'); 
    298             max_comment_num.innerHTML = max; 
    299             var min_comment_num = document.createElement('p'); 
    300             min_comment_num.setAttribute('id', 'heat_min_comment_num'); 
    301             min_comment_num.innerHTML = '0'; 
    302             output.appendChild(max_comment_num); 
    303             output.appendChild(min_comment_num); 
    304  
    305             $('heat_max_comment_num').title = $$('span.heat_level'+color_map_size).first().parentNode.title; 
    306             output.style.background = '#fff url('+THERMOGRAPH_DATA+') no-repeat scroll 10px 5px'; 
    307         } 
    308  
    309         function to_hour(msec) { 
    310             return(to_min(msec) / 60); 
    311         } 
    312  
    313         function to_min(msec) { 
    314             return(to_sec(msec) / 60); 
    315         } 
    316  
    317         function to_sec(msec) { 
    318             return(msec / 100); 
    319         } 
    320  
    321         function parseQueryString(hash, pair) { 
    322             if ((pair = pair.split('='))[0]) { 
    323                 var name = decodeURIComponent(pair[0]); 
    324                 var value = pair[1] ? decodeURIComponent(pair[1]) : undefined; 
    325  
    326                 if (hash[name] !== undefined) { 
    327                     if (hash[name].constructor != Array) 
    328                         hash[name] = [hash[name]]; 
    329                     if (value) hash[name].push(value); 
    330                 } 
    331                 else hash[name] = value; 
    332             } 
    333             return hash; 
    334         } 
    335  
    336         Element.buttonize = function(elem, func) { 
    337             Element.addClassName(elem, 'button'); 
    338             elem.setAttribute('href', 'javascript:void(0);'); 
    339             elem.addEventListener('mouseout', function() { 
    340                 Element.removeClassName(elem, 'click'); 
    341             }, false); 
    342             elem.addEventListener('mousedown', function() { 
    343                 Element.addClassName(elem, 'click'); 
    344             }, false); 
    345             elem.addEventListener('mouseup', function() { 
    346                 Element.removeClassName(elem, 'click'); 
    347             }, false); 
    348             elem.addEventListener('click', func, false); 
    349         } 
    350  
    351         unsafeWindow.fitPlayerToWindow = function() { 
    352             var seek_width = window.innerWidth - 339 - 77; 
    353             WIDTH = seek_width / (DIVISION - 1); 
    354             setSpanWidth(); 
    355             $("flvplayer").setStyle({width: "100%", height: "100%"}); 
    356             var player_height = $('PAGEBODY').offsetHeight - $('heat_output').offsetHeight - 1 + 'px'; 
    357             $('flvplayer_container').setStyle({height: player_height}); 
    358         } 
    359  
    360         unsafeWindow.toggleMaximizePlayer = function() { 
    361             if (unsafeWindow.playerMaximized) { 
    362                 unsafeWindow.restorePlayer(); 
    363                 $('heat_output').style.paddingLeft = '79px'; 
    364                 WIDTH = WIDTH_; 
    365                 setSpanWidth(); 
    366                 $('heat_message').show(); 
    367             } else { 
    368                 $('heat_message').hide(); 
    369                 $('heat_output').style.paddingLeft = '77px'; 
    370                 unsafeWindow.maximizePlayer(); 
    371             } 
    372             commentsCountArea($('heat_info'), $$('span.0').first()); 
    373             unsafeWindow.playerMaximized = !unsafeWindow.playerMaximized; 
    374         } 
    375  
    376     } 
    377  
    378     function commentsCountArea(node, span) { 
    379         node.innerHTML = span.innerHTML; 
    380         var position_x = -8 + WIDTH / 2 + span.getAttribute('class').to_i() * WIDTH; 
    381         node.style.backgroundPosition = position_x + 'px 0px'; 
    382         node.style.color = span.style.color; 
    383         node.style.display = 'block'; 
    384     } 
    385  
    386     function setSpanWidth() { 
    387         $$('#heat_output > span').each(function(node) { 
    388             node.setStyle({width: WIDTH + 'px'}); 
    389             /*node.addEventListener('mouseover', function(){ 
     364            $('heat_message').show(); 
     365        } else { 
     366            $('heat_message').hide(); 
     367            $('heat_output').style.paddingLeft = '77px'; 
     368            unsafeWindow.maximizePlayer(); 
     369        } 
     370        commentsCountArea($('heat_info'), $$('span.0').first()); 
     371        unsafeWindow.playerMaximized = !unsafeWindow.playerMaximized; 
     372    } 
     373 
     374} 
     375 
     376function commentsCountArea(node, span) { 
     377    node.innerHTML = span.innerHTML; 
     378    var position_x = -8 + WIDTH / 2 + span.getAttribute('class').to_i() * WIDTH; 
     379    node.style.backgroundPosition = position_x + 'px 0px'; 
     380    node.style.color = span.style.color; 
     381    node.style.display = 'block'; 
     382} 
     383 
     384function setSpanWidth() { 
     385    $$('#heat_output > span').each(function(node) { 
     386        node.setStyle({width: WIDTH + 'px'}); 
     387        /*node.addEventListener('mouseover', function(){ 
    390388                commentsCountArea($('heat_info'), node); 
    391389                }, false);*/ 
     390    }); 
     391} 
     392 
     393function wait_ready() { 
     394    var vlsec = $('flvplayer').GetVariable('ContentLength'); 
     395    if(typeof vlsec == 'undifined') return 0; 
     396    var interval = vlsec / DIVISION / 10; 
     397    if(interval > 1) interval = 1; 
     398    return interval; 
     399} 
     400 
     401function follow_seek_bar() { 
     402    var vlsec = $('flvplayer').GetVariable('ContentLength'); 
     403    if(typeof vlsec == 'undefined') return; 
     404    var percent_video_moving = $('flvplayer').GetVariable('moved_time') / vlsec; 
     405    var spans = $$('span.' + ~~(percent_video_moving * DIVISION)); 
     406    if(spans.size() == 0) return; 
     407    commentsCountArea($('heat_info'), spans.first()); 
     408} 
     409 
     410var PE = unsafeWindow.PeriodicalExecuter; 
     411var ready = /l=\d+&/; 
     412var waiting =new PE(function() { 
     413    var frequency = wait_ready(); 
     414    var nico = $('flvplayer').GetVariable('nico.o'); 
     415    if(frequency > 0) { 
     416        this.callback = follow_seek_bar; 
     417        this.frequency = frequency; 
     418        heat_map(); 
     419    } else if(nico && ready.test(nico)) { 
     420        waiting.stop(); 
     421        update_for_flv(); 
     422    } 
     423}, 0.5); 
     424 
     425function update_for_flv() { 
     426    var info = document.createElement('div'); 
     427    var head = document.createElement('h3'); 
     428    head.appendChild(document.createTextNode('flvplayer_wrapper customをお使いの方へ')); 
     429    var para = document.createElement('p'); 
     430    var text = [ 
     431        'コメント盛り上り度(弾幕,コメント職人)を可視化するGreasemonkeyスクリプト', 
     432        'がflvplayer_wrapper(custom)と共存できるようになりました.' 
     433    ].join(''); 
     434    para.appendChild(document.createTextNode(text)); 
     435    para.appendChild(document.createElement('br')); 
     436    var link = document.createElement('a'); 
     437    link.href = 'http://blog.fulltext-search.biz/pages/visualize-comments-upsurge-greasemonkey-script-for-nicovideo'; 
     438    link.appendChild(document.createTextNode('コチラからダウンロードしてください')); 
     439    para.appendChild(link) 
     440    info.appendChild(head); 
     441    info.appendChild(para); 
     442    $('WATCHFOOTER').parentNode.insertBefore(info, $('WATCHFOOTER')); 
     443} 
     444 
     445//instantiate and run 
     446GM_addStyle(<><![CDATA[ 
     447    #heat_output { 
     448        padding: 5px 1em 3px 79px; 
     449        font-size: 80%; 
     450        border: 1px solid #333; 
     451        position: relative; 
     452        min-height: 85px; 
     453                margin-bottom: 10px; 
     454    } 
     455    #heat_output > span { 
     456        display: block; 
     457        height: 1.4em; 
     458        float: left; 
     459        cursor: default; 
     460        overflow: hidden; 
     461    } 
     462    #heat_output a.button { 
     463        margin-left: 1em; 
     464        padding: 0pt 0.5em; 
     465        text-decoration: none; 
     466        border: 2px solid #444; 
     467    } 
     468    #heat_output a.button:link, 
     469    #heat_output a.button:visited { 
     470        border-left: 1px solid #999; 
     471        border-top: 1px solid #999; 
     472    } 
     473    #heat_output a.button.click { 
     474        border: 2px solid #444; 
     475        border-right: 1px solid #999; 
     476        border-bottom: 1px solid #999; 
     477    } 
     478    #heat_output a.heat_close { 
     479        background-color: #f88; 
     480        border: 1px solid #fff; 
     481        color: #fff; 
     482        font-weight: bold; 
     483        line-height: 1; 
     484        padding: 0.18em 0.25em; 
     485        position: absolute; 
     486        right: 4px; 
     487        text-decoration: none; 
     488        top: 4px; 
     489    } 
     490    #heat_info { 
     491        clear: left; 
     492        margin: 2px 0pt 5px; 
     493        padding-top: 18px; 
     494        font-weight: bold; 
     495        height: 2.8em; 
     496    } 
     497    #heat_info span { 
     498        color: #333; 
     499        margin: 0pt 0.2em; 
     500    } 
     501    #heat_info span.heat_level0 { font-size: 80%; } 
     502    #heat_info span.heat_level1 { font-size: 85%; } 
     503    #heat_info span.heat_level2 { font-size: 90%; } 
     504    #heat_info span.heat_level3 { font-size: 95%; } 
     505    #heat_info span.heat_level4 { font-size: 100%; } 
     506    #heat_info span.heat_level5 { font-size: 105%; } 
     507    #heat_info span.heat_level6 { font-size: 110%; } 
     508    #heat_info span.heat_level7 { font-size: 115%; } 
     509    #heat_info span.heat_level8 { font-size: 120%; } 
     510    #heat_info span.heat_level9 { font-size: 130%; } 
     511    #heat_info span.heat_level10 { font-size: 140%; } 
     512    #heat_info span.heat_level11 { font-size: 150%; } 
     513    #heat_info span.heat_level12 { font-size: 170%; } 
     514    #heat_info span.heat_level13 { font-size: 200%; } 
     515    #heat_info span.heat_level14 { font-size: 230%; } 
     516    #heat_info span.heat_level15 { font-size: 280%; } 
     517    #heat_max_comment_num, #heat_min_comment_num { 
     518        font-size: 10px; 
     519        position: absolute; 
     520        padding-left: 35px; 
     521        left: 0px; 
     522    } 
     523    #heat_max_comment_num { 
     524        top: 5px; 
     525    } 
     526    #heat_min_comment_num { 
     527        top: 77px; 
     528    } 
     529    #heat_filter_list { 
     530        position: absolute; 
     531        width: 300px; 
     532        border: #3a3 1px solid; 
     533        z-index: 4; 
     534        background-color: #eee; 
     535        padding: 0.5em 10px; 
     536    } 
     537    #heat_filter_list ul { 
     538        margin: 5px 0; 
     539        padding: 0; 
     540        font-family: Tahoma, Arial, Helvetica, sans-serif; 
     541        font-size: 13px; 
     542        line-height: 1.5; 
     543    } 
     544    #heat_filter_list ul li { 
     545        margin: 0 5px 3px 0; 
     546        padding: 0; 
     547        display: inline; 
     548        font-size: 100%; 
     549        list-style: none; 
     550    } 
     551    #heat_filter_list ul li a { 
     552        text-decoration: none; 
     553        border: #aaa 1px solid; 
     554        padding: 2px; 
     555        background-color: #fff; 
     556    } 
     557    #heat_filter_list ul li a:hover { 
     558        background-color: #333; 
     559        color: #fff; 
     560    } 
     561]]></>); 
     562 
     563 
     564Array.prototype.fill = function(v){ 
     565    for(var i=0,l=this.length;i<l;this[i++]=v); 
     566    return this; 
     567} 
     568 
     569Array.prototype.max = function(){ 
     570    return Math.max.apply(null,this) 
     571} 
     572 
     573Array.prototype.inject = function(memo, iterator) { 
     574    for (var i = 0, length = this.length; i < length; i++) 
     575        memo = iterator(memo, this[i], i); 
     576    return memo; 
     577} 
     578 
     579String.prototype.to_i = function(){ 
     580    return parseInt(this, 10) 
     581} 
     582 
     583Number.prototype.z = function(len){ 
     584    if(Math.pow(10,len) <= this) return this.toString(); 
     585    var s = '0'.fill(len) + this.toString(); 
     586    return s.substr(s.length - len); 
     587}; 
     588String.prototype.fill = function(len){ 
     589    var result = ''; 
     590    for(var i = 0; i < len; i++){ 
     591        result += this; 
     592    } 
     593    return result; 
     594}; 
     595 
     596function GM_wrap(f) { 
     597    return function() { 
     598        setTimeout.apply(window, [f, 0].concat([].slice.call(arguments))); 
     599    }; 
     600} 
     601 
     602// Auto UserScript Updater 
     603function UpdateChecker() {}; 
     604UpdateChecker.prototype = { 
     605    script_name: 'Heat the nicovideo up', 
     606    script_url: 'http://blog.fulltext-search.biz/files/heatthenicovideoup.user.js', 
     607    current_version: '0.3.2', 
     608    more_info_url: 'http://blog.fulltext-search.biz/pages/visualize-comments-upsurge-greasemonkey-script-for-nicovideo', 
     609 
     610    remote_version: null, 
     611 
     612    // Render update information in HTML 
     613    render_update_info: function() { 
     614        var self = this; 
     615        var newversion = document.createElement('div'); 
     616        newversion.setAttribute('id', 'gm_update_alert'); 
     617        var update_message = document.createElement('p'); 
     618        update_message.innerHTML = [ 
     619            '現在お使いのGreasemonkeyスクリプト \'', 
     620            this.script_name, 
     621            '(var. ', this.current_version, ')', 
     622            '\' は新しいバージョン ', 
     623            this.remote_version, 
     624            ' が公開されています.アップデートしますか?' 
     625        ].join(''); 
     626 
     627        var update_link = document.createElement('a'); 
     628        update_link.setAttribute('id', 'gm_update_alert_link'); 
     629        update_link.setAttribute('href', this.script_url); 
     630        update_link.addEventListener('click', function() { 
     631            var update_alert = document.getElementById('gm_update_alert'); 
     632            update_alert.parentNode.removeChild(update_alert); 
     633        }, false); 
     634        update_link.innerHTML = 
     635            '[Yes]今すぐアップデートする'; 
     636 
     637        if(this.more_info_url) { 
     638            var more_link = document.createElement('a'); 
     639            more_link.setAttribute('href', this.more_info_url); 
     640            more_link.innerHTML = '(詳細情報)'; 
     641            update_message.appendChild(more_link); 
     642        } 
     643 
     644        var close_link = document.createElement('a'); 
     645        close_link.setAttribute('href', 'javascript:void(0);'); 
     646        close_link.addEventListener('click', function() { 
     647            GM_wrap(GM_setValue)('last_check_day', self.beginning_of_day().toString()); 
     648            var update_alert = document.getElementById('gm_update_alert'); 
     649            update_alert.parentNode.removeChild(update_alert); 
     650        }, false); 
     651        close_link.innerHTML = [ 
     652            '[No]今はアップデートしない(日付が変わるまで有効)' 
     653        ].join(''); 
     654 
     655        var scroll_link = document.createElement('a'); 
     656        if(/(.*?)\#/.test(document.location)) { 
     657            scroll_link.href = RegExp.$1 + '#gm_update_alert'; 
     658        } else { 
     659            scroll_link.href = document.location + '#gm_update_alert'; 
     660        } 
     661        scroll_link.innerHTML = '(ページ最上部に"' + this.script_name + '"からのお知らせがあります)'; 
     662 
     663        newversion.appendChild(update_message); 
     664        newversion.appendChild(update_link); 
     665        newversion.appendChild(close_link); 
     666        document.body.appendChild(newversion); 
     667        var target = document.getElementById('WATCHFOOTER'); 
     668        target.parentNode.insertBefore(scroll_link, target); 
     669    }, 
     670 
     671    add_update_info_style: function() { 
     672        GM_addStyle(<><![CDATA[ 
     673            /* style(like CSS) for update information */ 
     674            #gm_update_alert { 
     675                padding: 5px 0pt; 
     676                background-color: #FFF280; 
     677                color: #CC0099; 
     678                width: 100%; 
     679                position: absolute; 
     680                z-index: 99; 
     681                top: 0px; 
     682                left: 0px; 
     683                text-align: center; 
     684                font-size: 11px; 
     685                font-family: Tahoma; 
     686            } 
     687 
     688            #gm_update_alert p { 
     689                margin: 0pt; 
     690            } 
     691 
     692            #gm_update_alert a:link { 
     693                color: #333333; 
     694            } 
     695 
     696            #gm_update_alert > a:link { 
     697                margin: 0.5em 1em 0pt 1em; 
     698            } 
     699 
     700            #gm_update_alert p + a:link, 
     701            #gm_update_alert p + a:visited, 
     702            #gm_update_alert p + a:active, 
     703            #gm_update_alert p + a:hover { 
     704                font-weight: bold; 
     705            } 
     706        ]]></>); 
     707    }, 
     708 
     709    // Check script update remote 
     710    check_update: function() { 
     711        if(!this.has_need_for_check()) return; 
     712        var user_script = this; 
     713        GM_xmlhttpRequest({ 
     714            method: 'GET', 
     715            url: this.script_url, 
     716            onload: function(res) { 
     717                user_script.remote_version = user_script.check_version(res.responseText); 
     718                if(user_script.remote_version && user_script.remote_version > user_script.current_version) { 
     719                    user_script.add_update_info_style(); 
     720                    user_script.render_update_info(); 
     721                } else { 
     722                    GM_setValue('last_check_day', user_script.beginning_of_day().toString()); 
     723                } 
     724            }, 
     725            onerror: function(res) { GM_log(res.status + ':' + res.responseText); } 
    392726        }); 
    393     } 
    394  
    395     function wait_ready() { 
    396         var vlsec = $('flvplayer').GetVariable('ContentLength'); 
    397         if(typeof vlsec == 'undifined') return 0; 
    398         var interval = vlsec / DIVISION / 10; 
    399         if(interval > 1) interval = 1; 
    400         return interval; 
    401     } 
    402  
    403     function follow_seek_bar() { 
    404         var vlsec = $('flvplayer').GetVariable('ContentLength'); 
    405         if(typeof vlsec == 'undefined') return; 
    406         var percent_video_moving = $('flvplayer').GetVariable('moved_time') / vlsec; 
    407         var spans = $$('span.' + ~~(percent_video_moving * DIVISION)); 
    408         if(spans.size() == 0) return; 
    409         commentsCountArea($('heat_info'), spans.first()); 
    410     } 
    411  
    412     var PE = unsafeWindow.PeriodicalExecuter; 
    413     var ready = /l=\d+&/; 
    414     var waiting =new PE(function() { 
    415         var frequency = wait_ready(); 
    416         var nico = $('flvplayer').GetVariable('nico.o'); 
    417         if(frequency > 0) { 
    418             this.callback = follow_seek_bar; 
    419             this.frequency = frequency; 
    420             heat_map(); 
    421         } else if(nico && ready.test(nico)) { 
    422             waiting.stop(); 
    423             update_for_flv(); 
    424         } 
    425     }, 0.5); 
    426  
    427     function update_for_flv() { 
    428         var info = document.createElement('div'); 
    429         var head = document.createElement('h3'); 
    430         head.appendChild(document.createTextNode('flvplayer_wrapper customをお使いの方へ')); 
    431         var para = document.createElement('p'); 
    432         var text = [ 
    433             'コメント盛り上り度(弾幕,コメント職人)を可視化するGreasemonkeyスクリプト', 
    434             'がflvplayer_wrapper(custom)と共存できるようになりました.' 
    435         ].join(''); 
    436         para.appendChild(document.createTextNode(text)); 
    437         para.appendChild(document.createElement('br')); 
    438         var link = document.createElement('a'); 
    439         link.href = 'http://blog.fulltext-search.biz/pages/visualize-comments-upsurge-greasemonkey-script-for-nicovideo'; 
    440         link.appendChild(document.createTextNode('コチラからダウンロードしてください')); 
    441         para.appendChild(link) 
    442         info.appendChild(head); 
    443         info.appendChild(para); 
    444         $('WATCHFOOTER').parentNode.insertBefore(info, $('WATCHFOOTER')); 
    445     } 
    446  
    447     Array.prototype.fill = function(v){ 
    448         for(var i=0,l=this.length;i<l;this[i++]=v); 
    449         return this 
    450     } 
    451  
    452     Array.prototype.max = function(){ 
    453         return Math.max.apply(null,this) 
    454     } 
    455  
    456     Array.prototype.inject = function(memo, iterator) { 
    457         for (var i = 0, length = this.length; i < length; i++) 
    458             memo = iterator(memo, this[i], i); 
    459         return memo; 
    460     } 
    461  
    462     String.prototype.to_i = function(){ 
    463         return parseInt(this, 10) 
    464     } 
    465  
    466     Number.prototype.z = function(len){ 
    467         if(Math.pow(10,len) <= this) return this.toString(); 
    468         var s = '0'.fill(len) + this.toString(); 
    469         return s.substr(s.length - len); 
    470     }; 
    471     String.prototype.fill = function(len){ 
    472         var result = ''; 
    473         for(var i = 0; i < len; i++){ 
    474             result += this; 
    475         } 
    476         return result; 
    477     }; 
    478  
    479     function UpdateChecker() {}; 
    480     UpdateChecker.prototype = { 
    481         script_name: 'Heat the nicovideo up', 
    482         script_url: 'http://blog.fulltext-search.biz/files/heatthenicovideoup.user.js', 
    483         current_version: '0.3.1', 
    484         more_info_url: 'http://blog.fulltext-search.biz/pages/visualize-comments-upsurge-greasemonkey-script-for-nicovideo', 
    485  
    486         remote_version: null, 
    487  
    488         // Render update information in HTML 
    489         render_update_info: function() { 
    490             var newversion = document.createElement('div'); 
    491             newversion.setAttribute('id', 'gm_update_alert'); 
    492             var update_message = document.createElement('p'); 
    493             update_message.innerHTML = [ 
    494                 '現在お使いのGreasemonkeyスクリプト \'', 
    495                 this.script_name, 
    496                 '(var. ', this.current_version, ')', 
    497                 '\' は新しいバージョン ', 
    498                 this.remote_version, 
    499                 ' が公開されています.アップデートしますか?' 
    500             ].join(''); 
    501  
    502             var update_link = document.createElement('a'); 
    503             update_link.setAttribute('id', 'gm_update_alert_link'); 
    504             update_link.setAttribute('href', this.script_url); 
    505             update_link.addEventListener('click', function() { 
    506                 var update_alert = document.getElementById('gm_update_alert'); 
    507                 update_alert.parentNode.removeChild(update_alert); 
    508             }, false); 
    509             update_link.innerHTML = 
    510                 '[Yes]今すぐアップデートする'; 
    511  
    512             if(this.more_info_url) { 
    513                 var more_link = document.createElement('a'); 
    514                 more_link.setAttribute('href', this.more_info_url); 
    515                 more_link.innerHTML = '(詳細情報)'; 
    516                 update_message.appendChild(more_link); 
    517             } 
    518  
    519             var close_link = document.createElement('a'); 
    520             close_link.setAttribute('href', 'javascript:void(0);'); 
    521             close_link.addEventListener('click', function() { 
    522                 GM_setValue('last_check_day', new Date().days_since_start()); 
    523                 var update_alert = document.getElementById('gm_update_alert'); 
    524                 update_alert.parentNode.removeChild(update_alert); 
    525             }, false); 
    526             close_link.innerHTML = [ 
    527                 '[No]今はアップデートしない(日付が変わるまで有効)' 
    528             ].join(''); 
    529  
    530             var scroll_link = document.createElement('a'); 
    531             if(/(.*?)\#/.test(document.location)) { 
    532                 scroll_link.href = RegExp.$1 + '#gm_update_alert'; 
    533             } else { 
    534                 scroll_link.href = document.location + '#gm_update_alert'; 
    535             } 
    536             scroll_link.innerHTML = '(ページ最上部に\'Comment Heat Map for nicovideo\'からのお知らせがあります)'; 
    537  
    538             newversion.appendChild(update_message); 
    539             newversion.appendChild(update_link); 
    540             newversion.appendChild(close_link); 
    541             document.body.appendChild(newversion); 
    542             $('WATCHFOOTER').parentNode.insertBefore(scroll_link, $('WATCHFOOTER')); 
    543         }, 
    544  
    545         add_update_info_style: function() { 
    546             GM_addStyle(<><![CDATA[ 
    547                 /* style(like CSS) for update information */ 
    548                 #gm_update_alert { 
    549                     padding: 5px 0pt; 
    550                     background-color: #FFF280; 
    551                     color: #CC0099; 
    552                     width: 100%; 
    553                     position: absolute; 
    554                     z-index: 99; 
    555                     top: 0px; 
    556                     left: 0px; 
    557                     text-align: center; 
    558                     font-size: 11px; 
    559                     font-family: Tahoma; 
    560                 } 
    561  
    562                 #gm_update_alert p { 
    563                     margin: 0pt; 
    564                 } 
    565  
    566                 #gm_update_alert a:link { 
    567                     color: #333333; 
    568                 } 
    569  
    570                 #gm_update_alert > a:link { 
    571                     margin: 0.5em 1em 0pt 1em; 
    572                 } 
    573  
    574                 #gm_update_alert p + a:link { 
    575                     font-weight: bold; 
    576                 } 
    577             ]]></>); 
    578         }, 
    579  
    580         // Check script update remote 
    581         check_update: function() { 
    582             if(!this.has_need_for_check) return; 
    583             var user_script = this; 
    584             GM_xmlhttpRequest({ 
    585                 method: 'GET', 
    586                 url: this.script_url, 
    587                 onload: function(res) { 
    588                     user_script.remote_version = user_script.check_version(res.responseText); 
    589                     if(user_script.remote_version && user_script.remote_version > user_script.current_version) { 
    590                         user_script.add_update_info_style(); 
    591                         user_script.render_update_info(); 
    592                     } else { 
    593                         GM_setValue('last_check_day', new Date().days_since_start()); 
    594                     } 
    595                 }, 
    596                 onerror: function(res) { GM_log(res.status + ':' + res.responseText); } 
    597             }); 
    598         }, 
    599  
    600         // Check the necessity for update: [Boolean] 
    601         // return [true] if necessary 
    602         has_need_for_check: function() { 
    603             var last_check_day = GM_getValue('last_check_day'); 
    604             var current_day = new Date().days_since_start(); 
    605             if(typeof last_check_day == 'undefined' || current_day > last_check_day) { 
    606                 return true; 
    607             } else { 
    608                 return false; 
    609             } 
    610         }, 
    611  
    612         // Check version in remote script file: [String] 
    613         check_version: function(string) { 
    614             if(/\/\/\s?@version\s+([\d.]+)/.test(string)) { 
    615                 return RegExp.$1; 
    616             } else { 
    617                 return null; 
    618             } 
    619         } 
    620  
    621     }; 
    622  
    623     Date.prototype.days_since_start = function() { 
    624         var DAYS_IN_MONTH = [31,59,90,120,151,181,212,243,273,304,334,365]; 
    625         return(this.getYear() * 365 + DAYS_IN_MONTH[this.getMonth()] + this.getDate()); 
    626     }; 
    627  
    628     //instantiate and run 
    629     GM_addStyle(<><![CDATA[ 
    630         #heat_output { 
    631             padding: 5px 1em 3px 79px; 
    632             font-size: 80%; 
    633             border: 1px solid #333; 
    634             position: relative; 
    635             min-height: 85px; 
    636         } 
    637         #heat_output > span { 
    638             display: block; 
    639             height: 1.4em; 
    640             float: left; 
    641             cursor: default; 
    642             overflow: hidden; 
    643         } 
    644         #heat_output a.button { 
    645             margin-left: 1em; 
    646             padding: 0pt 0.5em; 
    647             text-decoration: none; 
    648             border: 2px solid #444; 
    649         } 
    650         #heat_output a.button:link, 
    651         #heat_output a.button:visited { 
    652             border-left: 1px solid #999; 
    653             border-top: 1px solid #999; 
    654         } 
    655         #heat_output a.button.click { 
    656             border: 2px solid #444; 
    657             border-right: 1px solid #999; 
    658             border-bottom: 1px solid #999; 
    659         } 
    660         #heat_output a.heat_close { 
    661             background-color: #f88; 
    662             border: 1px solid #fff; 
    663             color: #fff; 
    664             font-weight: bold; 
    665             line-height: 1; 
    666             padding: 0.18em 0.25em; 
    667             position: absolute; 
    668             right: 4px; 
    669             text-decoration: none; 
    670             top: 4px; 
    671         } 
    672         #heat_info { 
    673             clear: left; 
    674             margin: 2px 0pt 5px; 
    675             padding-top: 18px; 
    676             font-weight: bold; 
    677             height: 2.8em; 
    678         } 
    679         #heat_info span { 
    680             color: #333; 
    681             margin: 0pt 0.2em; 
    682         } 
    683         #heat_info span.heat_level0 { font-size: 80%; } 
    684         #heat_info span.heat_level1 { font-size: 85%; } 
    685         #heat_info span.heat_level2 { font-size: 90%; } 
    686         #heat_info span.heat_level3 { font-size: 95%; } 
    687         #heat_info span.heat_level4 { font-size: 100%; } 
    688         #heat_info span.heat_level5 { font-size: 105%; } 
    689         #heat_info span.heat_level6 { font-size: 110%; } 
    690         #heat_info span.heat_level7 { font-size: 115%; } 
    691         #heat_info span.heat_level8 { font-size: 120%; } 
    692         #heat_info span.heat_level9 { font-size: 130%; } 
    693         #heat_info span.heat_level10 { font-size: 140%; } 
    694         #heat_info span.heat_level11 { font-size: 150%; } 
    695         #heat_info span.heat_level12 { font-size: 170%; } 
    696         #heat_info span.heat_level13 { font-size: 200%; } 
    697         #heat_info span.heat_level14 { font-size: 230%; } 
    698         #heat_info span.heat_level15 { font-size: 280%; } 
    699         #heat_max_comment_num, #heat_min_comment_num { 
    700             font-size: 10px; 
    701             position: absolute; 
    702             padding-left: 35px; 
    703             left: 0px; 
    704         } 
    705         #heat_max_comment_num { 
    706             top: 5px; 
    707         } 
    708         #heat_min_comment_num { 
    709             top: 77px; 
    710         } 
    711         #heat_filter_list { 
    712             position: absolute; 
    713             width: 300px; 
    714             border: #3a3 1px solid; 
    715             z-index: 4; 
    716             background-color: #eee; 
    717             padding: 0.5em 10px; 
    718         } 
    719         #heat_filter_list ul { 
    720             margin: 5px 0; 
    721             padding: 0; 
    722             font-family: Tahoma, Arial, Helvetica, sans-serif; 
    723             font-size: 13px; 
    724             line-height: 1.5; 
    725         } 
    726         #heat_filter_list ul li { 
    727             margin: 0 5px 3px 0; 
    728             padding: 0; 
    729             display: inline; 
    730             font-size: 100%; 
    731             list-style: none; 
    732         } 
    733         #heat_filter_list ul li a { 
    734             text-decoration: none; 
    735             border: #aaa 1px solid; 
    736             padding: 2px; 
    737             background-color: #fff; 
    738         } 
    739         #heat_filter_list ul li a:hover { 
    740             background-color: #333; 
    741             color: #fff; 
    742         } 
    743     ]]></>); 
    744  
    745     var user_script = new UpdateChecker(); 
    746     user_script.check_update(); 
    747  
    748 })(); 
     727    }, 
     728 
     729    // Check the necessity for update: [Boolean] 
     730    // return [true] if necessary 
     731    has_need_for_check: function() { 
     732        var last_check_day = new Date(GM_getValue('last_check_day', "Thu Jan 01 1970 00:00:00 GMT+0900")); 
     733        var current_day = this.beginning_of_day(); 
     734        if(current_day > last_check_day) { 
     735            return true; 
     736        } else { 
     737            return false; 
     738        } 
     739    }, 
     740 
     741    // Check version in remote script file: [String] 
     742    check_version: function(string) { 
     743        if(/\/\/\s?@version\s+([\d.]+)/.test(string)) { 
     744            return RegExp.$1; 
     745        } else { 
     746            return null; 
     747        } 
     748    }, 
     749 
     750    beginning_of_day: function() { 
     751        var now = new Date(); 
     752        return(new Date(now.getFullYear(), now.getMonth(), now.getDate())); 
     753    } 
     754}; 
     755 
     756if(typeof GM_getValue('last_check_day') == 'number') 
     757    GM_setValue('last_check_day', "Thu Jan 01 1970 00:00:00 GMT+0900"); 
     758var user_script = new UpdateChecker(); 
     759user_script.check_update();