copyparty/copyparty/web/browser.js
2021-02-21 01:31:49 +00:00

969 lines
22 KiB
JavaScript

"use strict";
window.onerror = vis_exh;
function dbg(msg) {
ebi('path').innerHTML = msg;
}
function ev(e) {
e = e || window.event;
if (!e)
return;
if (e.preventDefault)
e.preventDefault()
if (e.stopPropagation)
e.stopPropagation();
e.returnValue = false;
return e;
}
makeSortable(ebi('files'));
// extract songs + add play column
function init_mp() {
var tracks = [];
var ret = {
'au': null,
'au_native': null,
'au_ogvjs': null,
'tracks': tracks,
'cover_url': ''
};
var re_audio = /\.(opus|ogg|m4a|aac|mp3|wav|flac)$/i;
var trs = ebi('files').getElementsByTagName('tbody')[0].getElementsByTagName('tr');
for (var a = 0, aa = trs.length; a < aa; a++) {
var tds = trs[a].getElementsByTagName('td');
var link = tds[1].getElementsByTagName('a');
link = link[link.length - 1];
var url = link.getAttribute('href');
var m = re_audio.exec(url);
if (m) {
var ntrack = tracks.length;
tracks.push(url);
tds[0].innerHTML = '<a id="trk' + ntrack + '" href="#trk' + ntrack + '" class="play">play</a></td>';
}
}
for (var a = 0, aa = tracks.length; a < aa; a++)
ebi('trk' + a).onclick = ev_play;
ret.vol = localStorage.getItem('vol');
if (ret.vol !== null)
ret.vol = parseFloat(ret.vol);
else
ret.vol = 0.5;
ret.expvol = function () {
return 0.5 * ret.vol + 0.5 * ret.vol * ret.vol;
};
ret.setvol = function (vol) {
ret.vol = Math.max(Math.min(vol, 1), 0);
localStorage.setItem('vol', vol);
if (ret.au)
ret.au.volume = ret.expvol();
};
return ret;
}
var mp = init_mp();
// toggle player widget
var widget = (function () {
var ret = {};
var widget = ebi('widget');
var wtoggle = ebi('wtoggle');
var touchmode = false;
var side_open = false;
var was_paused = true;
ret.open = function () {
if (side_open)
return false;
widget.className = 'open';
side_open = true;
return true;
};
ret.close = function () {
if (!side_open)
return false;
widget.className = '';
side_open = false;
return true;
};
ret.toggle = function (e) {
ret.open() || ret.close();
ev(e);
return false;
};
ret.paused = function (paused) {
if (was_paused != paused) {
was_paused = paused;
ebi('bplay').innerHTML = paused ? '▶' : '⏸';
}
};
var click_handler = function (e) {
if (!touchmode)
ret.toggle(e);
return false;
};
if (window.Touch) {
var touch_handler = function (e) {
touchmode = true;
return ret.toggle(e);
};
wtoggle.addEventListener('touchstart', touch_handler, false);
}
wtoggle.onclick = click_handler;
return ret;
})();
// buffer/position bar
var pbar = (function () {
var r = {};
r.bcan = ebi('barbuf');
r.pcan = ebi('barpos');
r.bctx = r.bcan.getContext('2d');
r.pctx = r.pcan.getContext('2d');
var bctx = r.bctx;
var pctx = r.pctx;
var scale = (window.devicePixelRatio || 1) / (
bctx.webkitBackingStorePixelRatio ||
bctx.mozBackingStorePixelRatio ||
bctx.msBackingStorePixelRatio ||
bctx.oBackingStorePixelRatio ||
bctx.BackingStorePixelRatio || 1);
var gradh = 0;
var grad = null;
r.drawbuf = function () {
var cs = getComputedStyle(r.bcan);
var sw = parseInt(cs['width']);
var sh = parseInt(cs['height']);
var sm = sw * 1.0 / mp.au.duration;
r.bcan.width = (sw * scale);
r.bcan.height = (sh * scale);
bctx.setTransform(scale, 0, 0, scale, 0, 0);
if (!grad || gradh != sh) {
grad = bctx.createLinearGradient(0, 0, 0, sh);
grad.addColorStop(0, 'hsl(85,35%,42%)');
grad.addColorStop(0.49, 'hsl(85,40%,49%)');
grad.addColorStop(0.50, 'hsl(85,37%,47%)');
grad.addColorStop(1, 'hsl(85,35%,42%)');
gradh = sh;
}
bctx.fillStyle = grad;
bctx.clearRect(0, 0, sw, sh);
for (var a = 0; a < mp.au.buffered.length; a++) {
var x1 = sm * mp.au.buffered.start(a);
var x2 = sm * mp.au.buffered.end(a);
bctx.fillRect(x1, 0, x2 - x1, sh);
}
};
r.drawpos = function () {
var cs = getComputedStyle(r.bcan);
var sw = parseInt(cs['width']);
var sh = parseInt(cs['height']);
var sm = sw * 1.0 / mp.au.duration;
r.pcan.width = (sw * scale);
r.pcan.height = (sh * scale);
pctx.setTransform(scale, 0, 0, scale, 0, 0);
pctx.clearRect(0, 0, sw, sh);
var w = 8;
var x = sm * mp.au.currentTime;
pctx.fillStyle = '#573'; pctx.fillRect((x - w / 2) - 1, 0, w + 2, sh);
pctx.fillStyle = '#dfc'; pctx.fillRect((x - w / 2), 0, 8, sh);
};
return r;
})();
// volume bar
var vbar = (function () {
var r = {};
r.can = ebi('pvol');
r.ctx = r.can.getContext('2d');
var bctx = r.ctx;
var scale = (window.devicePixelRatio || 1) / (
bctx.webkitBackingStorePixelRatio ||
bctx.mozBackingStorePixelRatio ||
bctx.msBackingStorePixelRatio ||
bctx.oBackingStorePixelRatio ||
bctx.BackingStorePixelRatio || 1);
var gradh = 0;
var grad1 = null;
var grad2 = null;
r.draw = function () {
var cs = getComputedStyle(r.can);
var sw = parseInt(cs['width']);
var sh = parseInt(cs['height']);
r.can.width = (sw * scale);
r.can.height = (sh * scale);
bctx.setTransform(scale, 0, 0, scale, 0, 0);
if (!grad1 || gradh != sh) {
gradh = sh;
grad1 = bctx.createLinearGradient(0, 0, 0, sh);
grad1.addColorStop(0, 'hsl(50,45%,42%)');
grad1.addColorStop(0.49, 'hsl(50,50%,49%)');
grad1.addColorStop(0.50, 'hsl(50,47%,47%)');
grad1.addColorStop(1, 'hsl(50,45%,42%)');
grad2 = bctx.createLinearGradient(0, 0, 0, sh);
grad2.addColorStop(0, 'hsl(205,10%,16%)');
grad2.addColorStop(0.49, 'hsl(205,15%,20%)');
grad2.addColorStop(0.50, 'hsl(205,13%,18%)');
grad2.addColorStop(1, 'hsl(205,10%,16%)');
}
bctx.fillStyle = grad2; bctx.fillRect(0, 0, sw, sh);
bctx.fillStyle = grad1; bctx.fillRect(0, 0, sw * mp.vol, sh);
};
var rect;
function mousedown(e) {
rect = r.can.getBoundingClientRect();
mousemove(e);
}
function mousemove(e) {
if (e.changedTouches && e.changedTouches.length > 0) {
e = e.changedTouches[0];
}
else if (e.buttons === 0) {
r.can.onmousemove = null;
return;
}
var x = e.clientX - rect.left;
var mul = x * 1.0 / rect.width;
if (mul > 0.98)
mul = 1;
mp.setvol(mul);
r.draw();
}
r.can.onmousedown = function (e) {
if (e.button !== 0)
return;
r.can.onmousemove = mousemove;
mousedown(e);
};
r.can.onmouseup = function (e) {
if (e.button === 0)
r.can.onmousemove = null;
};
if (window.Touch) {
r.can.ontouchstart = mousedown;
r.can.ontouchmove = mousemove;
}
r.draw();
return r;
})();
// hook up the widget buttons
(function () {
var bskip = function (n) {
var tid = null;
if (mp.au)
tid = mp.au.tid;
if (tid !== null)
play(tid + n);
else
play(0);
};
ebi('bplay').onclick = function (e) {
ev(e);
if (mp.au) {
if (mp.au.paused)
mp.au.play();
else
mp.au.pause();
}
else
play(0);
};
ebi('bprev').onclick = function (e) {
ev(e);
bskip(-1);
};
ebi('bnext').onclick = function (e) {
ev(e);
bskip(1);
};
ebi('barpos').onclick = function (e) {
if (!mp.au) {
//dbg((new Date()).getTime());
return play(0);
}
var rect = pbar.pcan.getBoundingClientRect();
var x = e.clientX - rect.left;
var mul = x * 1.0 / rect.width;
var seek = mp.au.duration * mul;
console.log('seek: ' + seek);
if (!isFinite(seek))
return;
mp.au.currentTime = seek;
if (mp.au === mp.au_native)
// hack: ogv.js breaks on .play() during playback
mp.au.play();
};
})();
// periodic tasks
(function () {
var nth = 0;
var last_skip_url = '';
var progress_updater = function () {
if (!mp.au) {
widget.paused(true);
}
else {
// indicate playback state in ui
widget.paused(mp.au.paused);
// draw current position in song
if (!mp.au.paused)
pbar.drawpos();
// occasionally draw buffered regions
if (++nth == 10) {
pbar.drawbuf();
nth = 0;
}
// switch to next track if approaching the end
if (last_skip_url != mp.au.src) {
var pos = mp.au.currentTime;
var len = mp.au.duration;
if (pos > 0 && pos > len - 0.1) {
last_skip_url = mp.au.src;
play(mp.au.tid + 1);
}
}
}
setTimeout(progress_updater, 100);
};
progress_updater();
})();
// event from play button next to a file in the list
function ev_play(e) {
ev(e);
play(parseInt(this.getAttribute('id').substr(3)));
return false;
}
function setclass(id, clas) {
ebi(id).setAttribute('class', clas);
}
var need_ogv = true;
try {
need_ogv = new Audio().canPlayType('audio/ogg; codecs=opus') !== 'probably';
if (/ Edge\//.exec(navigator.userAgent + ''))
need_ogv = true;
}
catch (ex) { }
// plays the tid'th audio file on the page
function play(tid, call_depth) {
if (mp.tracks.length == 0)
return alert('no audio found wait what');
while (tid >= mp.tracks.length)
tid -= mp.tracks.length;
while (tid < 0)
tid += mp.tracks.length;
if (mp.au) {
mp.au.pause();
setclass('trk' + mp.au.tid, 'play');
}
// ogv.js breaks on .play() unless directly user-triggered
var hack_attempt_play = true;
var url = mp.tracks[tid];
if (need_ogv && /\.(ogg|opus)$/i.test(url)) {
if (mp.au_ogvjs) {
mp.au = mp.au_ogvjs;
}
else if (window['OGVPlayer']) {
mp.au = mp.au_ogvjs = new OGVPlayer();
hack_attempt_play = false;
mp.au.addEventListener('error', evau_error, true);
mp.au.addEventListener('progress', pbar.drawpos, false);
widget.open();
}
else {
if (call_depth !== undefined)
return alert('failed to load ogv.js');
show_modal('<h1>loading ogv.js</h1><h2>thanks apple</h2>');
import_js('/.cpr/deps/ogv.js', function () {
play(tid, 1);
});
return;
}
}
else {
if (!mp.au_native) {
mp.au = mp.au_native = new Audio();
mp.au.addEventListener('error', evau_error, true);
mp.au.addEventListener('progress', pbar.drawpos, false);
widget.open();
}
mp.au = mp.au_native;
}
mp.au.tid = tid;
mp.au.src = url;
mp.au.volume = mp.expvol();
var oid = 'trk' + tid;
setclass(oid, 'play act');
try {
if (hack_attempt_play)
mp.au.play();
if (mp.au.paused)
autoplay_blocked();
var o = ebi(oid);
o.setAttribute('id', 'thx_js');
if (window.history && history.replaceState) {
var nurl = (document.location + '').split('#')[0] + '#' + oid;
history.replaceState(ebi('files').tBodies[0].innerHTML, nurl, nurl);
}
else {
document.location.hash = oid;
}
o.setAttribute('id', oid);
pbar.drawbuf();
return true;
}
catch (ex) {
alert('playback failed: ' + ex);
}
setclass('trk' + mp.au.tid, 'play');
setTimeout('play(' + (mp.au.tid + 1) + ');', 500);
}
// event from the audio object if something breaks
function evau_error(e) {
var err = '';
var eplaya = (e && e.target) || (window.event && window.event.srcElement);
switch (eplaya.error.code) {
case eplaya.error.MEDIA_ERR_ABORTED:
err = "You aborted the playback attempt (how tho)";
break;
case eplaya.error.MEDIA_ERR_NETWORK:
err = "Your internet connection is wonky";
break;
case eplaya.error.MEDIA_ERR_DECODE:
err = "This file is supposedly corrupted??";
break;
case eplaya.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
err = "Your browser does not understand this audio format";
break;
default:
err = 'Unknown Errol';
break;
}
if (eplaya.error.message)
err += '\n\n' + eplaya.error.message;
err += '\n\nFile: «' + decodeURIComponent(eplaya.src.split('/').slice(-1)[0]) + '»';
alert(err);
}
// show a fullscreen message
function show_modal(html) {
var body = document.body || document.getElementsByTagName('body')[0];
var div = document.createElement('div');
div.setAttribute('id', 'blocked');
div.innerHTML = html;
unblocked();
body.appendChild(div);
}
// hide fullscreen message
function unblocked() {
var dom = ebi('blocked');
if (dom)
dom.parentNode.removeChild(dom);
}
// show ui to manually start playback of a linked song
function autoplay_blocked() {
show_modal(
'<div id="blk_play"><a href="#" id="blk_go"></a></div>' +
'<div id="blk_abrt"><a href="#" id="blk_na">Cancel<br />(show file list)</a></div>');
var go = ebi('blk_go');
var na = ebi('blk_na');
var fn = mp.tracks[mp.au.tid].split(/\//).pop();
fn = decodeURIComponent(fn.replace(/\+/g, ' '));
go.textContent = 'Play "' + fn + '"';
go.onclick = function (e) {
if (e) e.preventDefault();
unblocked();
mp.au.play();
};
na.onclick = unblocked;
}
// autoplay linked track
(function () {
var v = location.hash;
if (v && v.length > 4 && v.indexOf('#trk') === 0)
play(parseInt(v.substr(4)));
})();
//widget.open();
// search
(function () {
var sconf = [
["size",
["szl", "sz_min", "minimum MiB", ""],
["szu", "sz_max", "maximum MiB", ""]
],
["date",
["dtl", "dt_min", "min. iso8601", ""],
["dtu", "dt_max", "max. iso8601", ""]
],
["path",
["pn", "path_no", "path NOT contains", "30"],
["py", "path_yes", "path contains", "30"]
],
["name",
["nn", "name_no", "name NOT contains", "30"],
["ny", "name_yes", "name contains", "30"]
]
];
var html = [];
for (var a = 0; a < sconf.length; a++) {
html.push('<tr><td><br />' + sconf[a][0] + '</td>');
for (var b = 1; b < 3; b++) {
var hn = "srch_" + sconf[a][b][0];
html.push(
'<td><input id="' + hn + 'c" type="checkbox">\n' +
'<label for="' + hn + 'c">' + sconf[a][b][2] + '</label>\n' +
'<br /><input id="' + hn + 'v" type="text" size="' + sconf[a][b][3] +
'" name="' + sconf[a][b][1] + '" /></td>');
}
html.push('</tr>');
}
ebi('srch_form').innerHTML = html.join('\n');
var o = document.querySelectorAll('#op_search input[type="text"]');
for (var a = 0; a < o.length; a++) {
o[a].oninput = ev_search_input;
}
var search_timeout;
function ev_search_input() {
var v = this.value;
var chk = ebi(this.getAttribute('id').slice(0, -1) + 'c');
chk.checked = ((v + '').length > 0);
clearTimeout(search_timeout);
search_timeout = setTimeout(do_search, 100);
}
function do_search() {
clearTimeout(search_timeout);
var params = {};
var o = document.querySelectorAll('#op_search input[type="text"]');
for (var a = 0; a < o.length; a++) {
var chk = ebi(o[a].getAttribute('id').slice(0, -1) + 'c');
if (!chk.checked)
continue;
params[o[a].getAttribute('name')] = o[a].value;
}
// ebi('srch_q').textContent = JSON.stringify(params, null, 4);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/?srch', true);
xhr.onreadystatechange = xhr_search_results;
xhr.ts = new Date().getTime();
xhr.send(JSON.stringify(params));
}
function xhr_search_results() {
if (this.readyState != XMLHttpRequest.DONE)
return;
if (this.status !== 200) {
alert('ah fug\n' + this.status + ": " + this.responseText);
return;
}
var ofiles = ebi('files');
if (ofiles.getAttribute('ts') > this.ts)
return;
ebi('path').style.display = 'none';
ebi('tree').style.display = 'none';
var html = [];
var res = JSON.parse(this.responseText);
for (var a = 0; a < res.length; a++) {
var r = res[a],
ts = parseInt(r.ts),
sz = esc(r.sz + ''),
rp = esc(r.rp + ''),
ext = rp.lastIndexOf('.') > 0 ? rp.split('.').slice(-1)[0] : '%',
links = linksplit(rp);
ts = new Date(ts * 1000).toISOString().replace("T", " ").slice(0, -5);
if (ext.length > 8)
ext = '%';
links = links.join('');
html.push('<tr><td>-</td><td><div>' + links + '</div></td><td>' + sz +
'</td><td>' + ext + '</td><td>' + ts + '</td></tr>');
}
ofiles.tBodies[0].innerHTML = html.join('\n');
ofiles.setAttribute("ts", this.ts);
reload_browser();
}
})();
// tree
(function () {
var treedata = null;
function entree(e) {
ev(e);
ebi('path').style.display = 'none';
var treetab = ebi('treetab');
var treefiles = ebi('treefiles');
treetab.style.display = 'table';
var pro = ebi('pro');
if (pro)
treefiles.appendChild(pro);
treefiles.appendChild(ebi('files'));
var epi = ebi('epi');
if (epi)
treefiles.appendChild(epi);
localStorage.setItem('entreed', 'tree');
get_tree("", get_vpath());
}
function get_tree(top, dst) {
var xhr = new XMLHttpRequest();
xhr.top = top;
xhr.dst = dst;
xhr.open('GET', dst + '?tree=' + top, true);
xhr.onreadystatechange = recvtree;
xhr.send();
}
function recvtree() {
if (this.readyState != XMLHttpRequest.DONE)
return;
if (this.status !== 200) {
alert('ah fug\n' + this.status + ": " + this.responseText);
return;
}
var top = this.top == '.' ? this.dst : this.top,
name = top.split('/').slice(-2)[0],
rtop = top.replace(/^\/+/, "");
try {
var res = JSON.parse(this.responseText);
}
catch (ex) {
return;
}
var html = parsetree(res, rtop);
if (!this.top) {
html = '<li><a href="#">-</a><a href="/">[root]</a>\n<ul>' + html;
if (!ebi('treeul').getElementsByTagName('li').length)
ebi('treeul').innerHTML = html + '</ul></li>';
}
else {
html = '<a href="#">-</a><a href="' +
esc(top) + '">' + esc(name) + "</a>" + html;
var links = document.querySelectorAll('#tree a+a');
for (var a = 0, aa = links.length; a < aa; a++) {
if (links[a].getAttribute('href') == top) {
var o = links[a].parentNode;
if (!o.getElementsByTagName('li').length)
o.innerHTML = html;
//else
// links[a].previousSibling.textContent = '-';
}
}
}
document.querySelector('#treeul>li>a+a').textContent = '[root]';
reload_tree();
var q = '#tree';
var nq = 0;
while (true) {
nq++;
q += '>ul>li';
if (!document.querySelector(q))
break;
}
ebi('treeul').style.width = (24 + nq) + 'em';
}
function reload_tree() {
var cdir = get_vpath();
var links = document.querySelectorAll('#tree a+a');
for (var a = 0, aa = links.length; a < aa; a++) {
var href = links[a].getAttribute('href');
links[a].setAttribute('class', href == cdir ? 'hl' : '');
links[a].onclick = treego;
}
links = document.querySelectorAll('#tree li>a:first-child');
for (var a = 0, aa = links.length; a < aa; a++) {
links[a].setAttribute('dst', links[a].nextSibling.getAttribute('href'));
links[a].onclick = treegrow;
}
}
function treego(e) {
ev(e);
if (this.getAttribute('class') == 'hl') {
treegrow.call(this.previousSibling, e);
return;
}
var xhr = new XMLHttpRequest();
xhr.top = this.getAttribute('href');
xhr.open('GET', xhr.top + '?ls', true);
xhr.onreadystatechange = recvls;
xhr.send();
get_tree('.', xhr.top);
}
function treegrow(e) {
ev(e);
if (this.textContent == '-') {
while (this.nextSibling.nextSibling) {
var rm = this.nextSibling.nextSibling;
rm.parentNode.removeChild(rm);
this.textContent = '+';
}
return;
}
var dst = this.getAttribute('dst');
get_tree('.', dst);
}
function recvls() {
if (this.readyState != XMLHttpRequest.DONE)
return;
if (this.status !== 200) {
alert('ah fug\n' + this.status + ": " + this.responseText);
return;
}
try {
var res = JSON.parse(this.responseText);
}
catch (ex) {
window.location = this.top;
return;
}
ebi('srv_info').innerHTML = res.srvinf;
var nodes = res.dirs.concat(res.files);
var top = this.top;
var html = [];
for (var a = 0; a < nodes.length; a++) {
var r = nodes[a],
ln = '<tr><td>' + r.lead + '</td><td><a href="' +
top + r.href + '">' + esc(decodeURIComponent(r.href)) + '</a>';
ln = [ln, r.sz, r.ext, r.dt].join('</td><td>');
html.push(ln + '</td></tr>');
}
html = html.join('\n');
ebi('files').tBodies[0].innerHTML = html;
history.pushState(html, this.top, this.top);
var o = ebi('pro');
if (o) o.parentNode.removeChild(o);
o = ebi('epi');
if (o) o.parentNode.removeChild(o);
reload_tree();
reload_browser();
}
function parsetree(res, top) {
var ret = '';
for (var a = 0; a < res.a.length; a++) {
if (res.a[a] !== '')
res['k' + res.a[a]] = 0;
}
delete res['a'];
var keys = Object.keys(res);
keys.sort();
for (var a = 0; a < keys.length; a++) {
var kk = keys[a],
k = kk.slice(1),
url = '/' + (top ? top + k : k) + '/',
ek = esc(k),
sym = res[kk] ? '-' : '+',
link = '<a href="#">' + sym + '</a><a href="' +
esc(url) + '">' + ek + '</a>';
if (res[kk]) {
var subtree = parsetree(res[kk], url.slice(1));
ret += '<li>' + link + '\n<ul>\n' + subtree + '</ul></li>\n';
}
else {
ret += '<li>' + link + '</li>\n';
}
}
return ret;
}
function detree(e) {
ev(e);
var treetab = ebi('treetab');
var pro = ebi('pro');
if (pro)
treetab.parentNode.insertBefore(pro, treetab);
treetab.parentNode.insertBefore(ebi('files'), treetab.nextSibling);
var epi = ebi('epi');
if (epi)
treetab.parentNode.insertBefore(epi, ebi('files').nextSibling);
ebi('path').style.display = 'inline-block';
treetab.style.display = 'none';
localStorage.setItem('entreed', 'na');
}
ebi('entree').onclick = entree;
ebi('detree').onclick = detree;
if (window.localStorage && localStorage.getItem('entreed') == 'tree')
entree();
window.onpopstate = function (e) {
console.log(e.url + ' ,, ' + ((e.state + '').slice(0, 64)));
if (e.state) {
ebi('files').tBodies[0].innerHTML = e.state;
reload_tree();
reload_browser();
}
};
if (window.history && history.pushState) {
var u = get_vpath();
history.replaceState(ebi('files').tBodies[0].innerHTML, u, u);
}
})();
function reload_browser(not_mp) {
makeSortable(ebi('files'));
var parts = get_vpath().split('/');
var rm = document.querySelectorAll('#path>a+a+a');
for (a = rm.length - 1; a >= 0; a--)
rm[a].parentNode.removeChild(rm[a]);
var link = '/';
for (var a = 1; a < parts.length - 1; a++) {
link += parts[a] + '/';
var o = document.createElement('a');
o.setAttribute('href', link);
o.innerHTML = parts[a];
ebi('path').appendChild(o);
}
var oo = document.querySelectorAll('#files>tbody>tr>td:nth-child(3)');
for (var a = 0, aa = oo.length; a < aa; a++) {
var sz = oo[a].textContent.replace(/ /g, ""),
hsz = sz.replace(/\B(?=(\d{3})+(?!\d))/g, " ");
oo[a].textContent = hsz;
}
if (!not_mp) {
if (mp && mp.au) {
mp.au.pause();
mp.au = null;
}
widget.close();
mp = init_mp();
}
}
reload_browser(true);