MediaWiki:Common.js/GECharts.js

/*global mw:true, Highcharts:true, addCommas:true, window:true, $:true, alert:true, location:true, document:true, setTimeout:true */ /*jshint devel:true, jquery: true, browser:true, strict:false */ (function {

var newhash = location.hash.replace(/\.([0-9a-f]{2})/gi, function (first) {       return String.fromCharCode(parseInt(first, 16));    }).replace(/ /g, '_');

if (newhash && newhash.match(/#[aiz]=/)) { location.hash = newhash; }

});

window._GEC = {}; var i,   _GEC = window._GEC, unescape = window.unescape, onkeydown = window.onkeydown;

_GEC.addedData = [];

$('.GEdatachart').attr('id', function (c) {   return "GEdatachart" + c; });

$('.GEdataprices').attr('id', function (c) {   return "GEdataprices" + c; });

$('.GEChartBox').each(function (c) {   $(this).find('.GEChartItems').attr('id', 'GEChartItems' + c); });

// general functions

function cloneObj(a, b) { var key;

if (typeof a !== 'object') { return ''; }   if (typeof b !== 'object') { b = {}; }   for (key in a) { if (a.hasOwnProperty(key)) { b[key] = a[key]; }   }    return b; }

function sum(arr) { var tot = 0;

for (i = 0; i < arr.length; i += 1) { tot += parseFloat(arr[i]) || 0; }   return tot; }

function avg(arr, amt, round) { amt = amt || arr.length; round = Math.pow(10, round || 0); var avgs = [], list = [];

for (i = 0; i < arr.length; i += 1) { list[i % amt] = arr[i][1]; if (i >= amt) { avgs.push([arr[i][0], Math.round((sum(list) / list.length) * round) / round]); }   }    return avgs; }

function toKMB(n) { n = parseInt(n.replace(/,/g, ''), 10); var neg = n < 0 ? '-' : '';   n = Math.abs(n); if (n >= 1e10) { n = Math.round(n / 1e8) / 10; n += 'B'; } else if (n >= 1e7) { n = Math.round(n / 1e5) / 10; n += 'M'; } else if (n >= 1e4) { n = Math.round(n / 100) / 10; n += 'K'; }   n = neg + n;    return addCommas(n); }

$('body').append('\n Close popup [X]  ' + ' Average:  days Add more item(s):  Note: If you add more items, the averages will not be shown. Submit  Reset all fields  Permanent link ' + '  ');

function getData(c, isSmall, avginput) { var isIndexChart = !!($('#GEdataprices' + c).attr('data-item') || '').match(/index/i), itemName = $('#GEdataprices' + c).attr('data-item'), prices = $('#GEdataprices' + c).html.split(/,\s/), data = [], thisprice, volumes = [], dataList, inputAvg, newhash, yAxis;

itemName = itemName || mw.config.get('wgPageName').replace(/_/g, ' ').split('/')[0].replace('Exchange:', ''); avginput = avginput || c;   for (i = 0; i < prices.length; i += 1) { if (prices[i].replace(/\s/g, '').length) { thisprice = prices[i].split(':'); data.push([ parseInt(thisprice[0], 10) * 1000, parseFloat(thisprice[1]) ]); if (thisprice[2] && !isSmall) { volumes.push([ parseInt(thisprice[0], 10) * 1000, parseFloat(thisprice[2]) * 1000000 ]); // volumes are in millions }       }    }

dataList = [{ name: itemName, data: data, lineWidth: isSmall ? 2 : 3   }];    if (itemName.toLowerCase === 'blank') { dataList[0].color = '#000000'; }   if (!isSmall && itemName.toLowerCase !== 'blank') { inputAvg = parseInt($('input#average' + avginput).val, 10); if (inputAvg) { newhash = location.hash.replace(/#a=[^#]*|$/, '#a=' + inputAvg).replace(/ /g, '_'); if (newhash.length) { location.hash = newhash; }       }        inputAvg = inputAvg || 30; dataList.push({           name: inputAvg + '-day average',            data: avg(data, inputAvg, isIndexChart ? 2 : 0),           lineWidth: 2,            dashStyle: 'shortdash'        }); if (volumes.length >= 10) { dataList.push({               name: 'Volume',                data: volumes,                type: 'area',                color: '#cc8400',                fillColor: {                    linearGradient: {                        x1: 0,                        y1: 0,                        x2: 0,                        y2: 1                    },                    stops: [                        [0, '#ffa500'],                        [1, 'white']                    ]                },                yAxis: 1            }); }   }    yAxis = {}; if (volumes.length >= 10 && !isSmall) { yAxis = [{ title: { text: isIndexChart ? 'Index history' : 'Price history', offset: 60, style: { color: 'black', fontSize: '12px' }           },            labels: { align: 'right', x: -8, y: 4 },           allowDecimals: false, minTickInterval: 1, // 1 coin showLastLabel: 1, lineWidth: 1, lineColor: '#E0E0E0', height: 225 }, {           title: { text: 'Trade volume', offset: 60, style: { color: 'black', fontSize: '12px' }           },            labels: { align: 'right', x: -8, y: 4 },           showEmpty: 0, showLastLabel: 1, offset: 0, lineWidth: 1, lineColor: '#E0E0E0', height: 75, top: 325, min: 0 }];   } else { yAxis = { title: { text: isSmall ? null : (isIndexChart ? 'Index history' : 'Price history'), offset: 60, style: { color: 'black', fontSize: '12px' }           },            labels: { align: 'right', x: -8, y: 4 },           allowDecimals: false, minTickInterval: 1, // 1 coin showLastLabel: 1, lineWidth: 1, lineColor: '#E0E0E0' };   }    return [dataList, yAxis]; }

function reloadChart(c, change) {

var prop;

if (!_GEC['chart' + c].options) { return false; }   for (prop in change) { if (change.hasOwnProperty(prop)) { _GEC['chart' + c].options[prop] = change[prop]; }   }    _GEC['chart' + c] = new Highcharts.StockChart(_GEC['chart' + c].options); }

function getSeriesIndex(id, match) { if (_GEC['chart' + id]) { var series = _GEC['chart' + id].series;

for (i = 0; i < series.length; i += 1) { if (series[i].name.match(match)) { return i;           } }       return -1; } }

function chartPermLinkUrl { var xt = _GEC.chartpopup.xAxis[0].getExtremes, minDate = (new Date(xt.min)).toDateString.split(' ').slice(1).join('_'), maxDate = (new Date(xt.max)).toDateString.split(' ').slice(1).join('_'), inputAvg = parseInt($('#averagepopup').val, 10), items = '', urlHash = '#t=' + minDate + ',' + maxDate;

for (i = 0; i < _GEC.chartpopup.series.length; i += 1) { if (_GEC.chartpopup.series[i].name === 'Navigator' || _GEC.chartpopup.series[i].name.match('average')) { continue; }

if (items.length) { items += ','; }

items += _GEC.chartpopup.series[i].name.replace(/ /, '_'); }

if (!isNaN(inputAvg)) { urlHash += '#a=' + inputAvg; }

urlHash += '#i=' + items;

return 'http://rs.wikia.com/wiki/GEMW/C' + urlHash; }

function setChartExtremes(i) { var extremes = _GEC['chart' + i].yAxis[0].getExtremes; if (extremes.dataMin * 0.95 !== extremes.userMin || extremes.dataMax * 1.05 !== extremes.userMax) { _GEC['chart' + i].yAxis[0].setExtremes(extremes.dataMin * 0.95, extremes.dataMax * 1.05); if (_GEC['chart' + i].yAxis[2]) { extremes = _GEC['chart' + i].yAxis[1].getExtremes; _GEC['chart' + i].yAxis[1].setExtremes(0, extremes.dataMax * 1.05); }   }    if (i === 'popup') { $('#GEPermLink' + i).get(0).href = chartPermLinkUrl; } }

function removeGraphItem(item, c) { var id, newhash, data;

for (i = 0; i < _GEC['chart' + c].series.length; i += 1) { if (_GEC['chart' + c].series[i].name.match(item)) { id = i;       } }   if (typeof id !== 'number') { return false; }   newhash = location.hash.replace(/_/g, ' ').replace(new RegExp('(#i=[^#]*),?' + item, 'i'), '$1').replace(/,,/g, ',').replace(/,#/g, '#').replace(/#i=,/g, '#i=').replace(/#i=($|#)/, '$1').replace(/ /g, '_'); if (newhash.replace('#i=', '').length) { location.hash = newhash; } else if (location.hash.length) { location.hash = ''; }   _GEC['chart' + c].series[id].remove; setChartExtremes(c); $('#addedItems' + c + ' [data-item="' + item + '"]').remove; $('#addedItems' + c).html($('#addedItems' + c).html.replace(/,, /g, ', ').replace(/, $/, '').replace(': , ', ': ')); if (!$('#addedItems' + c + ' [data-item]').length) { $('#addedItems' + c).empty; id = c === 'popup' ? $('#GEpopupchart').attr('data-chartid') : c;       data = getData(id, false); reloadChart(c, {           series: data[0],            yAxis: data[1]        }); $('#itemstats').show; }   return true; }

function setChartRange(c) { var zoom = parseInt((location.hash.match(/#z=([^#]*)/) || [])[1], 10), hash = location.hash, hasT = (mw.config.get('wgNamespaceNumber') === 112 && mw.config.get('wgTitle').split('/')[1] === 'Data') || mw.config.get('wgPageName') === 'Grand_Exchange_Market_Watch/Chart', timespan = unescape((hash.match(/#t=([^#]*)/) || [])[1] || '').replace(/_/g, ' ').split(','), dates = [new Date(timespan[0]), new Date(timespan[1])], d = new Date(timespan[0]), extremes = _GEC['chart' + c].xAxis[0].getExtremes, button;

zoom = zoom && zoom <= 6 && zoom >= 0 ? zoom - 1 : (zoom === 0 ? 0 : 2);

if (typeof c === 'number' && ((hasT && !hash.match('#t=')) || !hasT)) { $('#GEdatachart' + c + ' .zoomButton').eq(zoom).click; return true; }

if (dates[0] !== 'Invalid Date' && dates[1] === 'Invalid Date' && typeof zoom === 'number') { button = _GEC['chart' + c].rangeSelector.buttonOptions[zoom]; if (button.type === 'month') { d.setMonth(d.getMonth + button.count); } else if (button.type === 'year') { d.setYear(d.getFullYear + button.count); } else if (button.type === 'all') { d = new Date(extremes.dataMax); }       dates[1] = d;    } if (dates[0] !== 'Invalid Date' && dates[1] !== 'Invalid Date') { _GEC['chart' + c].xAxis[0].setExtremes(dates[0].getTime, dates[1].getTime); return true; }   return false; }

function loadChartsQueueComplete(c) { var id, chartdata, isSmall, data, index, itemhash, iname, hadBlank;

if (getSeriesIndex(_GEC.chartid, 'Volume') !== -1) { id = c === 'popup' ? $('#GEpopupchart').attr('data-chartid') : c;       chartdata = getData(id, true);

chartdata[1].title.text = 'Price history'; reloadChart(c, {           series: chartdata[0],            yAxis: chartdata[1]        }); }   isSmall = $('#GEdatachart' + c).is('.smallChart'); data = [_GEC.AIQueue.length];

for (i = 0; i < _GEC.AIData.length; i += 1) { index = _GEC.AIQueue.indexOf((_GEC.AIData[i] || { name: '' }).name.toLowerCase); data[index !== -1 ? index : data.length] = _GEC.AIData[i]; }   for (i = 0; i < data.length; i += 1) { if (data[i]) { _GEC['chart' + c].addSeries(data[i]); }       if (isSmall) { if (typeof _GEC.addedData[c] !== 'object') { _GEC.addedData[c] = []; }           _GEC.addedData[c][i] = data[i]; }   }    setChartExtremes(_GEC.chartid); $('#itemstats').hide; $('#extraItem' + c).prop('disabled', false).val(''); itemhash = (location.hash.match(/#i=[^#]*/) || [])[0] || location.hash + '#i='; for (i = 0; i < data.length; i += 1) { if (!data[i]) { continue; }       iname = data[i].name; if (!($('#addedItems' + c).html || ).replace(/\s+/, ).length) { $('#addedItems' + c).html('Remove items from graph: ' + iname + ''); itemhash = '#i=' + iname; } else { $('#addedItems' + c).append(', ' + iname + ''); itemhash += ',' + iname; }   }

if (location.hash.match(/#i=/)) { itemhash = location.hash.replace(/#i=[^#]*/, itemhash).replace(/ /g, '_'); } else { itemhash = location.hash + itemhash; }

if (((mw.config.get('wgNamespaceNumber') === 112 && mw.config.get('wgTitle').split('/')[1] === 'Data') || mw.config.get('wgPageName') === 'Grand_Exchange_Market_Watch/Chart') && itemhash.replace('#i=', '').length) { location.hash = itemhash; }   _GEC.AIQueue = []; _GEC.AILoaded = []; _GEC.AIData = []; hadBlank = removeGraphItem('Blank', c); if (hadBlank) { setChartRange(c); } }

_GEC.AIQueue = []; _GEC.AILoaded = []; _GEC.AIData = [];

function addItem(i, it) { var id, item = it || $('#extraItem' + _GEC.chartid).val, data, series;

_GEC.chartid = i;

if (item && item.length) { if ($('#addedItems' + i + ' [data-item], #GEdataprices' + i + '[data-item]').map(function { return $(this).attr('data-item').toLowerCase; }).get.indexOf(item.toLowerCase) !== -1 || _GEC.AIQueue.indexOf(item.toLowerCase) !== -1) { if (!it) { alert(item + ' is already in the graph.'); }           $('#extraItem' + _GEC.chartid).val(''); return false; }

$('#extraItem' + _GEC.chartid).prop('disabled', true);

$.get('/api.php?action=parse&format=json&page=Exchange:' + encodeURIComponent(item) + '/Data', function (response) {

var prices, thisprice;

if (response.error) { item = decodeURIComponent((this.url.match(/Exchange:([^\/]*)\/Data/) || [])[1]);

if ($('#extraItem' + _GEC.chartid).val.length) { if (response.error.code === 'missingtitle') { alert("The item " + item + " doesn't exist on our Grand Exchange database."); $('#extraItem' + _GEC.chartid).prop('disabled', false).val(''); } else { alert("An error occurred while loading " + item + "."); $('#extraItem' + _GEC.chartid).prop('disabled', false).val(''); }               }

_GEC.AILoaded.push(false);

if (_GEC.AIData.length && _GEC.AIQueue.length === _GEC.AILoaded.length) { loadChartsQueueComplete(_GEC.chartid); } else { if (!_GEC.AIData.length) { setChartRange(_GEC.chartid); }               }

$('#extraItem' + _GEC.chartid).prop('disabled', false).val(''); return false; }

if (response.links) { $.get('/api.php?action=parse&format=json&page=' + encodeURIComponent(response.links[0]['*']), this.success); return false; }

item = response.parse.title.match(/Exchange:([^\/]*)\/Data/)[1];

_GEC.AILoaded.push(item); _GEC.AILoaded.push(item); prices = response.parse.text['*']; data = [];

prices = prices.substring(prices.match(/\d{5,}:\d/).index, prices.match(/<\/p>/).index).split(/,\s/);

for (i = 0; i < prices.length; i += 1) { if (prices[i].replace(/\s/g, '').length) { thisprice = prices[i].split(':'); data.push([ parseInt(thisprice[0], 10) * 1000, parseInt(thisprice[1], 10) ]); }           }

_GEC.AIData.push({               name: item,                data: data,                id: item,                lineWidth: 2            });

series = _GEC['chart' + _GEC.chartid].series;

if (getSeriesIndex(_GEC.chartid, 'average') !== -1) { _GEC['chart' + _GEC.chartid].series[getSeriesIndex(_GEC.chartid, 'average')].remove; }

if (_GEC.AIQueue.length === _GEC.AILoaded.length) { loadChartsQueueComplete(_GEC.chartid); //This is always true when only 1 item is being loaded. }       });        _GEC.AIQueue.push(item.toLowerCase);    } else {        if ($('#addedItems' + i).html.match(/^\s*$/)) {            id = i === 'popup' ? $('#GEpopupchart').attr('data-chartid') : i;            data = getData(id, false, i);            series = _GEC['chart' + i].series;

if (getSeriesIndex(i, 'average') !== -1) { series[getSeriesIndex(i, 'average')].remove; }           _GEC['chart' + i].addSeries(data[0][1]); }   } }

function addPopupPriceInfo(c) {

var prices, data = [], curprice, datal, priceDiffs = [], percentDiffs = [], dayDiffs = [1, 7, 30, 90, 180], itemStats, pthen, pdiff;

if (($('#GEdataprices' + c).attr('data-item') || '').match(/index/i)) { return false; }   prices = $('#GEdataprices' + c).html.split(/,\s/);

for (i = 0; i < prices.length; i += 1) { if (prices[i].replace(/\s/g, '').length) { curprice = prices[i].split(':'); data.push(parseInt(curprice[1], 10)); }   }

datal = data.length; curprice = data[datal - 1];

for (i = 0; i < dayDiffs.length; i += 1) { pthen = data[datal - dayDiffs[i] - 1]; pdiff = curprice - pthen; if (!isNaN(pdiff)) { priceDiffs.push(pdiff); percentDiffs.push(Math.round(pdiff / pthen * 1000) / 10); } else { dayDiffs.slice(0, i + 1); }   }    function rg(n) { return n > 0 ? 'green' : (n === 0 ? 'blue' : 'red'); }

itemStats = ' '; $('#itemstats').html(itemStats); }

function popupChart(i) { var n,       data, options = {};

if (!$('#GEchartpopup').length) { return false; }   if ($('#overlay').length) { $('#overlay').toggle; } else { $('#GEchartpopup').before(' '); }   document.getElementById('overlay').onclick = popupChart; if (typeof i === 'number') { onkeydown = function (e) { if (e.which === 27) { popupChart(false); }       };    } else { onkeydown = function {}; }   $('#GEchartpopup').toggle; if (typeof i === 'number' && $('#GEpopupchart').attr('data-chartid') !== i) { $('#averagepopup').val(_GEC.average); addPopupPriceInfo(i); $('#GEpopupchart').attr('data-chartid', i); cloneObj(_GEC['chart' + i].options, options); options.chart.renderTo = 'GEpopupchart'; options.legend.enabled = true; options.title.text = 'Grand Exchange Market Watch'; options.title.style.fontSize = '18px'; options.subtitle.text = options.series[0].name; options.subtitle.style.fontSize = '15px;'; options.chart.zoomType = ''; options.rangeSelector.enabled = true; options.rangeSelector.inputBoxStyle.display = 'block'; options.plotOptions.series.enableMouseTracking = true; options.tooltip.enabled = true; options.navigator.enabled = true; options.credits.enabled = false; options.series = [{}]; data = getData(i, false); options.series = _GEC.addedData[i] ? [data[0][0]] : data[0]; options.yAxis = data[1]; _GEC.chartpopup = new Highcharts.StockChart(options); if (_GEC.addedData[i]) { for (n = 0; n < _GEC.addedData[i].length; n += 1) { _GEC.chartpopup.addSeries(_GEC.addedData[i][n]); }       }        setChartExtremes('popup'); _GEC.chartpopup.redraw; }   $('#GEPermLinkpopup').get(0).href = chartPermLinkUrl; }

Highcharts.setOptions({   lang: {        resetZoom: ' reset zoom ',        numericSymbols: ['K', 'M', 'B', 'T', 'Qd', 'Qt']    } });

_GEC.average = parseInt((location.hash.match(/#a=([^#]*)/) || [])[1], 10) || '';

$('div.GEdatachart').each(function (c) {

if (!$('#GEdataprices' + c).length) { return; }

var isSmall = $('#GEdatachart' + c).is('.smallChart'), isIndexChart = !!($('#GEdataprices' + c).attr('data-item') || '').match(/index/i), isInfobox = $('#GEdataprices' + c).is('.infobox *, .infobar *'), itemName, dataList = getData(c, isSmall), yAxis = dataList[1], zoom, enlarge, items, noAdd, hash;

// setting up the form and chart elements

if (!isSmall) { $('#GEdatachart' + c).before(' Average:  days ' + (isIndexChart ?  : ' Add more item(s):  Note: If you add more items, the averages will not be shown.') + ' Submit  ' + ((mw.config.get('wgNamespaceNumber') === 112 && mw.config.get('wgTitle').split('/')[1] === 'Data') || mw.config.get('wgPageName') === 'Grand_Exchange_Market_Watch/Chart' ? 'Permanent link</a>' : '') + '<div id="addedItems' + c + '"> '); }

/*GENERATING THE CHART - INITIAL LOAD*/ itemName = $('#GEdataprices' + c).attr('data-item');

dataList = dataList[0]; itemName = itemName || mw.config.get('wgPageName').replace(/_/g, ' ').split('/')[0].replace('Exchange:', '');

if (itemName.toLowerCase !== 'blank') { zoom = parseInt((location.hash.match(/#z=([^#]*)/) || [])[1], 10); zoom = zoom && zoom <= 6 && zoom >= 0 ? zoom - 1 : (zoom === 0 ? 0 : 2); }   enlarge = 'Enlarge Chart</a>';

//generating the chart _GEC['chart' + c] = new Highcharts.StockChart({       chart: {            renderTo: 'GEdatachart' + c,            backgroundColor: 'white',            plotBackgroundColor: 'white',            zoomType: isSmall ? 'x' : ,            events: {                redraw: function  {                    _GEC.thisid = this.renderTo.id.replace('GEdatachart', ).replace('GEpopupchart', 'popup');                    setTimeout(function  { setChartExtremes(_GEC.thisid); }, 0);               }            }        },        legend: {            enabled: !isSmall,            backgroundColor: 'white',            align: 'right',            layout: 'vertical',            verticalAlign: 'top',            y: 75        },        title: {            text: isSmall ? (isInfobox ? enlarge : itemName) : 'Grand Exchange Market Watch',           style: {                color: 'black',                fontSize: isSmall ? (enlarge ? '13px' : '15px') : '18px'           }        },        subtitle: {            text: isSmall ? (isInfobox ? null : enlarge) : (itemName.toLowerCase === 'blank' ? 'Historical chart' : itemName),           y: 35,            style: {                color: '#666',                fontSize: isSmall ? '13px' : '15px'            }        },        rangeSelector: {            enabled: !isSmall,            selected: zoom,            inputBoxStyle: {                right: '15px',                display: isSmall ? 'none' : 'block'            },            inputStyle: {                width: '100px'            },            inputDateFormat: "%e-%b-%Y",            buttonTheme: {                class: 'zoomButton' // @todo ask juey about this, class is a res. word -> className            },            buttons: [{                type: 'month',                count: 1,                text: '1m'            }, {                type: 'month',                count: 2,                text: '2m'            }, {                type: 'month',                count: 3,                text: '3m' }, {               type: 'month', count: 6, text: '6m' }, {               type: 'year', count: 1, text: '1y' }, {               type: 'all', text: 'All' }]       },        plotOptions: { series: { enableMouseTracking: !isSmall, dataGrouping: { dateTimeLabelFormats: { day: ['%A, %e %B %Y', '%A, %e %B', '-%A, %e %B %Y'], week: ['Week from %A, %e %B %Y', '%A, %e %B', '-%A, %e %B %Y'], month: ['%B %Y', '%B', '-%B %Y'], year: ['%Y', '%Y', '-%Y'] }               }            }        },        tooltip: { enabled: !isSmall, valueDecimals: isIndexChart ? 2 : 0,           headerFormat: ' {point.key}  ', xDateFormat: "%A, %e %B %Y" },       navigator: { xAxis: { dateTimeLabelFormats: { day: "%e-%b", week: "%e-%b", month: "%b-%Y", year: "%Y" },               minTickInterval: 24 * 3600 * 1000 // 1 day },           maskFill: 'none', enabled: !isSmall },       credits: { enabled: false },       xAxis: [{ lineColor: '#666', tickColor: '#666', dateTimeLabelFormats: { day: "%e-%b", week: "%e-%b", month: "%b-%Y", year: "%Y" },           minTickInterval: 24 * 3600 * 1000 // 1 day }],       yAxis: yAxis, series: dataList, colors: window.GEMWChartColors || [ '#4572A7', '#AA4643', '#89A54E', '#80699B', '#3D96AE', '#DB843D', '#92A8CD', '#A47D7C', '#B5CA92' ]   });

items = ($('#GEChartItems' + c).html || '').split(','); noAdd = [];

for (i = 0; i < items.length; i += 1) { if (!items[i].match(/^\s*$/)) { addItem(0, items[i]); } else { noAdd.push(1); }   }

if (items.length === noAdd.length && _GEC['chart' + c].series[0].name.toLowerCase !== 'blank') { setChartRange(c); }

/*END CODE GENERATING THE CHART - INITIAL LOAD*/

//adjusting the axes extremes (initial load) setChartExtremes(c);

//loading the chart and additional price info when the page is ready if (((mw.config.get('wgNamespaceNumber') === 112 && mw.config.get('wgTitle').split('/')[1] === 'Data') || mw.config.get('wgPageName') === 'Grand_Exchange_Market_Watch/Chart') && location.hash.match('#i=')) { hash = location.hash;

items = unescape((hash.match(/#i=([^#]*)/) || [])[1] || '').replace(/_/g, ' ').split(',');

for (i = 0; i < items.length; i += 1) { if (!items[i].match(/^\s*$/)) { addItem(0, items[i]); }       }    }

});//exit c