Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,957 @@
;;(function(window,undefined){'use strict';function L10nError(message,id,loc){this.name='L10nError';this.message=message;this.id=id;this.loc=loc;}
L10nError.prototype=Object.create(Error.prototype);L10nError.prototype.constructor=L10nError;var io={_load:function(type,url,callback,sync){var xhr=new XMLHttpRequest();var needParse;if(xhr.overrideMimeType){xhr.overrideMimeType(type);}
xhr.open('GET',url,!sync);if(type==='application/json'){if(sync){needParse=true;}else{xhr.responseType='json';}}
xhr.addEventListener('load',function io_onload(e){if(e.target.status===200||e.target.status===0){var res=e.target.response||e.target.responseText;callback(null,needParse?JSON.parse(res):res);}else{callback(new L10nError('Not found: '+url));}});xhr.addEventListener('error',callback);xhr.addEventListener('timeout',callback);try{xhr.send(null);}catch(e){if(e.name==='NS_ERROR_FILE_NOT_FOUND'){callback(new L10nError('Not found: '+url));}else{throw e;}}},load:function(url,callback,sync){return io._load('text/plain',url,callback,sync);},loadJSON:function(url,callback,sync){return io._load('application/json',url,callback,sync);}};function EventEmitter(){}
EventEmitter.prototype.emit=function ee_emit(){if(!this._listeners){return;}
var args=Array.prototype.slice.call(arguments);var type=args.shift();if(!this._listeners[type]){return;}
var typeListeners=this._listeners[type].slice();for(var i=0;i<typeListeners.length;i++){typeListeners[i].apply(this,args);}};EventEmitter.prototype.addEventListener=function ee_add(type,listener){if(!this._listeners){this._listeners={};}
if(!(type in this._listeners)){this._listeners[type]=[];}
this._listeners[type].push(listener);};EventEmitter.prototype.removeEventListener=function ee_rm(type,listener){if(!this._listeners){return;}
var typeListeners=this._listeners[type];var pos=typeListeners.indexOf(listener);if(pos===-1){return;}
typeListeners.splice(pos,1);};function getPluralRule(lang){var locales2rules={'af':3,'ak':4,'am':4,'ar':1,'asa':3,'az':0,'be':11,'bem':3,'bez':3,'bg':3,'bh':4,'bm':0,'bn':3,'bo':0,'br':20,'brx':3,'bs':11,'ca':3,'cgg':3,'chr':3,'cs':12,'cy':17,'da':3,'de':3,'dv':3,'dz':0,'ee':3,'el':3,'en':3,'eo':3,'es':3,'et':3,'eu':3,'fa':0,'ff':5,'fi':3,'fil':4,'fo':3,'fr':5,'fur':3,'fy':3,'ga':8,'gd':24,'gl':3,'gsw':3,'gu':3,'guw':4,'gv':23,'ha':3,'haw':3,'he':2,'hi':4,'hr':11,'hu':0,'id':0,'ig':0,'ii':0,'is':3,'it':3,'iu':7,'ja':0,'jmc':3,'jv':0,'ka':0,'kab':5,'kaj':3,'kcg':3,'kde':0,'kea':0,'kk':3,'kl':3,'km':0,'kn':0,'ko':0,'ksb':3,'ksh':21,'ku':3,'kw':7,'lag':18,'lb':3,'lg':3,'ln':4,'lo':0,'lt':10,'lv':6,'mas':3,'mg':4,'mk':16,'ml':3,'mn':3,'mo':9,'mr':3,'ms':0,'mt':15,'my':0,'nah':3,'naq':7,'nb':3,'nd':3,'ne':3,'nl':3,'nn':3,'no':3,'nr':3,'nso':4,'ny':3,'nyn':3,'om':3,'or':3,'pa':3,'pap':3,'pl':13,'ps':3,'pt':3,'rm':3,'ro':9,'rof':3,'ru':11,'rwk':3,'sah':0,'saq':3,'se':7,'seh':3,'ses':0,'sg':0,'sh':11,'shi':19,'sk':12,'sl':14,'sma':7,'smi':7,'smj':7,'smn':7,'sms':7,'sn':3,'so':3,'sq':3,'sr':11,'ss':3,'ssy':3,'st':3,'sv':3,'sw':3,'syr':3,'ta':3,'te':3,'teo':3,'th':0,'ti':4,'tig':3,'tk':3,'tl':4,'tn':3,'to':0,'tr':0,'ts':3,'tzm':22,'uk':11,'ur':3,'ve':3,'vi':0,'vun':3,'wa':4,'wae':3,'wo':0,'xh':3,'xog':3,'yo':0,'zh':0,'zu':3};function isIn(n,list){return list.indexOf(n)!==-1;}
function isBetween(n,start,end){return typeof n===typeof start&&start<=n&&n<=end;}
var pluralRules={'0':function(){return'other';},'1':function(n){if((isBetween((n%100),3,10))){return'few';}
if(n===0){return'zero';}
if((isBetween((n%100),11,99))){return'many';}
if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'2':function(n){if(n!==0&&(n%10)===0){return'many';}
if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'3':function(n){if(n===1){return'one';}
return'other';},'4':function(n){if((isBetween(n,0,1))){return'one';}
return'other';},'5':function(n){if((isBetween(n,0,2))&&n!==2){return'one';}
return'other';},'6':function(n){if(n===0){return'zero';}
if((n%10)===1&&(n%100)!==11){return'one';}
return'other';},'7':function(n){if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'8':function(n){if((isBetween(n,3,6))){return'few';}
if((isBetween(n,7,10))){return'many';}
if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'9':function(n){if(n===0||n!==1&&(isBetween((n%100),1,19))){return'few';}
if(n===1){return'one';}
return'other';},'10':function(n){if((isBetween((n%10),2,9))&&!(isBetween((n%100),11,19))){return'few';}
if((n%10)===1&&!(isBetween((n%100),11,19))){return'one';}
return'other';},'11':function(n){if((isBetween((n%10),2,4))&&!(isBetween((n%100),12,14))){return'few';}
if((n%10)===0||(isBetween((n%10),5,9))||(isBetween((n%100),11,14))){return'many';}
if((n%10)===1&&(n%100)!==11){return'one';}
return'other';},'12':function(n){if((isBetween(n,2,4))){return'few';}
if(n===1){return'one';}
return'other';},'13':function(n){if((isBetween((n%10),2,4))&&!(isBetween((n%100),12,14))){return'few';}
if(n!==1&&(isBetween((n%10),0,1))||(isBetween((n%10),5,9))||(isBetween((n%100),12,14))){return'many';}
if(n===1){return'one';}
return'other';},'14':function(n){if((isBetween((n%100),3,4))){return'few';}
if((n%100)===2){return'two';}
if((n%100)===1){return'one';}
return'other';},'15':function(n){if(n===0||(isBetween((n%100),2,10))){return'few';}
if((isBetween((n%100),11,19))){return'many';}
if(n===1){return'one';}
return'other';},'16':function(n){if((n%10)===1&&n!==11){return'one';}
return'other';},'17':function(n){if(n===3){return'few';}
if(n===0){return'zero';}
if(n===6){return'many';}
if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'18':function(n){if(n===0){return'zero';}
if((isBetween(n,0,2))&&n!==0&&n!==2){return'one';}
return'other';},'19':function(n){if((isBetween(n,2,10))){return'few';}
if((isBetween(n,0,1))){return'one';}
return'other';},'20':function(n){if((isBetween((n%10),3,4)||((n%10)===9))&&!(isBetween((n%100),10,19)||isBetween((n%100),70,79)||isBetween((n%100),90,99))){return'few';}
if((n%1000000)===0&&n!==0){return'many';}
if((n%10)===2&&!isIn((n%100),[12,72,92])){return'two';}
if((n%10)===1&&!isIn((n%100),[11,71,91])){return'one';}
return'other';},'21':function(n){if(n===0){return'zero';}
if(n===1){return'one';}
return'other';},'22':function(n){if((isBetween(n,0,1))||(isBetween(n,11,99))){return'one';}
return'other';},'23':function(n){if((isBetween((n%10),1,2))||(n%20)===0){return'one';}
return'other';},'24':function(n){if((isBetween(n,3,10)||isBetween(n,13,19))){return'few';}
if(isIn(n,[2,12])){return'two';}
if(isIn(n,[1,11])){return'one';}
return'other';}};var index=locales2rules[lang.replace(/-.*$/,'')];if(!(index in pluralRules)){return function(){return'other';};}
return pluralRules[index];}
var MAX_PLACEABLES=100;var PropertiesParser={patterns:null,entryIds:null,init:function(){this.patterns={comment:/^\s*#|^\s*$/,entity:/^([^=\s]+)\s*=\s*(.*)$/,multiline:/[^\\]\\$/,index:/\{\[\s*(\w+)(?:\(([^\)]*)\))?\s*\]\}/i,unicode:/\\u([0-9a-fA-F]{1,4})/g,entries:/[^\r\n]+/g,controlChars:/\\([\\\n\r\t\b\f\{\}\"\'])/g,placeables:/\{\{\s*([^\s]*?)\s*\}\}/,};},parse:function(ctx,source){if(!this.patterns){this.init();}
var ast=[];this.entryIds=Object.create(null);var entries=source.match(this.patterns.entries);if(!entries){return ast;}
for(var i=0;i<entries.length;i++){var line=entries[i];if(this.patterns.comment.test(line)){continue;}
while(this.patterns.multiline.test(line)&&i<entries.length){line=line.slice(0,-1)+entries[++i].trim();}
var entityMatch=line.match(this.patterns.entity);if(entityMatch){try{this.parseEntity(entityMatch[1],entityMatch[2],ast);}catch(e){if(ctx){ctx._emitter.emit('parseerror',e);}else{throw e;}}}}
return ast;},parseEntity:function(id,value,ast){var name,key;var pos=id.indexOf('[');if(pos!==-1){name=id.substr(0,pos);key=id.substring(pos+1,id.length-1);}else{name=id;key=null;}
var nameElements=name.split('.');if(nameElements.length>2){throw new L10nError('Error in ID: "'+name+'".'+' Nested attributes are not supported.');}
var attr;if(nameElements.length>1){name=nameElements[0];attr=nameElements[1];if(attr[0]==='$'){throw new L10nError('Attribute can\'t start with "$"',id);}}else{attr=null;}
this.setEntityValue(name,attr,key,this.unescapeString(value),ast);},setEntityValue:function(id,attr,key,rawValue,ast){var pos,v;var value=rawValue.indexOf('{{')>-1?this.parseString(rawValue):rawValue;if(attr){pos=this.entryIds[id];if(pos===undefined){v={$i:id};if(key){v[attr]={};v[attr][key]=value;}else{v[attr]=value;}
ast.push(v);this.entryIds[id]=ast.length-1;return;}
if(key){if(typeof(ast[pos][attr])==='string'){ast[pos][attr]={$x:this.parseIndex(ast[pos][attr]),$v:{}};}
ast[pos][attr].$v[key]=value;return;}
ast[pos][attr]=value;return;}
if(key){pos=this.entryIds[id];if(pos===undefined){v={};v[key]=value;ast.push({$i:id,$v:v});this.entryIds[id]=ast.length-1;return;}
if(typeof(ast[pos].$v)==='string'){ast[pos].$x=this.parseIndex(ast[pos].$v);ast[pos].$v={};}
ast[pos].$v[key]=value;return;}
ast.push({$i:id,$v:value});this.entryIds[id]=ast.length-1;},parseString:function(str){var chunks=str.split(this.patterns.placeables);var complexStr=[];var len=chunks.length;var placeablesCount=(len-1)/2;if(placeablesCount>=MAX_PLACEABLES){throw new L10nError('Too many placeables ('+placeablesCount+', max allowed is '+MAX_PLACEABLES+')');}
for(var i=0;i<chunks.length;i++){if(chunks[i].length===0){continue;}
if(i%2===1){complexStr.push({t:'idOrVar',v:chunks[i]});}else{complexStr.push(chunks[i]);}}
return complexStr;},unescapeString:function(str){if(str.lastIndexOf('\\')!==-1){str=str.replace(this.patterns.controlChars,'$1');}
return str.replace(this.patterns.unicode,function(match,token){return unescape('%u'+'0000'.slice(token.length)+token);});},parseIndex:function(str){var match=str.match(this.patterns.index);if(!match){throw new L10nError('Malformed index');}
if(match[2]){return[{t:'idOrVar',v:match[1]},match[2]];}else{return[{t:'idOrVar',v:match[1]}];}}};var KNOWN_MACROS=['plural'];var MAX_PLACEABLE_LENGTH=2500;var rePlaceables=/\{\{\s*(.+?)\s*\}\}/g;var nonLatin1=/[^\x01-\xFF]/;var FSI='\u2068';var PDI='\u2069';function createEntry(node,env){var keys=Object.keys(node);if(typeof node.$v==='string'&&keys.length===2){return node.$v;}
var attrs;for(var i=0,key;key=keys[i];i++){if(key[0]==='$'){continue;}
if(!attrs){attrs=Object.create(null);}
attrs[key]=createAttribute(node[key],env,node.$i+'.'+key);}
return{id:node.$i,value:node.$v!==undefined?node.$v:null,index:node.$x||null,attrs:attrs||null,env:env,dirty:false};}
function createAttribute(node,env,id){if(typeof node==='string'){return node;}
return{id:id,value:node.$v||(node!==undefined?node:null),index:node.$x||null,env:env,dirty:false};}
function format(args,entity){if(typeof entity==='string'){return[{},entity];}
if(entity.dirty){throw new L10nError('Cyclic reference detected: '+entity.id);}
entity.dirty=true;var rv;try{rv=resolveValue({},args,entity.env,entity.value,entity.index);}finally{entity.dirty=false;}
return rv;}
function resolveIdentifier(args,env,id){if(KNOWN_MACROS.indexOf(id)>-1){return[{},env['__'+id]];}
if(args&&args.hasOwnProperty(id)){if(typeof args[id]==='string'||(typeof args[id]==='number'&&!isNaN(args[id]))){return[{},args[id]];}else{throw new L10nError('Arg must be a string or a number: '+id);}}
if(id in env&&id!=='__proto__'){return format(args,env[id]);}
throw new L10nError('Unknown reference: '+id);}
function subPlaceable(locals,args,env,id){var res;try{res=resolveIdentifier(args,env,id);}catch(err){return[{error:err},'{{ '+id+' }}'];}
var value=res[1];if(typeof value==='number'){return res;}
if(typeof value==='string'){if(value.length>=MAX_PLACEABLE_LENGTH){throw new L10nError('Too many characters in placeable ('+
value.length+', max allowed is '+
MAX_PLACEABLE_LENGTH+')');}
if(locals.contextIsNonLatin1||value.match(nonLatin1)){res[1]=FSI+value+PDI;}
return res;}
return[{},'{{ '+id+' }}'];}
function interpolate(locals,args,env,arr){return arr.reduce(function(prev,cur){if(typeof cur==='string'){return[prev[0],prev[1]+cur];}else if(cur.t==='idOrVar'){var placeable=subPlaceable(locals,args,env,cur.v);return[prev[0],prev[1]+placeable[1]];}},[locals,'']);}
function resolveSelector(args,env,expr,index){var selectorName=index[0].v;var selector=resolveIdentifier(args,env,selectorName)[1];if(typeof selector!=='function'){return selector;}
var argValue=index[1]?resolveIdentifier(args,env,index[1])[1]:undefined;if(selector===env.__plural){if(argValue===0&&'zero'in expr){return'zero';}
if(argValue===1&&'one'in expr){return'one';}
if(argValue===2&&'two'in expr){return'two';}}
return selector(argValue);}
function resolveValue(locals,args,env,expr,index){if(!expr){return[locals,expr];}
if(typeof expr==='string'||typeof expr==='boolean'||typeof expr==='number'){return[locals,expr];}
if(Array.isArray(expr)){locals.contextIsNonLatin1=expr.some(function($_){return typeof($_)==='string'&&$_.match(nonLatin1);});return interpolate(locals,args,env,expr);}
if(index){var selector=resolveSelector(args,env,expr,index);if(expr.hasOwnProperty(selector)){return resolveValue(locals,args,env,expr[selector]);}}
if('other'in expr){return resolveValue(locals,args,env,expr.other);}
throw new L10nError('Unresolvable value');}
var Resolver={createEntry:createEntry,format:format,rePlaceables:rePlaceables};function walkContent(node,fn){if(typeof node==='string'){return fn(node);}
if(node.t==='idOrVar'){return node;}
var rv=Array.isArray(node)?[]:{};var keys=Object.keys(node);for(var i=0,key;(key=keys[i]);i++){if(key==='$i'||key==='$x'){rv[key]=node[key];}else{rv[key]=walkContent(node[key],fn);}}
return rv;}
var reAlphas=/[a-zA-Z]/g;var reVowels=/[aeiouAEIOU]/g;var ACCENTED_MAP='\u0226\u0181\u0187\u1E12\u1E16\u0191\u0193\u0126\u012A'+'\u0134\u0136\u013F\u1E3E\u0220\u01FE\u01A4\u024A\u0158'+'\u015E\u0166\u016C\u1E7C\u1E86\u1E8A\u1E8E\u1E90'+'[\\]^_`'+'\u0227\u0180\u0188\u1E13\u1E17\u0192\u0260\u0127\u012B'+'\u0135\u0137\u0140\u1E3F\u019E\u01FF\u01A5\u024B\u0159'+'\u015F\u0167\u016D\u1E7D\u1E87\u1E8B\u1E8F\u1E91';var FLIPPED_MAP='\u2200\u0510\u2183p\u018E\u025F\u05E4HI\u017F'+'\u04FC\u02E5WNO\u0500\xD2\u1D1AS\u22A5\u2229\u0245'+'\uFF2DX\u028EZ'+'[\\]\u1D65_,'+'\u0250q\u0254p\u01DD\u025F\u0183\u0265\u0131\u027E'+'\u029E\u0285\u026Fuodb\u0279s\u0287n\u028C\u028Dx\u028Ez';function makeLonger(val){return val.replace(reVowels,function(match){return match+match.toLowerCase();});}
function replaceChars(map,val){return val.replace(reAlphas,function(match){return map.charAt(match.charCodeAt(0)-65);});}
var reWords=/[^\W0-9_]+/g;function makeRTL(val){return val.replace(reWords,function(match){return'\u202e'+match+'\u202c';});}
var reExcluded=/(%[EO]?\w|\{\s*.+?\s*\}|&[#\w]+;|<\s*.+?\s*>)/;function mapContent(fn,val){if(!val){return val;}
var parts=val.split(reExcluded);var modified=parts.map(function(part){if(reExcluded.test(part)){return part;}
return fn(part);});return modified.join('');}
function Pseudo(id,name,charMap,modFn){this.id=id;this.translate=mapContent.bind(null,function(val){return replaceChars(charMap,modFn(val));});this.name=this.translate(name);}
var PSEUDO={'fr-x-psaccent':new Pseudo('fr-x-psaccent','Runtime Accented',ACCENTED_MAP,makeLonger),'ar-x-psbidi':new Pseudo('ar-x-psbidi','Runtime Bidi',FLIPPED_MAP,makeRTL)};function Locale(id,ctx){this.id=id;this.ctx=ctx;this.isReady=false;this.entries=Object.create(null);this.entries.__plural=getPluralRule(this.isPseudo()?this.ctx.defaultLocale:id);}
Locale.prototype.isPseudo=function(){return this.ctx.qps.indexOf(this.id)!==-1;};var bindingsIO={extra:function(id,ver,path,type,callback,errback){if(type==='properties'){type='text';}
navigator.mozApps.getLocalizationResource(id,ver,path,type).then(callback.bind(null,null),errback);},app:function(id,ver,path,type,callback,errback,sync){switch(type){case'properties':io.load(path,callback,sync);break;case'json':io.loadJSON(path,callback,sync);break;}},};Locale.prototype.build=function L_build(callback){var sync=!callback;var ctx=this.ctx;var self=this;var l10nLoads=ctx.resLinks.length;function onL10nLoaded(err){if(err){ctx._emitter.emit('fetcherror',err);}
if(--l10nLoads<=0){self.isReady=true;if(callback){callback();}}}
if(l10nLoads===0){onL10nLoaded();return;}
function onJSONLoaded(err,json){if(!err&&json){self.addAST(json);}
onL10nLoaded(err);}
function onPropLoaded(err,source){if(!err&&source){var ast=PropertiesParser.parse(ctx,source);self.addAST(ast);}
onL10nLoaded(err);}
var idToFetch=this.isPseudo()?ctx.defaultLocale:this.id;var appVersion=null;var source='app';if(typeof(navigator)!=='undefined'){source=navigator.mozL10n._config.localeSources[this.id]||'app';appVersion=navigator.mozL10n._config.appVersion;}
for(var i=0;i<ctx.resLinks.length;i++){var resLink=decodeURI(ctx.resLinks[i]);var path=resLink.replace('{locale}',idToFetch);var type=path.substr(path.lastIndexOf('.')+1);var cb;switch(type){case'json':cb=onJSONLoaded;break;case'properties':cb=onPropLoaded;break;}
bindingsIO[source](this.id,appVersion,path,type,cb,onL10nLoaded,sync);}};function createPseudoEntry(node,entries){return Resolver.createEntry(walkContent(node,PSEUDO[this.id].translate),entries);}
Locale.prototype.addAST=function(ast){var createEntry=this.isPseudo()?createPseudoEntry.bind(this):Resolver.createEntry;for(var i=0;i<ast.length;i++){this.entries[ast[i].$i]=createEntry(ast[i],this.entries);}};function Context(id){this.id=id;this.isReady=false;this.isLoading=false;this.defaultLocale='en-US';this.availableLocales=[];this.supportedLocales=[];this.qps=[];this.resLinks=[];this.locales={};this._emitter=new EventEmitter();this._ready=new Promise(this.once.bind(this));}
function reportMissing(id,err){this._emitter.emit('notfounderror',err);return id;}
function getWithFallback(id){var cur=0;var loc;var locale;while(loc=this.supportedLocales[cur]){locale=this.getLocale(loc);if(!locale.isReady){locale.build(null);}
var entry=locale.entries[id];if(entry===undefined){cur++;reportMissing.call(this,id,new L10nError('"'+id+'"'+' not found in '+loc+' in '+this.id,id,loc));continue;}
return entry;}
throw new L10nError('"'+id+'"'+' missing from all supported locales in '+this.id,id);}
function formatTuple(args,entity){try{return Resolver.format(args,entity);}catch(err){this._emitter.emit('resolveerror',err);var locals={error:err};return[locals,entity.id];}}
function formatValue(args,entity){if(typeof entity==='string'){return entity;}
return formatTuple.call(this,args,entity)[1];}
function formatEntity(args,entity){var entityTuple=formatTuple.call(this,args,entity);var value=entityTuple[1];var formatted={value:value,attrs:null,};if(entity.attrs){formatted.attrs=Object.create(null);}
for(var key in entity.attrs){var attrTuple=formatTuple.call(this,args,entity.attrs[key]);formatted.attrs[key]=attrTuple[1];}
return formatted;}
function formatAsync(fn,id,args){return this._ready.then(getWithFallback.bind(this,id)).then(fn.bind(this,args),reportMissing.bind(this,id));}
Context.prototype.formatValue=function(id,args){return formatAsync.call(this,formatValue,id,args);};Context.prototype.formatEntity=function(id,args){return formatAsync.call(this,formatEntity,id,args);};function legacyGet(fn,id,args){if(!this.isReady){throw new L10nError('Context not ready');}
var entry;try{entry=getWithFallback.call(this,id);}catch(err){if(err.loc){throw err;}
reportMissing.call(this,id,err);return'';}
return fn.call(this,args,entry);}
Context.prototype.get=function(id,args){return legacyGet.call(this,formatValue,id,args);};Context.prototype.getEntity=function(id,args){return legacyGet.call(this,formatEntity,id,args);};Context.prototype.getLocale=function getLocale(code){var locales=this.locales;if(locales[code]){return locales[code];}
return locales[code]=new Locale(code,this);};function negotiate(available,requested,defaultLocale){var supportedLocale;for(var i=0;i<requested.length;i++){var locale=requested[i];if(available.indexOf(locale)!==-1){supportedLocale=locale;break;}}
if(!supportedLocale||supportedLocale===defaultLocale){return[defaultLocale];}
return[supportedLocale,defaultLocale];}
function freeze(supported){var locale=this.getLocale(supported[0]);if(locale.isReady){setReady.call(this,supported);}else{locale.build(setReady.bind(this,supported));}}
function setReady(supported){this.supportedLocales=supported;this.isReady=true;this._emitter.emit('ready');}
Context.prototype.registerLocales=function(defLocale,available){if(defLocale){this.defaultLocale=defLocale;}
this.availableLocales=[this.defaultLocale];this.qps=Object.keys(PSEUDO);if(available){for(var i=0,loc;loc=available[i];i++){if(this.availableLocales.indexOf(loc)===-1){this.availableLocales.push(loc);var pos=this.qps.indexOf(loc);if(pos!==-1){this.qps.splice(pos,1);}}}}};Context.prototype.requestLocales=function requestLocales(){if(this.isLoading&&!this.isReady){throw new L10nError('Context not ready');}
this.isLoading=true;var requested=Array.prototype.slice.call(arguments);if(requested.length===0){throw new L10nError('No locales requested');}
var supported=negotiate(this.availableLocales.concat(this.qps),requested,this.defaultLocale);if(this.supportedLocales[0]!==supported[0]){freeze.call(this,supported);}};Context.prototype.addEventListener=function(type,listener){this._emitter.addEventListener(type,listener);};Context.prototype.removeEventListener=function(type,listener){this._emitter.removeEventListener(type,listener);};Context.prototype.ready=function(callback){if(this.isReady){setTimeout(callback);}
this.addEventListener('ready',callback);};Context.prototype.once=function(callback){if(this.isReady){setTimeout(callback);return;}
var callAndRemove=(function(){this.removeEventListener('ready',callAndRemove);callback();}).bind(this);this.addEventListener('ready',callAndRemove);};var allowed={elements:['a','em','strong','small','s','cite','q','dfn','abbr','data','time','code','var','samp','kbd','sub','sup','i','b','u','mark','ruby','rt','rp','bdi','bdo','span','br','wbr'],attributes:{global:['title','aria-label','aria-valuetext','aria-moz-hint'],a:['download'],area:['download','alt'],input:['alt','placeholder'],menuitem:['label'],menu:['label'],optgroup:['label'],option:['label'],track:['label'],img:['alt'],textarea:['placeholder'],th:['abbr']}};var rtlList=['ar','he','fa','ps','ar-x-psbidi','ur'];var nodeObserver=null;var pendingElements=null;var moConfig={attributes:true,characterData:false,childList:true,subtree:true,attributeFilter:['data-l10n-id','data-l10n-args']};navigator.mozL10n={ctx:null,get:function get(id,ctxdata){return navigator.mozL10n.ctx.get(id,ctxdata);},formatValue:function(id,ctxdata){return navigator.mozL10n.ctx.formatValue(id,ctxdata);},formatEntity:function(id,ctxdata){return navigator.mozL10n.ctx.formatEntity(id,ctxdata);},translateFragment:function(fragment){return translateFragment.call(navigator.mozL10n,fragment);},setAttributes:setL10nAttributes,getAttributes:getL10nAttributes,ready:function ready(callback){return navigator.mozL10n.ctx.ready(callback);},once:function once(callback){return navigator.mozL10n.ctx.once(callback);},get readyState(){return navigator.mozL10n.ctx.isReady?'complete':'loading';},language:{set code(lang){navigator.mozL10n.ctx.requestLocales(lang);},get code(){return navigator.mozL10n.ctx.supportedLocales[0];},get direction(){return getDirection(navigator.mozL10n.ctx.supportedLocales[0]);}},qps:PSEUDO,_config:{appVersion:null,localeSources:Object.create(null),isPretranslated:false,},_getInternalAPI:function(){return{Error:L10nError,Context:Context,Locale:Locale,Resolver:Resolver,getPluralRule:getPluralRule,rePlaceables:rePlaceables,translateDocument:translateDocument,onMetaInjected:onMetaInjected,PropertiesParser:PropertiesParser,walkContent:walkContent,buildLocaleList:buildLocaleList};}};function getDirection(lang){return(rtlList.indexOf(lang)>=0)?'rtl':'ltr';}
var readyStates={loading:0,interactive:1,complete:2};function whenInteractive(callback){if(readyStates[document.readyState]>=readyStates.interactive){callback();return;}
document.addEventListener('readystatechange',function l10n_onrsc(){if(readyStates[document.readyState]>=readyStates.interactive){document.removeEventListener('readystatechange',l10n_onrsc);callback();}});}
function initObserver(){nodeObserver=new MutationObserver(onMutations.bind(navigator.mozL10n));nodeObserver.observe(document,moConfig);}
function init(pretranslate){if(!pretranslate){initObserver();}
initResources.call(navigator.mozL10n);}
function initResources(){var meta={};var nodes=document.head.querySelectorAll('link[rel="localization"],'+'meta[name="availableLanguages"],'+'meta[name="defaultLanguage"],'+'meta[name="appVersion"],'+'script[type="application/l10n"]');for(var i=0,node;node=nodes[i];i++){var type=node.getAttribute('rel')||node.nodeName.toLowerCase();switch(type){case'localization':this.ctx.resLinks.push(node.getAttribute('href'));break;case'meta':onMetaInjected.call(this,node,meta);break;case'script':onScriptInjected.call(this,node);break;}}
var additionalLanguagesPromise;if(navigator.mozApps&&navigator.mozApps.getAdditionalLanguages){additionalLanguagesPromise=navigator.mozApps.getAdditionalLanguages().catch(function(e){console.error('Error while loading getAdditionalLanguages',e);});document.addEventListener('additionallanguageschange',function(evt){registerLocales.call(this,meta,evt.detail);this.ctx.requestLocales.apply(this.ctx,navigator.languages||[navigator.language]);}.bind(this));}else{additionalLanguagesPromise=Promise.resolve();}
additionalLanguagesPromise.then(function(extraLangs){registerLocales.call(this,meta,extraLangs);initLocale.call(this);}.bind(this));}
function registerLocales(meta,extraLangs){var locales=buildLocaleList.call(this,meta,extraLangs);navigator.mozL10n._config.localeSources=locales[1];this.ctx.registerLocales(locales[0],Object.keys(locales[1]));}
function getMatchingLangpack(appVersion,langpacks){for(var i=0,langpack;(langpack=langpacks[i]);i++){if(langpack.target===appVersion){return langpack;}}
return null;}
function buildLocaleList(meta,extraLangs){var loc,lp;var localeSources=Object.create(null);var defaultLocale=meta.defaultLanguage||this.ctx.defaultLocale;if(meta.availableLanguages){for(loc in meta.availableLanguages){localeSources[loc]='app';}}
if(extraLangs){for(loc in extraLangs){lp=getMatchingLangpack(this._config.appVersion,extraLangs[loc]);if(!lp){continue;}
if(!(loc in localeSources)||!meta.availableLanguages[loc]||parseInt(lp.revision)>meta.availableLanguages[loc]){localeSources[loc]='extra';}}}
if(!(defaultLocale in localeSources)){localeSources[defaultLocale]='app';}
return[defaultLocale,localeSources];}
function splitAvailableLanguagesString(str){var langs={};str.split(',').forEach(function(lang){lang=lang.trim().split(':');langs[lang[0]]=parseInt(lang[1]);});return langs;}
function onMetaInjected(node,meta){switch(node.getAttribute('name')){case'availableLanguages':meta.availableLanguages=splitAvailableLanguagesString(node.getAttribute('content'));break;case'defaultLanguage':meta.defaultLanguage=node.getAttribute('content');break;case'appVersion':navigator.mozL10n._config.appVersion=node.getAttribute('content');break;}}
function onScriptInjected(node){var lang=node.getAttribute('lang');var locale=this.ctx.getLocale(lang);locale.addAST(JSON.parse(node.textContent));}
function initLocale(){this.ctx.requestLocales.apply(this.ctx,navigator.languages||[navigator.language]);window.addEventListener('languagechange',function l10n_langchange(){this.ctx.requestLocales.apply(this.ctx,navigator.languages||[navigator.language]);}.bind(this));}
function localizeMutations(mutations){var mutation;var targets=new Set();for(var i=0;i<mutations.length;i++){mutation=mutations[i];if(mutation.type==='childList'){var addedNode;for(var j=0;j<mutation.addedNodes.length;j++){addedNode=mutation.addedNodes[j];if(addedNode.nodeType!==Node.ELEMENT_NODE){continue;}
targets.add(addedNode);}}
if(mutation.type==='attributes'){targets.add(mutation.target);}}
targets.forEach(function(target){if(target.childElementCount){translateFragment.call(this,target);}else if(target.hasAttribute('data-l10n-id')){translateElement.call(this,target);}},this);}
function onMutations(mutations,self){self.disconnect();localizeMutations.call(this,mutations);self.observe(document,moConfig);}
function onReady(){if(!navigator.mozL10n._config.isPretranslated){translateDocument.call(this);}
navigator.mozL10n._config.isPretranslated=false;if(pendingElements){for(var i=0,element;element=pendingElements[i];i++){translateElement.call(this,element);}
pendingElements=null;}
if(!nodeObserver){initObserver();}
fireLocalizedEvent.call(this);}
function fireLocalizedEvent(){var event=new CustomEvent('localized',{'bubbles':false,'cancelable':false,'detail':{'language':this.ctx.supportedLocales[0]}});window.dispatchEvent(event);}
var reOverlay=/<|&#?\w+;/;var reHtml=/[&<>]/g;var htmlEntities={'&':'&amp;','<':'&lt;','>':'&gt;',};function translateDocument(){document.documentElement.lang=this.language.code;document.documentElement.dir=this.language.direction;translateFragment.call(this,document.documentElement);}
function translateFragment(element){if(typeof element.hasAttribute==='function'&&element.hasAttribute('data-l10n-id')){translateElement.call(this,element);}
var nodes=getTranslatableChildren(element);for(var i=0;i<nodes.length;i++){translateElement.call(this,nodes[i]);}}
function setL10nAttributes(element,id,args){element.setAttribute('data-l10n-id',id);if(args){element.setAttribute('data-l10n-args',JSON.stringify(args));}}
function getL10nAttributes(element){return{id:element.getAttribute('data-l10n-id'),args:JSON.parse(element.getAttribute('data-l10n-args'))};}
function getTranslatableChildren(element){return element?element.querySelectorAll('*[data-l10n-id]'):[];}
function camelCaseToDashed(string){if(string==='ariaValueText'){return'aria-valuetext';}
return string.replace(/[A-Z]/g,function(match){return'-'+match.toLowerCase();}).replace(/^-/,'');}
function escapeL10nArgs(match){return htmlEntities[match];}
function translateElement(element){if(!this.ctx.isReady){if(!pendingElements){pendingElements=[];}
pendingElements.push(element);return;}
var l10nId=element.getAttribute('data-l10n-id');if(!l10nId){return false;}
var l10nArgs=element.getAttribute('data-l10n-args');var entity=this.ctx.getEntity(l10nId,l10nArgs?JSON.parse(l10nArgs.replace(reHtml,escapeL10nArgs)):undefined);var value=entity.value;if(typeof value==='string'){if(!reOverlay.test(value)){element.textContent=value;}else{var translation=element.ownerDocument.createElement('template');translation.innerHTML=value;overlayElement(element,translation.content);}}
for(var key in entity.attrs){var attrName=camelCaseToDashed(key);if(isAttrAllowed({name:attrName},element)){element.setAttribute(attrName,entity.attrs[key]);}}}
function overlayElement(sourceElement,translationElement){var result=translationElement.ownerDocument.createDocumentFragment();var k,attr;var childElement;while((childElement=translationElement.childNodes[0])){translationElement.removeChild(childElement);if(childElement.nodeType===Node.TEXT_NODE){result.appendChild(childElement);continue;}
var index=getIndexOfType(childElement);var sourceChild=getNthElementOfType(sourceElement,childElement,index);if(sourceChild){overlayElement(sourceChild,childElement);result.appendChild(sourceChild);continue;}
if(isElementAllowed(childElement)){var sanitizedChild=childElement.ownerDocument.createElement(childElement.nodeName);overlayElement(sanitizedChild,childElement);result.appendChild(sanitizedChild);continue;}
result.appendChild(document.createTextNode(childElement.textContent));}
sourceElement.textContent='';sourceElement.appendChild(result);if(translationElement.attributes){for(k=0,attr;(attr=translationElement.attributes[k]);k++){if(isAttrAllowed(attr,sourceElement)){sourceElement.setAttribute(attr.name,attr.value);}}}}
function isElementAllowed(element){return allowed.elements.indexOf(element.tagName.toLowerCase())!==-1;}
function isAttrAllowed(attr,element){var attrName=attr.name.toLowerCase();var tagName=element.tagName.toLowerCase();if(allowed.attributes.global.indexOf(attrName)!==-1){return true;}
if(!allowed.attributes[tagName]){return false;}
if(allowed.attributes[tagName].indexOf(attrName)!==-1){return true;}
if(tagName==='input'&&attrName==='value'){var type=element.type.toLowerCase();if(type==='submit'||type==='button'||type==='reset'){return true;}}
return false;}
function getNthElementOfType(context,element,index){var nthOfType=0;for(var i=0,child;child=context.children[i];i++){if(child.nodeType===Node.ELEMENT_NODE&&child.tagName===element.tagName){if(nthOfType===index){return child;}
nthOfType++;}}
return null;}
function getIndexOfType(element){var index=0;var child;while((child=element.previousElementSibling)){if(child.tagName===element.tagName){index++;}}
return index;}
var DEBUG=false;navigator.mozL10n.ctx=new Context(window.document?document.URL:null);navigator.mozL10n.ctx.ready(onReady.bind(navigator.mozL10n));navigator.mozL10n.ctx.addEventListener('notfounderror',function reportMissingEntity(e){if(DEBUG||e.loc==='en-US'){console.warn(e.toString());}});if(DEBUG){navigator.mozL10n.ctx.addEventListener('fetcherror',console.error.bind(console));navigator.mozL10n.ctx.addEventListener('parseerror',console.error.bind(console));navigator.mozL10n.ctx.addEventListener('resolveerror',console.error.bind(console));}
if(window.document){navigator.mozL10n._config.isPretranslated=document.documentElement.lang===navigator.language;var forcePretranslate=!navigator.mozL10n._config.isPretranslated;whenInteractive(init.bind(navigator.mozL10n,forcePretranslate));}
document.l10n={setAttributes:navigator.mozL10n.setAttributes,getAttributes:navigator.mozL10n.getAttributes,formatValue:function(id,args){return navigator.mozL10n.formatValue(id,args);},translateFragment:function(frag){return Promise.resolve(navigator.mozL10n.translateFragment(frag));},ready:new Promise(function(resolve){navigator.mozL10n.once(resolve);}),formatValues:function(){var keys=arguments;var resp=keys.map(function(key){if(Array.isArray(key)){return navigator.mozL10n.formatValue(key[0],key[1]);}
return navigator.mozL10n.formatValue(key);});return Promise.all(resp);},requestLanguages:function(langs){navigator.mozL10n.ctx.requestLocales.apply(navigator.mozL10n.ctx,langs);},pseudo:{'fr-x-psaccent':{getName:function(){return Promise.resolve(navigator.mozL10n.qps['fr-x-psaccent'].name);},processString:function(s){return Promise.resolve(navigator.mozL10n.qps['fr-x-psaccent'].translate(s));}},'ar-x-psbidi':{getName:function(){return Promise.resolve(navigator.mozL10n.qps['ar-x-psbidi'].name);},processString:function(s){return Promise.resolve(navigator.mozL10n.qps['ar-x-psbidi'].translate(s));}}},};navigator.mozL10n.ready(function(){document.documentElement.setAttribute('langs',navigator.mozL10n.ctx.supportedLocales.join(' '));});navigator.mozL10n.once(function(){window.addEventListener('localized',function(){document.dispatchEvent(new CustomEvent('DOMRetranslated',{bubbles:false,cancelable:false}));});});})(this);;'use strict';var MediaDB=(function(){function MediaDB(mediaType,metadataParser,options){this.mediaType=mediaType;this.metadataParser=metadataParser;if(!options){options={};}
this.indexes=options.indexes||[];this.version=options.version||1;this.mimeTypes=options.mimeTypes;this.autoscan=(options.autoscan!==undefined)?options.autoscan:true;this.state=MediaDB.OPENING;this.scanning=false;this.initialScanComplete=false;this.parsingBigFiles=false;this.updateRecord=options.updateRecord;this.reparsedRecord=options.reparsedRecord;if(options.excludeFilter&&(options.excludeFilter instanceof RegExp)){this.clientExcludeFilter=options.excludeFilter;}
this.batchHoldTime=options.batchHoldTime||100;this.batchSize=options.batchSize||0;this.dbname='MediaDB/'+this.mediaType+'/';var media=this;this.details={eventListeners:{},pendingInsertions:[],pendingDeletions:[],whenDoneProcessing:[],pendingCreateNotifications:[],pendingDeleteNotifications:[],pendingNotificationTimer:null,newestFileModTime:0};if(!this.metadataParser){this.metadataParser=function(file,callback){setTimeout(function(){callback({});},0);};}
var dbVersion=(0xFFFF&this.version)<<16|(0xFFFF&MediaDB.VERSION);var openRequest=indexedDB.open(this.dbname,dbVersion);openRequest.onerror=function(e){console.error('MediaDB():',openRequest.error.name);};openRequest.onblocked=function(e){console.error('indexedDB.open() is blocked in MediaDB()');};openRequest.onupgradeneeded=function(e){var db=openRequest.result;var transaction=e.target.transaction;var oldVersion=e.oldVersion;var oldDbVersion=0xFFFF&oldVersion;var oldClientVersion=0xFFFF&(oldVersion>>16);if(oldClientVersion===0){oldDbVersion=2;oldClientVersion=oldVersion/oldDbVersion;}
if(0===db.objectStoreNames.length){createObjectStores(db);}else{handleUpgrade(db,transaction,oldDbVersion,oldClientVersion);}};openRequest.onsuccess=function(e){media.db=openRequest.result;media.db.onerror=function(event){console.error('MediaDB: ',event.target.error&&event.target.error.name);};changeState(media,MediaDB.ENUMERABLE);var cursorRequest=media.db.transaction('files','readonly').objectStore('files').index('date').openCursor(null,'prev');cursorRequest.onerror=function(){console.error('MediaDB initialization error',cursorRequest.error);};cursorRequest.onsuccess=function(){var cursor=cursorRequest.result;if(cursor){media.details.newestFileModTime=cursor.value.date;}
else{media.details.newestFileModTime=0;}
initDeviceStorage();};};function createObjectStores(db){var filestore=db.createObjectStore('files',{keyPath:'name'});filestore.createIndex('date','date');media.indexes.forEach(function(indexName){if(indexName==='name'||indexName==='date'){return;}
filestore.createIndex(indexName,indexName);});}
function enumerateOldFiles(store,callback){var openCursorReq=store.openCursor();openCursorReq.onsuccess=function(){var cursor=openCursorReq.result;if(cursor){callback(cursor.value);cursor.continue();}};}
function handleUpgrade(db,trans,oldDbVersion,oldClientVersion){media.state=MediaDB.UPGRADING;var evtDetail={'oldMediaDBVersion':oldDbVersion,'oldClientVersion':oldClientVersion,'newMediaDBVersion':MediaDB.VERSION,'newClientVersion':media.version};dispatchEvent(media,'upgrading',evtDetail);var store=trans.objectStore('files');if(media.version!=oldClientVersion){upgradeIndexesChanges(store);}
var clientUpgradeNeeded=(media.version!=oldClientVersion)&&media.updateRecord;if((2!=oldDbVersion||3!=MediaDB.VERSION)&&!clientUpgradeNeeded){return;}
enumerateOldFiles(store,function doUpgrade(dbfile){if(2==oldDbVersion&&3==MediaDB.VERSION){upgradeDBVer2to3(store,dbfile);}
if(clientUpgradeNeeded){handleClientUpgrade(store,dbfile,oldClientVersion);}});}
function upgradeIndexesChanges(store){var dbIndexes=store.indexNames;var clientIndexes=media.indexes;for(var i=0;i<dbIndexes.length;i++){if('name'===dbIndexes[i]||'date'===dbIndexes[i]){continue;}
if(clientIndexes.indexOf(dbIndexes[i])<0){store.deleteIndex(dbIndexes[i]);}}
for(i=0;i<clientIndexes.length;i++){if(!dbIndexes.contains(clientIndexes[i])){store.createIndex(clientIndexes[i],clientIndexes[i]);}}}
function upgradeDBVer2to3(store,dbfile){if(dbfile.name[0]==='/'){return;}
store.delete(dbfile.name);dbfile.name='/sdcard/'+dbfile.name;store.add(dbfile);}
function handleClientUpgrade(store,dbfile,oldClientVersion){try{dbfile.metadata=media.updateRecord(dbfile,oldClientVersion,media.version);if(dbfile.needsReparse&&!media.reparsedRecord){console.warn('client app requested reparse, but no reparsedRecord was set');delete dbfile.needsReparse;}
store.put(dbfile);}catch(ex){console.warn('client app updates record, '+dbfile.name+', failed: '+ex.message);}}
function initDeviceStorage(){var details=media.details;details.storages=navigator.getDeviceStorages(mediaType);details.availability={};getStorageAvailability();function getStorageAvailability(){var next=0;getNextAvailability();function getNextAvailability(){if(next>=details.storages.length){setupHandlers();return;}
var s=details.storages[next++];var name=s.storageName;var req=s.available();req.onsuccess=function(e){details.availability[name]=req.result;getNextAvailability();};req.onerror=function(e){details.availability[name]='unavailable';getNextAvailability();};}}
function setupHandlers(){for(var i=0;i<details.storages.length;i++){details.storages[i].addEventListener('change',changeHandler);}
details.dsEventListener=changeHandler;sendInitialEvent();}
function sendInitialEvent(){var state=getState(details.availability);changeState(media,state);if(media.autoscan){scan(media);}}
function getState(availability){var n=0;var a=0;var u=0;var s=0;for(var name in availability){n++;switch(availability[name]){case'available':a++;break;case'unavailable':u++;break;case'shared':s++;break;}}
if(s>0){return MediaDB.UNMOUNTED;}
if(u===n){return MediaDB.NOCARD;}
return MediaDB.READY;}
function changeHandler(e){switch(e.reason){case'modified':case'deleted':fileChangeHandler(e);return;case'available':case'unavailable':case'shared':volumeChangeHandler(e);return;default:return;}}
function volumeChangeHandler(e){var storageName=e.target.storageName;if(details.availability[storageName]===e.reason){return;}
var oldState=media.state;details.availability[storageName]=e.reason;var newState=getState(details.availability);if(newState!==oldState){changeState(media,newState);if(newState===MediaDB.READY){if(media.autoscan){scan(media);}}
else{endscan(media);}}
else if(newState===MediaDB.READY){if(e.reason==='available'){dispatchEvent(media,'ready');if(media.autoscan){scan(media);}}
else if(e.reason==='unavailable'){dispatchEvent(media,'cardremoved');deleteAllFiles(storageName);}}}
function fileChangeHandler(e){var filename=e.path;if(ignoreName(media,filename)){return;}
if(e.reason==='modified'){insertRecord(media,filename);}else{deleteRecord(media,filename);}}
function deleteAllFiles(storageName){var storagePrefix=storageName?'/'+storageName+'/':'';var store=media.db.transaction('files').objectStore('files');var cursorRequest=store.openCursor();cursorRequest.onsuccess=function(){var cursor=cursorRequest.result;if(cursor){if(cursor.value.name.startsWith(storagePrefix)){deleteRecord(media,cursor.value.name);}
cursor.continue();}};}}}
MediaDB.prototype={close:function close(){this.db.close();for(var i=0;i<this.details.storages.length;i++){var s=this.details.storages[i];s.removeEventListener('change',this.details.dsEventListener);}
changeState(this,MediaDB.CLOSED);},addEventListener:function addEventListener(type,listener){if(!this.details.eventListeners.hasOwnProperty(type)){this.details.eventListeners[type]=[];}
var listeners=this.details.eventListeners[type];if(listeners.indexOf(listener)!==-1){return;}
listeners.push(listener);},removeEventListener:function removeEventListener(type,listener){if(!this.details.eventListeners.hasOwnProperty(type)){return;}
var listeners=this.details.eventListeners[type];var position=listeners.indexOf(listener);if(position===-1){return;}
listeners.splice(position,1);},getFileInfo:function getFile(filename,callback,errback){if(this.state===MediaDB.OPENING){throw Error('MediaDB is not ready. State: '+this.state);}
var media=this;var read=media.db.transaction('files','readonly').objectStore('files').get(filename);read.onerror=function(){var msg='MediaDB.getFileInfo: unknown filename: '+filename;if(errback){errback(msg);}else{console.error(msg);}};read.onsuccess=function(){if(callback){callback(read.result);}};},getFile:function getFile(filename,callback,errback){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
var storage=navigator.getDeviceStorage(this.mediaType);var getRequest=storage.get(filename);getRequest.onsuccess=function(){callback(getRequest.result);};getRequest.onerror=function(){var errmsg=getRequest.error&&getRequest.error.name;if(errback){errback(errmsg);}else{console.error('MediaDB.getFile:',errmsg);}};},deleteFile:function deleteFile(filename){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
var storage=navigator.getDeviceStorage(this.mediaType);storage.delete(filename).onerror=function(e){console.error('MediaDB.deleteFile(): Failed to delete',filename,'from DeviceStorage:',e.target.error);};},addFile:function addFile(filename,file){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
var media=this;var storage=navigator.getDeviceStorage(media.mediaType);var deletereq=storage.delete(filename);deletereq.onsuccess=deletereq.onerror=save;function save(){var request=storage.addNamed(file,filename);request.onerror=function(){console.error('MediaDB: Failed to store',filename,'in DeviceStorage:',request.error);};}},updateMetadata:function(filename,metadata,callback){if(this.state===MediaDB.OPENING){throw Error('MediaDB is not ready. State: '+this.state);}
var media=this;var read=media.db.transaction('files','readonly').objectStore('files').get(filename);read.onerror=function(){console.error('MediaDB.updateMetadata called with unknown filename');};read.onsuccess=function(){var fileinfo=read.result;Object.keys(metadata).forEach(function(key){fileinfo.metadata[key]=metadata[key];});var write=media.db.transaction('files','readwrite').objectStore('files').put(fileinfo);write.onerror=function(){console.error('MediaDB.updateMetadata: database write failed',write.error&&write.error.name);};if(callback){write.onsuccess=function(){callback();};}};},count:function(key,range,callback){if(this.state!==MediaDB.READY&&this.state!==MediaDB.ENUMERABLE){throw Error('MediaDB is not ready or enumerable. State: '+this.state);}
if(arguments.length===1){callback=key;range=undefined;key=undefined;}
else if(arguments.length===2){callback=range;range=key;key=undefined;}
var store=this.db.transaction('files').objectStore('files');if(key&&key!=='name'){store=store.index(key);}
var countRequest=store.count(range||null);countRequest.onerror=function(){console.error('MediaDB.count() failed with',countRequest.error);};countRequest.onsuccess=function(e){callback(e.target.result);};},enumerate:function enumerate(key,range,direction,callback){if(this.state!==MediaDB.READY&&this.state!==MediaDB.ENUMERABLE){throw Error('MediaDB is not ready or enumerable. State: '+this.state);}
var handle={state:'enumerating'};if(arguments.length===1){callback=key;key=undefined;}
else if(arguments.length===2){callback=range;range=undefined;}
else if(arguments.length===3){callback=direction;direction=undefined;}
var store=this.db.transaction('files').objectStore('files');if(key&&key!=='name'){store=store.index(key);}
var cursorRequest=store.openCursor(range||null,direction||'next');cursorRequest.onerror=function(){console.error('MediaDB.enumerate() failed with',cursorRequest.error);handle.state='error';};cursorRequest.onsuccess=function(){if(handle.state==='cancelling'){handle.state='cancelled';return;}
var cursor=cursorRequest.result;if(cursor){try{var fileinfo=cursor.value;if(!fileinfo.fail){callback(fileinfo);}}
catch(e){console.warn('MediaDB.enumerate(): callback threw',e,e.stack);}
cursor.continue();}
else{handle.state='complete';callback(null);}};return handle;},advancedEnumerate:function(key,range,direction,index,callback){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
var handle={state:'enumerating'};var store=this.db.transaction('files').objectStore('files');if(key&&key!=='name'){store=store.index(key);}
var cursorRequest=store.openCursor(range||null,direction||'next');var isTarget=false;cursorRequest.onerror=function(){console.error('MediaDB.enumerate() failed with',cursorRequest.error);handle.state='error';};cursorRequest.onsuccess=function(){if(handle.state==='cancelling'){handle.state='cancelled';return;}
var cursor=cursorRequest.result;if(cursor){try{if(index===0){isTarget=true;}
var fileinfo=cursor.value;if(!fileinfo.fail&&isTarget){callback(cursor.value);cursor.continue();}
else{cursor.advance(index);isTarget=true;}}
catch(e){console.warn('MediaDB.enumerate(): callback threw',e,e.stack);}}
else{handle.state='complete';callback(null);}};return handle;},enumerateAll:function enumerateAll(key,range,direction,callback){var batch=[];if(arguments.length===1){callback=key;key=undefined;}
else if(arguments.length===2){callback=range;range=undefined;}
else if(arguments.length===3){callback=direction;direction=undefined;}
return this.enumerate(key,range,direction,function(fileinfo){if(fileinfo!==null){batch.push(fileinfo);}else{callback(batch);}});},cancelEnumeration:function cancelEnumeration(handle){if(handle.state==='enumerating'){handle.state='cancelling';}},getAll:function getAll(callback){if(this.state!==MediaDB.READY&&this.state!==MediaDB.ENUMERABLE){throw Error('MediaDB is not ready or enumerable. State: '+this.state);}
var store=this.db.transaction('files').objectStore('files');var request=store.mozGetAll();request.onerror=function(){console.error('MediaDB.getAll() failed with',request.error);};request.onsuccess=function(){var all=request.result;var good=all.filter(function(fileinfo){return!fileinfo.fail;});callback(good);};},scan:function(){scan(this);},freeSpace:function freeSpace(callback){if(this.state!==MediaDB.READY){throw Error('MediaDB is not ready. State: '+this.state);}
var storage=navigator.getDeviceStorage(this.mediaType);var freereq=storage.freeSpace();freereq.onsuccess=function(){callback(freereq.result);};}};MediaDB.VERSION=3;MediaDB.OPENING='opening';MediaDB.UPGRADING='upgrading';MediaDB.ENUMERABLE='enumerable';MediaDB.READY='ready';MediaDB.NOCARD='nocard';MediaDB.UNMOUNTED='unmounted';MediaDB.CLOSED='closed';function ignore(media,file){if(ignoreName(media,file.name)){return true;}
if(media.mimeTypes&&media.mimeTypes.indexOf(file.type)===-1){return true;}
return false;}
function ignoreName(media,filename){if(media.clientExcludeFilter&&media.clientExcludeFilter.test(filename)){return true;}else{return(filename[0]==='.'||filename.indexOf('/.')!==-1);}}
function scan(media){media.scanning=true;dispatchEvent(media,'scanstart');quickScan(media.details.newestFileModTime);function quickScan(timestamp){var options;if(timestamp>0){media.details.firstscan=false;options={since:new Date(timestamp+1)};}
else{media.details.firstscan=true;media.details.records=[];options={};}
scanDS(media.details.storages,null,options).then(processFiles).catch(handleScanError);function processFiles(files){if(!media.scanning){return;}
files=files.sort(function(a,b){return b.lastModifiedDate-a.lastModifiedDate;});for(var i=0;i<files.length;i++){insertRecord(media,files[i]);}
whenDoneProcessing(media,function(){sendNotifications(media);if(media.details.firstscan){endscan(media);}
else{fullScan();}});}
function handleScanError(error){console.warn('Error while scanning',error);endscan(media);}}
function fullScan(){if(media.state!==MediaDB.READY){endscan(media);return;}
var dsfiles;scanDS(media.details.storages).then(function(files){dsfiles=files;getDBFiles();}).catch(function(error){console.warn('Error while scanning',error);endscan(media);});function getDBFiles(){var store=media.db.transaction('files').objectStore('files');var getAllRequest=store.mozGetAll();getAllRequest.onsuccess=function(){if(!media.scanning){return;}
var dbfiles=getAllRequest.result;compareLists(dbfiles,dsfiles);};}
function compareLists(dbfiles,dsfiles){dsfiles.sort(function(a,b){if(a.name<b.name){return-1;}else{return 1;}});var dsindex=0,dbindex=0;while(true){var dsfile;if(dsindex<dsfiles.length){dsfile=dsfiles[dsindex];}else{dsfile=null;}
var dbfile;if(dbindex<dbfiles.length){dbfile=dbfiles[dbindex];}else{dbfile=null;}
if(dsfile===null&&dbfile===null){break;}
if(dbfile===null){insertRecord(media,dsfile);dsindex++;continue;}
if(dsfile===null){deleteRecord(media,dbfile.name);dbindex++;continue;}
if(dsfile.name===dbfile.name){var lastModified=dsfile.lastModifiedDate;var timeDifference=lastModified.getTime()-dbfile.date;var sameTime=(timeDifference===0||((Math.abs(timeDifference)<=12*60*60*1000)&&(timeDifference%10*60*1000===0)));var sameSize=dsfile.size===dbfile.size;if(!sameTime||!sameSize){deleteRecord(media,dbfile.name);insertRecord(media,dsfile);}else if(dbfile.needsReparse){deleteRecord(media,dbfile.name);insertRecord(media,dsfile,dbfile.metadata);}
dsindex++;dbindex++;continue;}
if(dsfile.name<dbfile.name){insertRecord(media,dsfile);dsindex++;continue;}
if(dsfile.name>dbfile.name){deleteRecord(media,dbfile.name);dbindex++;continue;}
console.error('Assertion failed');}
insertRecord(media,null);}}
function scanDS(storage,directory,options){if(Array.isArray(storage)){return Promise.all(storage.map((s)=>scanDS(s,directory,options))).then(function(arrays){return Array.prototype.concat.apply([],arrays);});}
return new Promise(function(resolve,reject){var files=[];var cursor=storage.enumerate(directory||'',options||{});cursor.onerror=function(){if(cursor.error.name==='NotFoundError'){resolve(files);}
else{reject(cursor.error);}};cursor.onsuccess=function(){var result=cursor.result;if(result){if(!ignore(media,result)){files.push(result);}
cursor.continue();}
else{resolve(files);}};});}}
function endscan(media){if(media.scanning){media.initialScanComplete=true;media.scanning=false;media.parsingBigFiles=false;dispatchEvent(media,'scanend');}}
function insertRecord(media,fileOrName,oldMetadata){var details=media.details;details.pendingInsertions.push([fileOrName,oldMetadata]);if(details.processingQueue){return;}
processQueue(media);}
function deleteRecord(media,filename){var details=media.details;details.pendingDeletions.push(filename);if(details.processingQueue){return;}
processQueue(media);}
function whenDoneProcessing(media,f){var details=media.details;if(details.processingQueue){details.whenDoneProcessing.push(f);}else{f();}}
function processQueue(media){var details=media.details;details.processingQueue=true;next();function next(){if(details.pendingDeletions.length>0){deleteFiles();}
else if(details.pendingInsertions.length>0){insertFile(...details.pendingInsertions.shift());}
else{details.processingQueue=false;if(details.whenDoneProcessing.length>0){var functions=details.whenDoneProcessing;details.whenDoneProcessing=[];functions.forEach(function(f){f();});}}}
function deleteFiles(){var transaction=media.db.transaction('files','readwrite');var store=transaction.objectStore('files');deleteNextFile();function deleteNextFile(){if(details.pendingDeletions.length===0){next();return;}
var filename=details.pendingDeletions.shift();var request=store.delete(filename);request.onerror=function(){console.warn('MediaDB: Unknown file in deleteRecord:',filename,request.error);deleteNextFile();};request.onsuccess=function(){queueDeleteNotification(media,filename);deleteNextFile();};}}
function insertFile(f,oldMetadata){if(f===null){sendNotifications(media);endscan(media);next();return;}
if(typeof f==='string'){var storage=navigator.getDeviceStorage(media.mediaType);var getreq=storage.get(f);getreq.onerror=function(){console.warn('MediaDB: Unknown file in insertRecord:',f,getreq.error);next();};getreq.onsuccess=function(){if(media.mimeTypes&&ignore(media,getreq.result)){next();}else{parseMetadata(getreq.result,f,oldMetadata);}};}
else{parseMetadata(f,f.name,oldMetadata);}}
function parseMetadata(file,filename,oldMetadata){if(!file.lastModifiedDate){console.warn('MediaDB: parseMetadata: no lastModifiedDate for',filename,'using Date.now() until #793955 is fixed');}
var fileinfo={name:filename,type:file.type,size:file.size,date:file.lastModifiedDate?file.lastModifiedDate.getTime():Date.now()};if(fileinfo.date>details.newestFileModTime){details.newestFileModTime=fileinfo.date;}
media.metadataParser(file,gotMetadata,metadataError,parsingBigFile);function parsingBigFile(){media.parsingBigFiles=true;}
function metadataError(e){console.warn('MediaDB: error parsing metadata for',filename,':',e);fileinfo.fail=true;storeRecord(fileinfo);}
function gotMetadata(metadata){fileinfo.metadata=metadata;if(oldMetadata&&media.reparsedRecord){fileinfo.metadata=media.reparsedRecord(oldMetadata,metadata);}
storeRecord(fileinfo);if(!media.scanning){media.parsingBigFiles=false;}}}
function storeRecord(fileinfo){if(media.details.firstscan){media.details.records.push(fileinfo);if(!fileinfo.fail){queueCreateNotification(media,fileinfo);}
next();}
else{var transaction=media.db.transaction('files','readwrite');var store=transaction.objectStore('files');var request=store.add(fileinfo);request.onsuccess=function(){if(!fileinfo.fail){queueCreateNotification(media,fileinfo);}
next();};request.onerror=function(event){if(request.error.name==='ConstraintError'){event.stopPropagation();event.preventDefault();var putrequest=store.put(fileinfo);putrequest.onsuccess=function(){queueDeleteNotification(media,fileinfo.name);if(!fileinfo.fail){queueCreateNotification(media,fileinfo);}
next();};putrequest.onerror=function(){console.error('MediaDB: unexpected ConstraintError','in insertRecord for file:',fileinfo.name);next();};}
else{console.error('MediaDB: unexpected error in insertRecord:',request.error,'for file:',fileinfo.name);next();}};}}}
function queueCreateNotification(media,fileinfo){var creates=media.details.pendingCreateNotifications;creates.push(fileinfo);if(media.batchSize&&creates.length>=media.batchSize){sendNotifications(media);}else{resetNotificationTimer(media);}}
function queueDeleteNotification(media,filename){var deletes=media.details.pendingDeleteNotifications;deletes.push(filename);if(media.batchSize&&deletes.length>=media.batchSize){sendNotifications(media);}else{resetNotificationTimer(media);}}
function resetNotificationTimer(media){var details=media.details;if(details.pendingNotificationTimer){clearTimeout(details.pendingNotificationTimer);}
details.pendingNotificationTimer=setTimeout(function(){sendNotifications(media);},media.scanning?media.batchHoldTime:100);}
function sendNotifications(media){var details=media.details;if(details.pendingNotificationTimer){clearTimeout(details.pendingNotificationTimer);details.pendingNotificationTimer=null;}
if(details.pendingDeleteNotifications.length>0){var deletions=details.pendingDeleteNotifications;details.pendingDeleteNotifications=[];dispatchEvent(media,'deleted',deletions);}
if(details.pendingCreateNotifications.length>0){var creations=details.pendingCreateNotifications;details.pendingCreateNotifications=[];if(details.firstscan&&details.records.length>0){var transaction=media.db.transaction('files','readwrite');var store=transaction.objectStore('files');for(var i=0;i<details.records.length;i++){store.add(details.records[i]);}
details.records.length=0;transaction.oncomplete=function(){dispatchEvent(media,'created',creations);};}
else{dispatchEvent(media,'created',creations);}}}
function dispatchEvent(media,type,detail){var handler=media['on'+type];var listeners=media.details.eventListeners[type];if(!handler&&(!listeners||listeners.length===0)){return;}
var event={type:type,target:media,currentTarget:media,timestamp:Date.now(),detail:detail};if(typeof handler==='function'){try{handler.call(media,event);}
catch(e){console.warn('MediaDB: ','on'+type,'event handler threw',e,e.stack);}}
if(!listeners){return;}
for(var i=0;i<listeners.length;i++){try{var listener=listeners[i];if(typeof listener==='function'){listener.call(media,event);}
else{listener.handleEvent(event);}}
catch(e){console.warn('MediaDB: ',type,'event listener threw',e,e.stack);}}}
function changeState(media,state){if(media.state!==state){media.state=state;switch(state){case MediaDB.READY:case MediaDB.ENUMERABLE:dispatchEvent(media,state);break;default:dispatchEvent(media,'unavailable',state);break;}}}
return MediaDB;}());;;'use strict';var LazyLoader=(function(){function LazyLoader(){this._loaded={};this._isLoading={};}
LazyLoader.prototype={_js:function(file,callback){var script=document.createElement('script');script.src=file;script.async=false;script.addEventListener('load',callback);document.head.appendChild(script);this._isLoading[file]=script;},_css:function(file,callback){var style=document.createElement('link');style.type='text/css';style.rel='stylesheet';style.href=file;document.head.appendChild(style);callback();},_html:function(domNode,callback){if(domNode.getAttribute('is')){this.load(['/shared/js/html_imports.js'],function(){HtmlImports.populate(callback);}.bind(this));return;}
for(var i=0;i<domNode.childNodes.length;i++){if(domNode.childNodes[i].nodeType==document.COMMENT_NODE){domNode.innerHTML=domNode.childNodes[i].nodeValue;break;}}
window.dispatchEvent(new CustomEvent('lazyload',{detail:domNode}));callback();},getJSON:function(file,mozSystem){return new Promise(function(resolve,reject){var xhr;if(mozSystem){xhr=new XMLHttpRequest({mozSystem:true});}else{xhr=new XMLHttpRequest();}
xhr.open('GET',file,true);xhr.responseType='json';xhr.onerror=function(error){reject(error);};xhr.onload=function(){if(xhr.response!==null){resolve(xhr.response);}else{reject(new Error('No valid JSON object was found ('+
xhr.status+' '+xhr.statusText+')'));}};xhr.send();});},load:function(files,callback){var deferred={};deferred.promise=new Promise(resolve=>{deferred.resolve=resolve;});if(!Array.isArray(files)){files=[files];}
var loadsRemaining=files.length,self=this;function perFileCallback(file){if(self._isLoading[file]){delete self._isLoading[file];}
self._loaded[file]=true;if(--loadsRemaining===0){deferred.resolve();if(callback){callback();}}}
for(var i=0;i<files.length;i++){var file=files[i];if(this._loaded[file.id||file]){perFileCallback(file);}else if(this._isLoading[file]){this._isLoading[file].addEventListener('load',perFileCallback.bind(null,file));}else{var method,idx;if(typeof file==='string'){method=file.match(/\.([^.]+)$/)[1];idx=file;}else{method='html';idx=file.id;}
this['_'+method](file,perFileCallback.bind(null,idx));}}
return deferred.promise;}};return new LazyLoader();}());;;(function(exports){'use strict';var FontSizeUtils={_cachedContexts:{},_getCachedContext:function(fontSize,fontFamily,fontStyle){fontStyle=fontStyle||'italic';var cache=this._cachedContexts;var ctx=cache[fontSize]&&cache[fontSize][fontFamily]?cache[fontSize][fontFamily][fontStyle]:null;if(!ctx){var canvas=document.createElement('canvas');canvas.setAttribute('moz-opaque','true');canvas.setAttribute('width','1');canvas.setAttribute('height','1');ctx=canvas.getContext('2d',{willReadFrequently:true});ctx.font=fontStyle+' '+fontSize+'px '+fontFamily;if(!cache[fontSize]){cache[fontSize]={};}
if(!cache[fontSize][fontFamily]){cache[fontSize][fontFamily]={};}
cache[fontSize][fontFamily][fontStyle]=ctx;}
return ctx;},resetCache:function(){this._cachedContexts={};},getFontWidth:function(string,fontSize,fontFamily,fontStyle){var ctx=this._getCachedContext(fontSize,fontFamily,fontStyle);return ctx.measureText(string).width;},getMaxFontSizeInfo:function(string,allowedSizes,fontFamily,maxWidth){var fontSize;var resultWidth;var i=allowedSizes.length-1;do{fontSize=allowedSizes[i];resultWidth=this.getFontWidth(string,fontSize,fontFamily);i--;}while(resultWidth>maxWidth&&i>=0);return{fontSize:fontSize,overflow:resultWidth>maxWidth,textWidth:resultWidth};},_overflowCountCache:-1,getOverflowCount:function(string,fontSize,fontFamily,maxWidth){var substring;var resultWidth;var overflowCount=-1;if(string.length>this._overflowCountCache){substring=string.substr(0,string.length-this._overflowCountCache);resultWidth=this.getFontWidth(substring,fontSize,fontFamily);if(resultWidth>maxWidth){overflowCount=this._overflowCountCache;}}
do{overflowCount++;substring=string.substr(0,string.length-overflowCount);resultWidth=this.getFontWidth(substring,fontSize,fontFamily);}while(substring.length>0&&resultWidth>maxWidth);this._overflowCountCache=overflowCount;return overflowCount;},getContentWidth:function(style){var width=parseInt(style.width,10);if(style.boxSizing==='border-box'){width-=(parseInt(style.paddingRight,10)+
parseInt(style.paddingLeft,10));}
return width;},getStyleProperties:function(element){var style=window.getComputedStyle(element);var contentWidth=this.getContentWidth(style);if(isNaN(contentWidth)){contentWidth=0;}
return{fontFamily:style.fontFamily,contentWidth:contentWidth,paddingRight:parseInt(style.paddingRight,10),paddingLeft:parseInt(style.paddingLeft,10),offsetLeft:element.offsetLeft};},getWindowWidth:function(){return window.innerWidth;}};exports.FontSizeUtils=FontSizeUtils;}(this));;'use strict';(function(exports){var AccessibilityHelper={setAriaSelected:function ah_setAriaSelected(selectedTab,tabs){Array.prototype.forEach.call(tabs,function setAriaSelectedAttr(tab){tab.setAttribute('aria-selected',tab===selectedTab?'true':'false');});}};exports.AccessibilityHelper=AccessibilityHelper;})(window);;;this.asyncStorage=(function(){'use strict';var DBNAME='asyncStorage';var DBVERSION=1;var STORENAME='keyvaluepairs';var db=null;function withDatabase(f){if(db){f();}else{var openreq=indexedDB.open(DBNAME,DBVERSION);openreq.onerror=function withStoreOnError(){console.error('asyncStorage: can\'t open database:',openreq.error.name);};openreq.onupgradeneeded=function withStoreOnUpgradeNeeded(){openreq.result.createObjectStore(STORENAME);};openreq.onsuccess=function withStoreOnSuccess(){db=openreq.result;f();};}}
function withStore(type,callback,oncomplete){withDatabase(function(){var transaction=db.transaction(STORENAME,type);if(oncomplete){transaction.oncomplete=oncomplete;}
callback(transaction.objectStore(STORENAME));});}
function getItem(key,callback){var req;withStore('readonly',function getItemBody(store){req=store.get(key);req.onerror=function getItemOnError(){console.error('Error in asyncStorage.getItem(): ',req.error.name);};},function onComplete(){var value=req.result;if(value===undefined){value=null;}
callback(value);});}
function setItem(key,value,callback){withStore('readwrite',function setItemBody(store){var req=store.put(value,key);req.onerror=function setItemOnError(){console.error('Error in asyncStorage.setItem(): ',req.error.name);};},callback);}
function removeItem(key,callback){withStore('readwrite',function removeItemBody(store){var req=store.delete(key);req.onerror=function removeItemOnError(){console.error('Error in asyncStorage.removeItem(): ',req.error.name);};},callback);}
function clear(callback){withStore('readwrite',function clearBody(store){var req=store.clear();req.onerror=function clearOnError(){console.error('Error in asyncStorage.clear(): ',req.error.name);};},callback);}
function length(callback){var req;withStore('readonly',function lengthBody(store){req=store.count();req.onerror=function lengthOnError(){console.error('Error in asyncStorage.length(): ',req.error.name);};},function onComplete(){callback(req.result);});}
function key(n,callback){if(n<0){callback(null);return;}
var req;withStore('readonly',function keyBody(store){var advanced=false;req=store.openCursor();req.onsuccess=function keyOnSuccess(){var cursor=req.result;if(!cursor){return;}
if(n===0||advanced){return;}
advanced=true;cursor.advance(n);};req.onerror=function keyOnError(){console.error('Error in asyncStorage.key(): ',req.error.name);};},function onComplete(){var cursor=req.result;callback(cursor?cursor.key:null);});}
return{getItem:getItem,setItem:setItem,removeItem:removeItem,clear:clear,length:length,key:key};}());;;(function(exports){'use strict';var ImageUtils=exports.ImageUtils={};const JPEG='image/jpeg';const PNG='image/png';const GIF='image/gif';const BMP='image/bmp';ImageUtils.JPEG=JPEG;ImageUtils.PNG=PNG;ImageUtils.GIF=GIF;ImageUtils.BMP=BMP;ImageUtils.getSizeAndType=function getSizeAndType(imageBlob){if(!(imageBlob instanceof Blob)){console.log('not blob');return Promise.reject(new TypeError('argument is not a Blob'));}
return new Promise(function(resolve,reject){if(imageBlob.size<=16){reject('corrupt image file');return;}
var bytesToRead=32*1024;if(imageBlob.type===PNG||imageBlob.type===GIF||imageBlob.type===BMP){bytesToRead=512;}
findSizeAndType(imageBlob,bytesToRead,success,tryagain);function success(data){resolve(data);}
function tryagain(data){if(data.type===JPEG){findSizeAndType(imageBlob,imageBlob.size,success,failure);}
else{reject(data.error);}}
function failure(data){reject(data.error);}});function findSizeAndType(imageBlob,amountToRead,success,failure){var slice=imageBlob.slice(0,Math.min(amountToRead,imageBlob.size));var reader=new FileReader();reader.readAsArrayBuffer(slice);reader.onloadend=function(){parseImageData(reader.result);};function parseImageData(buffer){var header=new Uint8Array(buffer,0,16);var view=new DataView(buffer);if(header[0]===0x89&&header[1]===0x50&&header[2]===0x4e&&header[3]===0x47&&header[4]===0x0d&&header[5]===0x0a&&header[6]===0x1A&&header[7]===0x0a&&header[12]===0x49&&header[13]===0x48&&header[14]===0x44&&header[15]===0x52)
{try{success({type:PNG,width:view.getUint32(16,false),height:view.getUint32(20,false)});}
catch(ex){failure({error:ex.toString()});}}
else if(header[0]===0x47&&header[1]===0x49&&header[2]===0x46&&header[3]===0x38&&(header[4]===0x37||header[4]===0x39)&&header[5]===0x61)
{try{success({type:GIF,width:view.getUint16(6,true),height:view.getUint16(8,true)});}
catch(ex){failure({error:ex.toString()});}}
else if(header[0]===0x42&&header[1]===0x4D&&view.getUint32(2,true)===imageBlob.size)
{try{var width,height;if(view.getUint16(14,true)===12){width=view.getUint16(18,true);height=view.getUint16(20,true);}
else{width=view.getUint32(18,true);height=view.getUint32(22,true);}
success({type:BMP,width:width,height:height});}
catch(ex){failure({error:ex.toString()});}}
else if(header[0]===0xFF&&header[1]===0xD8){var value={type:JPEG};try{var offset=2;for(;;){if(view.getUint8(offset)!==0xFF){failure({error:'corrupt JPEG file'});}
var segmentType=view.getUint8(offset+1);var segmentSize=view.getUint16(offset+2)+2;if((segmentType>=0xC0&&segmentType<=0xC3)||(segmentType>=0xC5&&segmentType<=0xC7)||(segmentType>=0xC9&&segmentType<=0xCB)||(segmentType>=0xCD&&segmentType<=0xCF))
{value.height=view.getUint16(offset+5,false);value.width=view.getUint16(offset+7,false);success(value);break;}
offset+=segmentSize;if(offset+9>view.byteLength){value.error='corrupt JPEG file';failure(value);break;}}}
catch(ex){failure({error:ex.toString()});}}
else{failure({error:'unknown image type'});}}}};ImageUtils.resizeAndCropToCover=function(inputImageBlob,outputWidth,outputHeight,outputType,encoderOptions)
{if(!outputWidth||!isFinite(outputWidth)||outputWidth<=0||!outputHeight||!isFinite(outputHeight)||outputHeight<=0){return Promise.reject(new TypeError('invalid output dimensions'));}
outputWidth=Math.round(outputWidth);outputHeight=Math.round(outputHeight);return ImageUtils.getSizeAndType(inputImageBlob).then(function resolve(data){var inputWidth=data.width;var inputHeight=data.height;if(inputWidth===outputWidth&&inputHeight===outputHeight){return inputImageBlob;}
return resize(data);},function reject(error){return resize({});});function resize(data){var inputType=data.type;var inputWidth=data.width;var inputHeight=data.height;if(outputType&&outputType!==JPEG&&outputType!==PNG){console.warn('Ignoring unsupported outputType',outputType);outputType=undefined;}
if(!outputType){if(inputType===JPEG||inputType===PNG){outputType=inputType;}
else{outputType=PNG;}}
var url=URL.createObjectURL(inputImageBlob);var mediaFragment;if(inputType===JPEG&&inputWidth>outputWidth&&inputHeight>outputHeight){var reduction=Math.max(outputWidth/inputWidth,outputHeight/inputHeight);mediaFragment=ImageUtils.Downsample.sizeNoMoreThan(reduction);}
else{mediaFragment='';}
return new Promise(function(resolve,reject){var offscreenImage=new Image();offscreenImage.src=url+mediaFragment;offscreenImage.onerror=function(e){cleanupImage();reject('failed to decode image');};offscreenImage.onload=function(){var actualWidth=offscreenImage.width;var actualHeight=offscreenImage.height;var widthScale=outputWidth/actualWidth;var heightScale=outputHeight/actualHeight;var scale=Math.max(widthScale,heightScale);var cropWidth=Math.round(outputWidth/scale);var cropHeight=Math.round(outputHeight/scale);var cropLeft=Math.floor((actualWidth-cropWidth)/2);var cropTop=Math.floor((actualHeight-cropHeight)/2);var canvas=document.createElement('canvas');canvas.width=outputWidth;canvas.height=outputHeight;var context=canvas.getContext('2d',{willReadFrequently:true});context.drawImage(offscreenImage,cropLeft,cropTop,cropWidth,cropHeight,0,0,outputWidth,outputHeight);cleanupImage();canvas.toBlob(function(blob){canvas.width=0;resolve(blob);},outputType,encoderOptions);};function cleanupImage(){offscreenImage.onerror=offscreenImage.onload='';offscreenImage.onload=offscreenImage.onerror=null;offscreenImage.removeAttribute('src');URL.revokeObjectURL(url);}});}};(function(exports){'use strict';function round(x){return Math.round(x*100)/100;}
function MozSampleSize(n,scale){return Object.freeze({dimensionScale:round(scale),areaScale:round(scale*scale),toString:function(){return'#-moz-samplesize='+n;},scale:function(x){return Math.ceil(x*scale);}});}
var NONE=Object.freeze({dimensionScale:1,areaScale:1,toString:function(){return'';},scale:function(x){return x;}});var fragments=[NONE,MozSampleSize(2,1/2),MozSampleSize(3,3/8),MozSampleSize(4,1/4),MozSampleSize(8,1/8)];function sizeAtLeast(scale){scale=round(scale);for(var i=0;i<fragments.length;i++){var f=fragments[i];if(f.dimensionScale<=scale){return f;}}
return fragments[fragments.length-1];}
function sizeNoMoreThan(scale){scale=round(scale);for(var i=fragments.length-1;i>=0;i--){var f=fragments[i];if(f.dimensionScale>=scale){return f;}}
return NONE;}
function areaAtLeast(scale){scale=round(scale);for(var i=0;i<fragments.length;i++){var f=fragments[i];if(f.areaScale<=scale){return f;}}
return fragments[fragments.length-1];}
function areaNoMoreThan(scale){scale=round(scale);for(var i=fragments.length-1;i>=0;i--){var f=fragments[i];if(f.areaScale>=scale){return f;}}
return NONE;}
exports.Downsample={sizeAtLeast:sizeAtLeast,sizeNoMoreThan:sizeNoMoreThan,areaAtLeast:areaAtLeast,areaNoMoreThan:areaNoMoreThan,NONE:NONE,MAX_SIZE_REDUCTION:1/fragments[fragments.length-1].dimensionScale,MAX_AREA_REDUCTION:1/fragments[fragments.length-1].areaScale};}(exports.ImageUtils));})(window);;'use strict';(function(exports){if(exports.ForwardLock){return;}
const mimeSubtype='vnd.mozilla.oma.drm.fl';const SECRET_SETTINGS_ID='oma.drm.forward_lock.secret.key';var secret=null;function xor(buffer,key){var words=new Uint32Array(buffer,0,buffer.byteLength>>2);for(var i=0,n=words.length;i<n;i++){words[i]^=key;}}
function lockBuffer(secret,content,type,metadata){var header='LOCKED 1 '+escape(type)+'\n';if(metadata){for(var p in metadata){header+=escape(p)+':'+escape(metadata[p])+'\n';}}
header+='\0';var buffer=new Uint8Array(new Uint8Array(content)).buffer;xor(buffer,secret);return new Blob([header,buffer],{type:type.split('/')[0]+'/'+mimeSubtype});}
function lockBlob(secret,blob,metadata,callback){var reader=new FileReader();reader.readAsArrayBuffer(blob);reader.onload=function(){callback(lockBuffer(secret,reader.result,blob.type,metadata));};}
function unlockBlob(secret,blob,callback,errorCallback){if(!secret){return error('no secret supplied');}
var reader=new FileReader();reader.readAsArrayBuffer(blob);reader.onload=function(){var buffer=reader.result;var bytes=new Uint8Array(buffer);var header='';var contentStart;for(var i=0;i<bytes.length;i++){if(bytes[i]===0){contentStart=i+1;break;}
header+=String.fromCharCode(bytes[i]);}
if(!header.startsWith('LOCKED')){return error('Bad magic number');}
if(header.substring(6,9)!==' 1 '){return error('Unsupported version number');}
if(!contentStart){return error('No content');}
var eol=header.indexOf('\n');if(eol===-1){return error('malformed header');}
var type=unescape(header.substring(9,eol).trim());var metadata={};var lines=header.substring(eol+1).split('\n');for(var j=0;j<lines.length;j++){var line=lines[j];if(!line){continue;}
var[key,value]=line.split(':');if(!key||!value){return error('malformed metadata');}
metadata[unescape(key)]=unescape(value);}
var content=buffer.slice(contentStart);xor(content,secret);var blob=new Blob([content],{type:type});try{callback(blob,metadata);}
catch(e){console.error('Exception in content callback',e);}};function error(msg){msg='LCKA.decrypt(): '+msg;if(errorCallback){try{errorCallback(msg);}
catch(e){console.error('Exception in error callback',e);}}
else{console.error(msg);}}}
function getKey(callback){try{if(secret!==null){report(secret);return;}
var lock=navigator.mozSettings.createLock();var getreq=lock.get(SECRET_SETTINGS_ID);getreq.onsuccess=function(){secret=getreq.result[SECRET_SETTINGS_ID]||null;report(secret);};getreq.onerror=function(){console.error('Error getting ForwardLock setting',getreq.error);report(null);};}
catch(e){console.error('Exception in ForwardLock.getKey():',e);report(null);}
function report(secret){if(callback){try{callback(secret);}
catch(e){console.error('Exception in ForwardLock.getKey() callback',e);}}}}
function getOrCreateKey(callback){getKey(function(key){if(key!==null){report(key);return;}
secret=((Math.random()*0xFFFFFFFF)|0)+1;var setting={};setting[SECRET_SETTINGS_ID]=secret;var setreq=navigator.mozSettings.createLock().set(setting);setreq.onsuccess=function(){report(secret);};setreq.onerror=function(){console.error('Failed to set key in ForwardLock.getOrCreateKey()',setreq.error.name);secret=null;};});function report(secret){if(callback){try{callback(secret);}
catch(e){console.error('Exception in ForwardLock.getOrCreateKey() callback');}}}}
exports.ForwardLock={lockBuffer:lockBuffer,lockBlob:lockBlob,unlockBlob:unlockBlob,mimeSubtype:mimeSubtype,getKey:getKey,getOrCreateKey:getOrCreateKey};}(window));;(function(root,factory){'use strict';if(typeof define==='function'&&define.amd){define(factory);}else if(typeof exports==='object'){module.exports=factory();}else{root.Sanitizer=factory();}}(this,function(){'use strict';var Sanitizer={_entity:/[&<>"'/]/g,_entities:{'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;','\'':'&apos;','/':'&#x2F;'},getEntity:function(s){return Sanitizer._entities[s];},escapeHTML:function(strings,...values){var result='';for(var i=0;i<strings.length;i++){result+=strings[i];if(i<values.length){result+=String(values[i]).replace(Sanitizer._entity,Sanitizer.getEntity);}}
return result;},createSafeHTML:function(strings,...values){var escaped=Sanitizer.escapeHTML(strings,...values);return{__html:escaped,toString:function(){return'[object WrappedHTMLObject]';},info:'This is a wrapped HTML object. See https://developer.mozilla.or'+'g/en-US/Firefox_OS/Security/Security_Automation for more.'};},unwrapSafeHTML:function(...htmlObjects){var markupList=htmlObjects.map(function(obj){return obj.__html;});return markupList.join('');}};return Sanitizer;}));;(function(exports){'use strict';exports.ComponentUtils={style:function(baseUrl){if(window.VulpesCompat){window.VulpesCompat.componentStyle(this,baseUrl).catch(console.error);return;}var style=document.createElement('style');var url=baseUrl+'style.css';var self=this;style.setAttribute('scoped','');style.innerHTML='@import url('+url+');';this.appendChild(style);this.style.visibility='hidden';style.addEventListener('load',function(){if(self.shadowRoot){self.shadowRoot.appendChild(style.cloneNode(true));}
self.style.visibility='';});}};}(window));;'use strict';window.GaiaSubheader=(function(win){var proto=Object.create(HTMLElement.prototype);var baseurl=window.GaiaSubheaderBaseurl||'/shared/elements/gaia_subheader/';proto.createdCallback=function(){ComponentUtils.style.call(this,baseurl);};return document.registerElement('gaia-subheader',{prototype:proto});})(window);;;(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.GaiaHeader=f()}})(function(){var define,module,exports;return(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){;(function(define){define(function(require,exports,module){'use strict';var debug=0?console.log.bind(console):function(){};var cache={};var MIN=16;var MAX=24;var BUFFER=3;module.exports=function(config){debug('font fit',config);var space=config.space-BUFFER;var min=config.min||MIN;var max=config.max||MAX;var text=trim(config.text);var fontSize=max;var textWidth;var font;do{font=config.font.replace(/\d+px/,fontSize+'px');textWidth=getTextWidth(text,font);}while(textWidth>space&&fontSize!==min&&fontSize--);return{textWidth:textWidth,fontSize:fontSize,overflowing:textWidth>space};};function getTextWidth(text,font){var ctx=getCanvasContext(font);var width=ctx.measureText(text).width;debug('got text width',width);return width;}
function getCanvasContext(font){debug('get canvas context',font);var cached=cache[font];if(cached){return cached;}
var canvas=document.createElement('canvas');canvas.setAttribute('moz-opaque','true');canvas.setAttribute('width','1px');canvas.setAttribute('height','1px');debug('created canvas',canvas);var ctx=canvas.getContext('2d',{willReadFrequently:true});ctx.font=font;return cache[font]=ctx;}
function trim(text){return text.replace(/\s+/g,' ').trim();}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('font-fit',this));},{}],2:[function(require,module,exports){;(function(define){'use strict';define(function(require,exports,module){var textContent=Object.getOwnPropertyDescriptor(Node.prototype,'textContent');var innerHTML=Object.getOwnPropertyDescriptor(Element.prototype,'innerHTML');var removeAttribute=Element.prototype.removeAttribute;var setAttribute=Element.prototype.setAttribute;var noop=function(){};exports.register=function(name,props){var baseProto=getBaseProto(props.extends);var template=props.template||baseProto.templateString;var extensible=props.extensible=props.hasOwnProperty('extensible')?props.extensible:true;delete props.extends;if(template){if(extensible&&props.template){props.templateString=props.template;}
var output=processCss(template,name);props.template=document.createElement('template');props.template.innerHTML=output.template;props.lightCss=output.lightCss;props.globalCss=props.globalCss||'';props.globalCss+=output.globalCss;}
injectGlobalCss(props.globalCss);delete props.globalCss;var descriptors=mixin(props.attrs||{},base.descriptors);props._attrs=props.attrs;delete props.attrs;var proto=createProto(baseProto,props);Object.defineProperties(proto,descriptors);try{return document.registerElement(name,{prototype:proto});}catch(e){if(e.name!=='NotSupportedError'){throw e;}}};var base={properties:{GaiaComponent:true,attributeChanged:noop,attached:noop,detached:noop,created:noop,createdCallback:function(){if(this.dirObserver){addDirObserver();}
injectLightCss(this);this.created();},attributeChangedCallback:function(name,from,to){var prop=toCamelCase(name);if(this._attrs&&this._attrs[prop]){this[prop]=to;}
this.attributeChanged(name,from,to);},attachedCallback:function(){if(this.dirObserver){this.setInnerDirAttributes=setInnerDirAttributes.bind(null,this);document.addEventListener('dirchanged',this.setInnerDirAttributes);}
this.attached();},detachedCallback:function(){if(this.dirObserver){document.removeEventListener('dirchanged',this.setInnerDirAttributes);}
this.detached();},setupShadowRoot:function(){if(!this.template){return;}
var node=document.importNode(this.template.content,true);this.createShadowRoot().appendChild(node);if(this.dirObserver){setInnerDirAttributes(this);}
return this.shadowRoot;},setAttr:function(name,value){var internal=this.shadowRoot.firstElementChild;setAttribute.call(internal,name,value);setAttribute.call(this,name,value);},removeAttr:function(name){var internal=this.shadowRoot.firstElementChild;removeAttribute.call(internal,name);removeAttribute.call(this,name);}},descriptors:{textContent:{set:function(value){textContent.set.call(this,value);if(this.lightStyle){this.appendChild(this.lightStyle);}},get:function(){return textContent.get();}},innerHTML:{set:function(value){innerHTML.set.call(this,value);if(this.lightStyle){this.appendChild(this.lightStyle);}},get:innerHTML.get}}};var defaultPrototype=createProto(HTMLElement.prototype,base.properties);function getBaseProto(proto){if(!proto){return defaultPrototype;}
proto=proto.prototype||proto;return!proto.GaiaComponent?createProto(proto,base.properties):proto;}
function createProto(proto,props){return mixin(Object.create(proto),props);}
var hasShadowCSS=(function(){var div=document.createElement('div');try{div.querySelector(':host');div.querySelector('::content');return true;}
catch(e){return false;}})();var regex={shadowCss:/(?:\:host|\:\:content)[^{]*\{[^}]*\}/g,':host':/(?:\:host)/g,':host()':/\:host\((.+)\)(?: \:\:content)?/g,':host-context':/\:host-context\((.+)\)([^{,]+)?/g,'::content':/(?:\:\:content)/g};function processCss(template,name){var globalCss='';var lightCss='';if(!hasShadowCSS){template=template.replace(regex.shadowCss,function(match){var hostContext=regex[':host-context'].exec(match);if(hostContext){globalCss+=match.replace(regex['::content'],'').replace(regex[':host-context'],'$1 '+name+'$2').replace(/ +/g,' ');}else{lightCss+=match.replace(regex[':host()'],name+'$1').replace(regex[':host'],name).replace(regex['::content'],name);}
return'';});}
return{template:template,lightCss:lightCss,globalCss:globalCss};}
function injectGlobalCss(css){if(!css){return;}
var style=document.createElement('style');style.innerHTML=css.trim();headReady().then(function(){document.head.appendChild(style);});}
function headReady(){return new Promise(function(resolve){if(document.head){return resolve();}
window.addEventListener('load',function fn(){window.removeEventListener('load',fn);resolve();});});}
function injectLightCss(el){if(hasShadowCSS){return;}
var stylesheet=el.querySelector('style');if(!stylesheet){stylesheet=document.createElement('style');stylesheet.setAttribute('scoped','');stylesheet.appendChild(document.createTextNode(el.lightCss));el.appendChild(stylesheet);}
el.lightStyle=stylesheet;}
function toCamelCase(string){return string.replace(/-(.)/g,function replacer(string,p1){return p1.toUpperCase();});}
var dirObserver;function setInnerDirAttributes(component){var dir=component.dir||document.dir;Array.from(component.shadowRoot.children).forEach(element=>{if(element.nodeName!=='STYLE'){element.dir=dir;}});}
function addDirObserver(){if(dirObserver){return;}
dirObserver=new MutationObserver(onChanged);dirObserver.observe(document.documentElement,{attributeFilter:['dir'],attributes:true});function onChanged(mutations){document.dispatchEvent(new Event('dirchanged'));}}
function mixin(target,source){for(var key in source){target[key]=source[key];}
return target;}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-component',this));},{}],3:[function(require,module,exports){(function(define){'use strict';define(function(require,exports,module){var base=window.GAIA_ICONS_BASE_URL||window.COMPONENTS_BASE_URL||'bower_components/';if(!document.documentElement){window.addEventListener('load',load);}else{load();}
function load(){if(isLoaded()){return;}
var link=document.createElement('link');link.rel='stylesheet';link.type='text/css';link.href=base+'gaia-icons/gaia-icons.css';document.head.appendChild(link);exports.loaded=true;}
function isLoaded(){return exports.loaded||document.querySelector('link[href*=gaia-icons]')||document.documentElement.classList.contains('gaia-icons-loaded');}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-icons',this));},{}],4:[function(require,module,exports){;(function(define){'use strict';define(function(require,exports,module){var component=require('gaia-component');var fontFit=require('font-fit');require('gaia-icons');var debug=0?console.log.bind(console):function(){};const KNOWN_ACTIONS={menu:'menu',back:'back',close:'close'};const TITLE_FONT='italic 300 24px FiraSans';const TITLE_PADDING=10;const MINIMUM_FONT_SIZE_CENTERED=20;const MINIMUM_FONT_SIZE_UNCENTERED=16;const MAXIMUM_FONT_SIZE=23;module.exports=component.register('gaia-header',{extensible:false,dirObserver:true,created:function(){debug('created');this.setupShadowRoot();this.els={actionButton:this.shadowRoot.querySelector('.action-button'),titles:this.getElementsByTagName('h1')};this.els.actionButton.addEventListener('click',e=>this.onActionButtonClick(e));this.observer=new MutationObserver(this.onMutation.bind(this));this.ignoreDir=this.hasAttribute('ignore-dir');this.titleEnd=this.getAttribute('title-end');this.titleStart=this.getAttribute('title-start');this.noFontFit=this.getAttribute('no-font-fit');this.notFlush=this.hasAttribute('not-flush');this.action=this.getAttribute('action');this.unresolved={};this.pending={};this._resizeThrottlingId=null;this.onResize=this.onResize.bind(this);},attached:function(){debug('attached');this.runFontFitSoon();this.observerStart();window.addEventListener('resize',this.onResize);},detached:function(){debug('detached');window.removeEventListener('resize',this.onResize);this.observerStop();this.clearPending();},clearPending:function(){for(var key in this.pending){this.pending[key].clear();delete this.pending[key];}
window.cancelAnimationFrame(this._resizeThrottlingId);this._resizeThrottlingId=null;},runFontFit:function(){debug('run font-fit');if(this.noFontFit){return Promise.resolve();}
var titles=this.els.titles;var space=this.getTitleSpace();var styles=[].map.call(titles,el=>this.getTitleStyle(el,space));return this.setTitleStylesSoon(styles);},runFontFitSoon:function(){debug('run font-fit soon');if(this.pending.runFontFitSoon){return;}
this.pending.runFontFitSoon=this.nextTick(()=>{delete this.pending.runFontFitSoon;this.runFontFit();});},getTitleStyle:function(el,space){debug('get el style',el,space);var text=el.textContent;var styleId=space.start+text+space.end+'#'+space.value;if(!text||!text.trim()){return debug('exit: no text');}
if(getStyleId(el)===styleId){return debug('exit: no change');}
var marginStart=this.getTitleMarginStart();var textSpace=space.value-Math.abs(marginStart);var fontFitResult=this.fontFit(text,textSpace,{min:MINIMUM_FONT_SIZE_CENTERED});var overflowing=fontFitResult.overflowing;var padding={start:0,end:0};if(overflowing){debug('title overflowing');padding.start=!space.start?TITLE_PADDING:0;padding.end=!space.end?TITLE_PADDING:0;textSpace=space.value-padding.start-padding.end;fontFitResult=this.fontFit(text,textSpace);marginStart=0;}
return{id:styleId,fontSize:fontFitResult.fontSize,marginStart:marginStart,overflowing:overflowing,padding:padding};},setTitleStylesSoon:function(styles){debug('set title styles soon',styles);var key='setStyleTitlesSoon';this._titleStyles=styles;if(this.unresolved[key]){return this.unresolved[key];}
this.unresolved[key]=new Promise((resolve)=>{this.pending[key]=this.nextTick(()=>{var styles=this._titleStyles;var els=this.els.titles;[].forEach.call(els,(el,i)=>{if(!styles[i]){return debug('exit');}
this.setTitleStyle(el,styles[i]);});delete this._titleStyles;delete this.unresolved[key];delete this.pending[key];resolve();});});},setTitleStyle:function(el,style){debug('set title style',style);this.observerStop();if(this.ignoreDir){el.style.marginLeft=style.marginStart+'px';el.style.paddingLeft=style.padding.start+'px';el.style.paddingRight=style.padding.end+'px';}else{el.style.marginInlineStart=style.marginStart+'px';el.style.paddingInlineStart=style.padding.start+'px';el.style.paddingInlineEnd=style.padding.end+'px';}
el.style.fontSize=style.fontSize+'px';setStyleId(el,style.id);this.observerStart();},fontFit:function(text,space,opts={}){debug('font fit:',text,space,opts);var fontFitArgs={font:TITLE_FONT,min:opts.min||MINIMUM_FONT_SIZE_UNCENTERED,max:MAXIMUM_FONT_SIZE,text:text,space:space};return fontFit(fontFitArgs);},observerStart:function(){if(this.observing){return;}
this.observer.observe(this,{childList:true,attributes:true,subtree:true});this.observing=true;debug('observer started');},observerStop:function(){if(!this.observing){return;}
this.observer.disconnect();this.observing=false;debug('observer stopped');},onResize:function(e){debug('onResize',this._resizeThrottlingId);if(this._resizeThrottlingId!==null){return;}
this._resizeThrottlingId=window.requestAnimationFrame(()=>{this._resizeThrottlingId=null;this.runFontFitSoon();});},onMutation:function(mutations){debug('on mutation',mutations);if(!this.pending.runFontFitSoon){this.runFontFit();}},getTitleSpace:function(){var start=this.titleStart;var end=this.titleEnd;var space=this.getWidth()-start-end;var result={value:space,start:start,end:end};debug('get title space',result);return result;},getWidth:function(){var value=this.notFlush?this.clientWidth:window.innerWidth;debug('get width',value);return value;},triggerAction:function(){if(this.action){this.els.actionButton.click();}},onActionButtonClick:function(){debug('action button click');var config={detail:{type:this.action}};var e=new CustomEvent('action',config);setTimeout(()=>this.dispatchEvent(e));},getTitleMarginStart:function(){var start=this.titleStart;var end=this.titleEnd;var marginStart=end-start;debug('get title margin start',marginStart);return marginStart;},getButtonsBeforeTitle:function(){var children=this.children;var l=children.length;var els=[];for(var i=0;i<l;i++){var el=children[i];if(el.tagName==='H1'){break;}
if(!contributesToLayout(el)){continue;}
els.push(el);}
if(this.action){els.push(this.els.actionButton);}
return els;},getButtonsAfterTitle:function(){var children=this.children;var els=[];for(var i=children.length-1;i>=0;i--){var el=children[i];if(el.tagName==='H1'){break;}
if(!contributesToLayout(el)){continue;}
els.push(el);}
return els;},sumButtonWidths:function(buttons){var defaultWidth=50;var sum=buttons.reduce((prev,button)=>{var isStandardButton=button===this.els.actionButton;var width=isStandardButton?defaultWidth:button.clientWidth;return prev+width;},0);debug('sum button widths',buttons,sum);return sum;},attrs:{action:{get:function(){return this._action;},set:function(value){var action=KNOWN_ACTIONS[value];if(action===this._action){return;}
this.setAttr('action',action);this._action=action;}},titleStart:{get:function(){debug('get title-start');if('_titleStart'in this){return this._titleStart;}
var buttons=this.getButtonsBeforeTitle();var value=this.sumButtonWidths(buttons);debug('get title-start',buttons,value);return value;},set:function(value){debug('set title-start',value);value=parseInt(value,10);if(value===this._titleStart||isNaN(value)){return;}
this.setAttr('title-start',value);this._titleStart=value;debug('set');}},titleEnd:{get:function(){debug('get title-end');if('_titleEnd'in this){return this._titleEnd;}
var buttons=this.getButtonsAfterTitle();return this.sumButtonWidths(buttons);},set:function(value){debug('set title-end',value);value=parseInt(value,10);if(value===this._titleEnd||isNaN(value)){return;}
this.setAttr('title-end',value);this._titleEnd=value;}},noFontFit:{get:function(){return this._noFontFit||false;},set:function(value){debug('set no-font-fit',value);value=!!(value||value==='');if(value===this.noFontFit){return;}
this._noFontFit=value;if(value){this.setAttr('no-font-fit','');}
else{this.removeAttr('no-font-fit');}}},ignoreDir:{get:function(){return this._ignoreDir||false;},set:function(value){debug('set ignore-dir',value);value=!!(value||value==='');if(value===this.ignoreDir){return;}
this._ignoreDir=value;this.dirObserver=!value;if(value){this.setAttr('ignore-dir','');}
else{this.removeAttr('ignore-dir');}}}},template:`<div class="inner">
<button class="action-button">
<content select="[l10n-action]"></content>
</button>
<content></content>
</div>
<style>
:host {
display: block;
-moz-user-select: none;
--gaia-header-button-color:
var(--header-button-color,
var(--header-color,
var(--link-color,
inherit)));
}
/**
* [hidden]
*/
:host[hidden] {
display: none;
}
/** Reset
---------------------------------------------------------*/
::-moz-focus-inner { border: 0; }
/** Inner
---------------------------------------------------------*/
.inner {
display: flex;
min-height: 50px;
-moz-user-select: none;
background:
var(--header-background,
var(--background,
#fff));
}
/** Action Button
---------------------------------------------------------*/
/**
* 1. Hidden by default
*/
.action-button {
position: relative;
display: none; /* 1 */
width: 50px;
font-size: 30px;
margin: 0;
padding: 0;
border: 0;
outline: 0;
align-items: center;
background: none;
cursor: pointer;
transition: opacity 200ms 280ms;
color:
var(--header-action-button-color,
var(--header-icon-color,
var(--gaia-header-button-color)));
}
/**
* [action=back]
* [action=menu]
* [action=close]
*
* 1. For icon vertical-alignment
*/
[action=back] .action-button,
[action=menu] .action-button,
[action=close] .action-button {
display: flex; /* 1 */
}
/**
* :active
*/
.action-button:active {
transition: none;
opacity: 0.2;
}
/** Action Button Icon
---------------------------------------------------------*/
.action-button:before {
font-family: 'gaia-icons';
font-style: normal;
text-rendering: optimizeLegibility;
font-weight: 500;
}
[action=close] .action-button:before { content: 'close' }
[action=menu] .action-button:before { content: 'menu' }
[action=back]:-moz-dir(ltr) .action-button:before { content: 'left' }
[action=back]:-moz-dir(rtl) .action-button:before { content: 'right' }
/** Action Button Icon
---------------------------------------------------------*/
/**
* 1. To enable vertical alignment.
*/
.action-button:before {
display: block;
}
/** Action Button Text
---------------------------------------------------------*/
/**
* To provide custom localized content for
* the action-button, we allow the user
* to provide an element with the class
* .l10n-action. This node is then
* pulled inside the real action-button.
*
* Example:
*
* <gaia-header action="back">
* <span l10n-action aria-label="Back">Localized text</span>
* <h1>title</h1>
* </gaia-header>
*/
::content [l10n-action] {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
font-size: 0;
}
/** Title
---------------------------------------------------------*/
/**
* 1. Vertically center text. We can't use flexbox
* here as it breaks text-overflow ellipsis
* without an inner div.
*/
::content h1 {
flex: 1;
margin: 0;
padding: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: center;
line-height: 50px; /* 1 */
font-weight: 300;
font-style: italic;
font-size: 24px;
color:
var(--header-title-color,
var(--header-color,
var(--title-color,
var(--text-color,
inherit))));
}
/**
* [ignore-dir]
*
* When the <gaia-header> component has an [ignore-dir] attribute, header
* direction is forced to LTR but we still want the <h1> text to be reversed
* so that strings like '1 selected' become 'selected 1'.
*
* When we're happy for <gaia-header> to be fully RTL responsive we won't need
* these rules anymore, but this depends on all Gaia apps being ready.
*
* This should be safe to remove when bug 1179459 lands.
*/
:host[ignore-dir] {
direction: ltr;
}
:host[ignore-dir]:-moz-dir(rtl) h1 {
direction: rtl;
}
/** Buttons
---------------------------------------------------------*/
::content a,
::content button {
position: relative;
z-index: 1;
box-sizing: border-box;
display: flex;
width: auto;
height: auto;
min-width: 50px;
margin: 0;
padding: 0 10px;
outline: 0;
border: 0;
font-size: 14px;
line-height: 1;
align-items: center;
justify-content: center;
text-decoration: none;
text-align: center;
background: none;
border-radius: 0;
font-style: italic;
cursor: pointer;
transition: opacity 200ms 280ms;
color: var(--gaia-header-button-color);
}
/**
* :active
*/
::content a:active,
::content button:active {
transition: none;
opacity: 0.2;
}
/**
* [hidden]
*/
::content a[hidden],
::content button[hidden] {
display: none;
}
/**
* [disabled]
*/
::content a[disabled],
::content button[disabled] {
pointer-events: none;
color: var(--header-disabled-button-color);
}
/** Icon Buttons
---------------------------------------------------------*/
/**
* Icons are a different color to text
*/
::content .icon,
::content [data-icon] {
color:
var(--header-icon-color,
var(--gaia-header-button-color));
}
/**
* If users want their action button
* to be in the component's light-dom
* they can add an .action class
* to make it look like the
* shadow action button.
*/
::content .action {
color:
var(--header-action-button-color,
var(--header-icon-color,
var(--gaia-header-button-color)));
}
/**
* [data-icon]:empty
*
* Icon buttons with no textContent,
* should always be 50px.
*
* This is to prevent buttons being
* larger than they should be before
* icon-font has loaded.
*/
::content [data-icon]:empty {
width: 50px;
}
</style>`,nextTick:nextTick});function contributesToLayout(el){return el.localName!=='style'&&!el.hasAttribute('l10n-action');}
function setStyleId(el,id){el._styleId=id;}
function getStyleId(el){return el._styleId;}
function nextTick(fn){var cleared;Promise.resolve().then(()=>{if(!cleared){fn();}});return{clear:function(){cleared=true;}};}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-header',this));},{"font-fit":1,"gaia-component":2,"gaia-icons":3}]},{},[4])(4)});;;'use strict';function formatTime(secs){if(isNaN(secs)){return;}
secs=Math.floor(secs);var formatedTime;var seconds=secs%60;var minutes=Math.floor(secs/60)%60;var hours=Math.floor(secs/3600);if(hours===0){formatedTime=(minutes<10?'0'+minutes:minutes)+':'+
(seconds<10?'0'+seconds:seconds);}else{formatedTime=(hours<10?'0'+hours:hours)+':'+
(minutes<10?'0'+minutes:minutes)+':'+
(seconds<10?'0'+seconds:seconds);}
return formatedTime;}
function createListElement(option,data,index,highlight){var li=document.createElement('li');li.className='list-item';li.setAttribute('role','presentation');var a=document.createElement('a');a.dataset.index=index;a.dataset.option=option;a.setAttribute('role','option');var titleBdi;li.appendChild(a);function highlightText(result,text){var textContent=result.textContent;var textLowerCased=textContent.toLocaleLowerCase();var index=Normalizer.toAscii(textLowerCased).indexOf(text);if(index>=0){var innerHTML=Sanitizer.createSafeHTML`
${textContent.substring(0, index)}
<span class="search-highlight">
${textContent.substring(index, index + text.length)}
</span>
${textContent.substring(index + text.length)}`;result.innerHTML=Sanitizer.unwrapSafeHTML(innerHTML);}}
switch(option){case'playlist':titleBdi=document.createElement('bdi');titleBdi.className='list-playlist-title';if(data.metadata.l10nId){titleBdi.textContent=navigator.mozL10n.get(data.metadata.l10nId);titleBdi.dataset.l10nId=data.metadata.l10nId;}else{titleBdi.textContent=data.metadata.title||navigator.mozL10n.get('unknownTitle');titleBdi.dataset.l10nId=data.metadata.title?'':'unknownTitle';}
a.dataset.keyRange='all';a.dataset.option=data.option;a.appendChild(titleBdi);if(index===0){var shuffleIcon=document.createElement('div');shuffleIcon.className='list-playlist-icon';shuffleIcon.dataset.icon='shuffle';shuffleIcon.setAttribute('data-l10n-id','shuffle-toggle');a.appendChild(shuffleIcon);}
break;case'artist':case'album':case'title':var artistBdi;var albumImg;albumImg=document.createElement('img');albumImg.className='list-album-art';li.appendChild(albumImg);LazyLoader.load('js/metadata/album_art_cache.js').then(()=>{return AlbumArtCache.getThumbnailURL(data);}).then((url)=>{showImage(albumImg,url);});if(option==='artist'){artistBdi=document.createElement('bdi');artistBdi.className='list-single-title';artistBdi.textContent=data.metadata.artist||navigator.mozL10n.get('unknownArtist');artistBdi.dataset.l10nId=data.metadata.artist?'':'unknownArtist';if(highlight){highlightText(artistBdi,highlight);}
a.appendChild(artistBdi);}else{var albumOrTitleBdi=document.createElement('bdi');artistBdi=document.createElement('bdi');albumOrTitleBdi.className='list-main-title';artistBdi.className='list-sub-title';if(option==='album'){albumOrTitleBdi.textContent=data.metadata.album||navigator.mozL10n.get('unknownAlbum');albumOrTitleBdi.dataset.l10nId=data.metadata.album?'':'unknownAlbum';}else{albumOrTitleBdi.textContent=data.metadata.title||navigator.mozL10n.get('unknownTitle');albumOrTitleBdi.dataset.l10nId=data.metadata.title?'':'unknownTitle';}
artistBdi.textContent=data.metadata.artist||navigator.mozL10n.get('unknownArtist');artistBdi.dataset.l10nId=data.metadata.artist?'':'unknownArtist';if(highlight){highlightText(albumOrTitleBdi,highlight);}
a.appendChild(albumOrTitleBdi);a.appendChild(artistBdi);}
a.dataset.keyRange=data.metadata[option];a.dataset.option=option;break;case'song':case'song-index':var songTitle=data.metadata.title||navigator.mozL10n.get('unknownTitle');var indexBdi=document.createElement('bdi');indexBdi.className='list-song-index';if(option==='song-index'){indexBdi.textContent=index+1;}else{var trackNum=data.metadata.tracknum;if(data.metadata.discnum&&data.multidisc){trackNum=data.metadata.discnum+'.'+
(trackNum<10?'0'+trackNum:trackNum);}
indexBdi.textContent=trackNum;}
titleBdi=document.createElement('bdi');titleBdi.className='list-song-title';titleBdi.textContent=songTitle;titleBdi.dataset.l10nId=data.metadata.title?'':'unknownTitle';var lengthBdi=document.createElement('bdi');lengthBdi.className='list-song-length';a.appendChild(indexBdi);a.appendChild(titleBdi);a.appendChild(lengthBdi);break;}
return li;}
function showImage(image,url,option){image.classList.remove(option);image.src='';if(option==='fadeIn'){image.style.opacity=0;}
image.addEventListener('load',handler);function handler(evt){evt.target.removeEventListener('load',handler);image.classList.add(option);}
image.src=url;};'use strict';var App=(function(){var app;var chromeInteractive=false;init();function init(){navigator.mozL10n.once(function onLocalizationInit(){window.performance.mark('navigationLoaded');Database.init();TitleBar.init();TabBar.init();setStartMode();navigator.mozL10n.ready(function(){ModeManager.updateTitle();if(!chromeInteractive){chromeInteractive=true;window.performance.mark('navigationInteractive');}});});}
function setStartMode(){if(document.URL.indexOf('#pick')!==-1){navigator.mozSetMessageHandler('activity',function activityHandler(a){var activityName=a.source.name;if(activityName==='pick'){document.body.classList.add('picker-mode');app.pendingPick=a;document.getElementById('overlay-cancel-button').addEventListener('click',function(){if(App.pendingPick){App.pendingPick.postError('pick cancelled');}});}
TabBar.option='title';ModeManager.start(MODE_PICKER);});}else{TitleBar.doneButton.parentNode.removeChild(TitleBar.doneButton);TabBar.option='mix';ModeManager.start(MODE_TILES);}}
function showOverlay(id){document.activeElement.blur();app.currentOverlay=id;function setVisibility(visible){Array.forEach(document.body.children,function(elt){if(elt.id==='overlay'){elt.classList.toggle('hidden',!visible);}else{elt.setAttribute('aria-hidden',visible);}});}
if(id===null){setVisibility(false);return;}
var menu=document.getElementById('overlay-menu');if(app.pendingPick){menu.classList.remove('hidden');}else{menu.classList.add('hidden');}
var l10nIds={'title':id+'-title','text':id+'-text'};if(id==='nocard'){l10nIds.title='nocard2-title';l10nIds.text='nocard3-text';}
var titleElement=document.getElementById('overlay-title');var textElement=document.getElementById('overlay-text');titleElement.dataset.l10nId=l10nIds.title;textElement.dataset.l10nId=l10nIds.text;setVisibility(true);}
function showCorrectOverlay(){if(app.knownSongs.length>0){if(app.currentOverlay==='empty'||app.currentOverlay==='upgrade'){app.showOverlay(null);}}else{app.showOverlay('empty');}}
function dbEnumerable(callback){if(app.currentOverlay==='upgrade'){app.showOverlay(null);}
refreshViews(function(){window.performance.mark('visuallyLoaded');window.performance.mark('contentInteractive');TitleBar.view.removeAttribute('no-font-fit');document.getElementById('spinner').classList.add('hidden');setTimeout(function(){document.getElementById('spinner-overlay').classList.add('hidden');},100);if(document.URL.indexOf('#pick')===-1){setupCommunications();}
if(callback){callback();}});}
function setupCommunications(){var files=['shared/js/bluetooth_helper.js','shared/js/media/remote_controls.js','js/communications.js',];LazyLoader.load(files).then(()=>{MusicComms.init();});}
function dbReady(refresh,callback){if(app.currentOverlay==='nocard'||app.currentOverlay==='pluggedin'){app.showOverlay(null);}
if(refresh){refreshViews(callback);}else if(callback){callback();}}
function dbUnavailable(why){if(typeof PlayerView!=='undefined'){PlayerView.stop();}
if(!app.pendingPick){TabBar.option='mix';ModeManager.start(MODE_TILES,function(){TilesView.hideSearch();});}
if(why==='nocard'){app.showOverlay('nocard');}else if(why==='unmounted'){app.showOverlay('pluggedin');}}
var hidSearchBox=false;function refreshViews(callback){function showListView(){var option=TabBar.option;var info={key:'metadata.'+option,range:null,direction:(option==='title')?'next':'nextunique',option:option};ModeManager.waitForView(MODE_PICKER,()=>{ListView.activate(info);});}
if(app.pendingPick){showListView();if(callback){callback();}
return;}
if(ModeManager.currentMode===MODE_LIST&&TabBar.option!=='playlist'){showListView();}
ModeManager.waitForView(MODE_TILES,()=>{TilesView.activate(function(songs){TabBar.setDisabled(!songs.length);app.knownSongs=songs;app.showCorrectOverlay();if(app.currentOverlay===null&&!hidSearchBox){hidSearchBox=true;window.setTimeout(function(){TilesView.hideSearch();},1000);}
if(callback){callback();}});});}
app={pendingPick:null,currentOverlay:null,knownSongs:[],showOverlay:showOverlay,showCorrectOverlay:showCorrectOverlay,dbEnumerable:dbEnumerable,dbReady:dbReady,dbUnavailable:dbUnavailable,refreshViews:refreshViews};return app;})();;'use strict';var Database=(function(){var musicdb;function init(){var excludedFolders=['Ringtones','Notifications','Alarms'];var excludeFilter=new RegExp('^(/[^/]*/)?('+excludedFolders.join('|')+')/','i');musicdb=new MediaDB('music',metadataParserWrapper,{indexes:['metadata.album','metadata.artist','metadata.title','metadata.rated','metadata.played','date'],excludeFilter:excludeFilter,batchSize:1,autoscan:false,updateRecord:updateRecord,reparsedRecord:reparsedRecord,version:3});function metadataParserWrapper(file,onsuccess,onerror){var files=['/js/metadata_scripts.js','/js/metadata/album_art.js'];LazyLoader.load(files).then(()=>{return AudioMetadata.parse(file);}).then((metadata)=>{return AlbumArt.process(file,metadata);}).then(onsuccess,onerror);}
var startedReparsing=false;function updateRecord(record,oldVersion,newVersion){if(oldVersion===2){record.needsReparse=true;if(!startedReparsing){startedReparsing=true;App.showOverlay('upgrade');}}
return record.metadata;}
function reparsedRecord(oldMetadata,newMetadata){newMetadata.rated=oldMetadata.rated;newMetadata.played=oldMetadata.played;return newMetadata;}
musicdb.onupgrading=function(event){App.showOverlay('upgrade');};musicdb.onunavailable=function(event){var why;switch(event.detail){case MediaDB.NOCARD:why='nocard';break;case MediaDB.UNMOUNTED:why='unmounted';break;}
App.dbUnavailable(why);};musicdb.oncardremoved=function(){App.dbUnavailable('cardremoved');};musicdb.onenumerable=startupOnEnumerable;var refreshOnReady=false;function startupOnEnumerable(){App.dbEnumerable(function(){if(musicdb.state===MediaDB.READY){onReady();}else{musicdb.onready=onReady;}});}
function onReady(){App.dbReady(refreshOnReady,function(){musicdb.scan();});refreshOnReady=true;}
var filesDeletedWhileScanning=0;var filesFoundWhileScanning=0;var filesFoundBatch=0;var scanning=false;var SCAN_UPDATE_BATCH_SIZE=25;var DELETE_BATCH_TIMEOUT=500;var deleteTimer=null;var firstScanDone=false;musicdb.onscanstart=function(){scanning=true;filesFoundWhileScanning=0;filesFoundBatch=0;filesDeletedWhileScanning=0;};musicdb.onscanend=function(){scanning=false;TitleBar.hideScanProgress();if(filesFoundBatch>0||filesDeletedWhileScanning>0){filesFoundWhileScanning=0;filesFoundBatch=0;filesDeletedWhileScanning=0;App.refreshViews();}
if(!firstScanDone){firstScanDone=true;window.performance.mark('fullyLoaded');}};musicdb.oncreated=function(event){if(scanning){var metadata=event.detail[0].metadata;var n=event.detail.length;filesFoundWhileScanning+=n;filesFoundBatch+=n;TitleBar.showScanProgress({count:filesFoundWhileScanning,artist:metadata.artist,title:metadata.title});if(filesFoundBatch>SCAN_UPDATE_BATCH_SIZE){filesFoundBatch=0;App.refreshViews();}}
else{App.refreshViews();}};musicdb.ondeleted=function(event){if(scanning){filesDeletedWhileScanning+=event.detail.length;}
else{if(deleteTimer){clearTimeout(deleteTimer);}
deleteTimer=setTimeout(function(){deleteTimer=null;App.refreshViews();},DELETE_BATCH_TIMEOUT);}};}
function incrementPlayCount(fileinfo){fileinfo.metadata.played++;musicdb.updateMetadata(fileinfo.name,{played:fileinfo.metadata.played});}
function setSongRating(fileinfo,rated){fileinfo.metadata.rated=rated;musicdb.updateMetadata(fileinfo.name,{rated:fileinfo.metadata.rated});}
function getFile(fileinfo,decrypt=false){return new Promise((resolve,reject)=>{musicdb.getFile(fileinfo.name,(file)=>{if(file){resolve(file);}else{reject('unable to get file: '+fileinfo.name);}});}).then((blob)=>{if(!decrypt||!fileinfo.metadata.locked){return blob;}
return new Promise(function(resolve,reject){ForwardLock.getKey(function(secret){ForwardLock.unlockBlob(secret,blob,resolve,null,reject);});});});}
function enumerate(...args){return musicdb.enumerate(...args);}
function enumerateAll(...args){return musicdb.enumerateAll(...args);}
function advancedEnumerate(...args){return musicdb.advancedEnumerate(...args);}
function count(...args){return musicdb.count(...args);}
function search(key,query,callback){query=Normalizer.toAscii(query.toLocaleLowerCase());var direction=(key==='title')?'next':'nextunique';return musicdb.enumerate('metadata.'+key,null,direction,(result)=>{if(result===null){callback(result);return;}
var resultLowerCased=result.metadata[key].toLocaleLowerCase();if(Normalizer.toAscii(resultLowerCased).indexOf(query)!==-1){callback(result);}});}
function cancelEnumeration(handle){musicdb.cancelEnumeration(handle);}
return{init:init,incrementPlayCount:incrementPlayCount,setSongRating:setSongRating,getFile:getFile,enumerate:enumerate,enumerateAll:enumerateAll,advancedEnumerate:advancedEnumerate,count:count,search:search,cancelEnumeration:cancelEnumeration,get initialScanComplete(){return musicdb.initialScanComplete;}};})();;'use strict';var TitleBar={get view(){return document.getElementById('title');},get titleText(){return document.querySelector('#title-text bdi');},get playerIcon(){return document.getElementById('title-player');},get doneButton(){return document.getElementById('title-done');},get scanProgress(){return document.getElementById('scan-progress');},get scanSpinner(){return document.getElementById('scan-spinner');},get scanCount(){return document.getElementById('scan-count');},get scanArtist(){return document.getElementById('scan-artist');},get scanTitle(){return document.getElementById('scan-title');},init:function tb_init(){this.view.addEventListener('click',this);this.view.addEventListener('action',this.onActionBack);},changeTitleText:function tb_changeTitleText(content){this.titleText.textContent=content;},showBackArrow:function(show){if(show){this.view.setAttribute('action','back');}
else{this.view.removeAttribute('action');}},onActionBack:function(){if(App.pendingPick){if(ModeManager.currentMode===MODE_PICKER){App.pendingPick.postError('pick cancelled');return;}
PlayerView.stop();}
ModeManager.pop();},showScanProgress:function(info){this.scanProgress.classList.remove('hidden');this.scanSpinner.classList.remove('hidden');this.scanCount.textContent=info.count;this.scanArtist.textContent=info.artist||'';this.scanTitle.textContent=info.title||'';},hideScanProgress:function(){this.scanSpinner.classList.add('hidden');setTimeout(function(){this.scanProgress.classList.add('hidden');}.bind(this),100);},handleEvent:function tb_handleEvent(evt){var target=evt.target;function cleanupPick(){PlayerView.stop();}
switch(evt.type){case'click':if(!target){return;}
switch(target.id){case'title-player':if(PlayerView.isQueued){ModeManager.push(MODE_PLAYER);}
break;case'title-done':var currentFileInfo=PlayerView.currentFileInfo;LazyLoader.load('js/metadata/album_art_cache.js').then(()=>{return AlbumArtCache.getThumbnailBlob(currentFileInfo);}).then((picture)=>{var currentMetadata=currentFileInfo.metadata;var playingBlob=PlayerView.playingBlob;App.pendingPick.postResult({type:playingBlob.type,blob:playingBlob,name:currentMetadata.title||'',metadata:{title:currentMetadata.title,artist:currentMetadata.artist,album:currentMetadata.album,picture:picture}});cleanupPick();});break;}
break;default:return;}}};;'use strict';var TabBar={playlistArray:[{metadata:{l10nId:'playlists-shuffle-all'},option:'shuffleAll'},{metadata:{l10nId:'playlists-highest-rated'},option:'rated'},{metadata:{l10nId:'playlists-recently-added'},option:'date'},{metadata:{l10nId:'playlists-most-played'},option:'played'},{metadata:{l10nId:'playlists-least-played'},option:'played'},null],get view(){return document.getElementById('tabs');},get tabs(){return this.view.querySelectorAll('[role="tab"]');},set option(choice){var map={'mix':'tabs-mix','playlist':'tabs-playlists','artist':'tabs-artists','album':'tabs-albums','title':'tabs-songs'};var tab=document.getElementById(map[choice]);AccessibilityHelper.setAriaSelected(tab,this.tabs);this._option=choice;},get option(){return this._option;},init:function tab_init(){this.option='mix';this.view.addEventListener('touchend',this);},setDisabled:function tab_setDisabled(option){this.disabled=option;},handleEvent:function tab_handleEvent(evt){if(this.disabled){return;}
switch(evt.type){case'touchend':var target=evt.target;if(!target){return;}
if(this.option===target.dataset.option){return;}else{this.option=target.dataset.option;}
switch(target.id){case'tabs-mix':ListView.cancelEnumeration();ModeManager.start(MODE_TILES);TilesView.hideSearch();break;case'tabs-playlists':ModeManager.start(MODE_LIST,function(){ListView.activate();this.playlistArray.forEach(function(playlist){ListView.update(this.option,playlist);}.bind(this));}.bind(this));break;case'tabs-artists':case'tabs-albums':case'tabs-songs':var info={key:'metadata.'+this.option,range:null,direction:(this.option==='title')?'next':'nextunique',option:this.option};ModeManager.start(MODE_LIST,function(){ListView.activate(info);});break;}
break;default:return;}}};;'use strict';var MODE_TILES=1;var MODE_LIST=2;var MODE_SUBLIST=3;var MODE_PLAYER=4;var MODE_SEARCH_FROM_TILES=5;var MODE_SEARCH_FROM_LIST=6;var MODE_PICKER=7;var ModeManager={views:{1:{id:'views-tiles',paths:['js/ui/views/tiles_view.js']},2:{id:'views-list',paths:['js/ui/views/list_view.js']},3:{id:'views-sublist',paths:['js/ui/views/subList_view.js']},4:{id:'views-player',paths:['js/ui/views/player_view.js','js/queue.js']},5:{id:'views-search',paths:['js/ui/views/search_view.js','shared/js/text_normalizer.js']},6:{id:'views-search',paths:['js/ui/views/search_view.js','shared/js/text_normalizer.js']},7:{id:'views-list',paths:['js/ui/views/list_view.js']}},_modeStack:[],playerTitle:null,get currentMode(){return this._modeStack[this._modeStack.length-1];},get previousMode(){return this._modeStack[this._modeStack.length-2];},start:function(mode,callback){this._modeStack=[];this._resetViews();this._pushMode(mode,false,function(){this._modeStack=[mode];this._updateMode(callback);}.bind(this));},push:function(mode,callback){this._pushMode(mode,true,function(){this._modeStack.push(mode);this._updateMode(callback);}.bind(this));},pop:function(){if(this._modeStack.length<=1){return;}
this._popMode();this._modeStack.pop();this._updateMode();},_resetViews:function(){for(var mode in this.views){var sheet=document.getElementById(this.views[mode].id);sheet.classList.remove('animated');sheet.classList.remove('current');sheet.classList.add('next');}},waitForView:function(mode,callback){var view=this.views[mode];if(view.isLoaded){if(callback){callback(view);return;}}
LazyLoader.load(view.paths).then(()=>{if(view.isLoaded){return;}
var sheet=document.getElementById(view.id);sheet.classList.remove('hidden');switch(view.id){case'views-tiles':TilesView.init();break;case'views-list':ListView.init();break;case'views-sublist':SubListView.init();break;case'views-player':if(App.pendingPick){PlayerView.init(TYPE_SINGLE,false);}else{PlayerView.init(TYPE_LIST);}
break;case'views-search':SearchView.init();break;}
if(view.id==='views-player'){return PlaybackQueue.loadSettings();}}).then(()=>{view.isLoaded=true;if(callback){callback(view);}});},_pushMode:function(mode,animated,callback){this.waitForView(mode,(view)=>{var nextId=view.id;var currentId=this.currentMode?this.views[this.currentMode].id:null;var nextSheet=document.getElementById(nextId);var currentSheet=document.getElementById(currentId);if(nextSheet){nextSheet.classList.toggle('animated',animated);nextSheet.classList.remove('previous');nextSheet.classList.remove('next');nextSheet.classList.add('current');}
if(currentSheet){currentSheet.classList.toggle('animated',animated);currentSheet.classList.remove('current');currentSheet.classList.add('previous');}
if(callback){callback();}});},_popMode:function(callback){var currentId=this.views[this.currentMode].id;var previousId=this.views[this.previousMode].id;var currentSheet=document.getElementById(currentId);var previousSheet=document.getElementById(previousId);currentSheet.classList.remove('current');currentSheet.classList.add('next');previousSheet.classList.remove('previous');previousSheet.classList.add('current');if(callback){callback();}},_updateBackArrow:function(){var noBackArrow=[MODE_TILES,MODE_LIST,MODE_SEARCH_FROM_TILES,MODE_SEARCH_FROM_LIST];var hide=noBackArrow.indexOf(this.currentMode)>-1;TitleBar.showBackArrow(!hide);},updateTitle:function(){var title;switch(this.currentMode){case MODE_TILES:title=this.playerTitle||navigator.mozL10n.get('music');break;case MODE_LIST:case MODE_SUBLIST:switch(TabBar.option){case'playlist':title=navigator.mozL10n.get('playlists');break;case'artist':title=navigator.mozL10n.get('artists');break;case'album':title=navigator.mozL10n.get('albums');break;case'title':title=navigator.mozL10n.get('songs');break;}
break;case MODE_PLAYER:title=this.playerTitle||navigator.mozL10n.get('unknownTitle');break;case MODE_PICKER:title=navigator.mozL10n.get('picker-title');break;}
if(title){TitleBar.changeTitleText(title);}
TitleBar.view.hidden=this.currentMode===MODE_SEARCH_FROM_TILES||this.currentMode===MODE_SEARCH_FROM_LIST;},updatePlayerIcon:function(){var isPlayerMode=(this.currentMode===MODE_PLAYER);var isPlayerQueued=(this.views[MODE_PLAYER].isLoaded&&PlayerView.isQueued);TitleBar.playerIcon.hidden=isPlayerMode||!isPlayerQueued;if(App.pendingPick){TitleBar.doneButton.hidden=!isPlayerMode;}},_updateTabs:function(){var hideTabs=this.currentMode===MODE_PLAYER||this.currentMode===MODE_SEARCH_FROM_TILES||this.currentMode===MODE_SEARCH_FROM_LIST;TabBar.view.classList.toggle('away',hideTabs);},_updateMode:function(callback){this._updateBackArrow();this.updateTitle();this.updatePlayerIcon();this._updateTabs();this._enableNFCSharing((this.currentMode===MODE_PLAYER));if(callback){callback();}},_enableNFCSharing:function(enabled){if(!navigator.mozNfc){return;}
if(enabled&&!App.pendingPick){navigator.mozNfc.onpeerready=function(event){var peer=event.peer;if(peer){peer.sendFile(PlayerView.playingBlob);}};}else{navigator.mozNfc.onpeerready=null;}}};

View file

@ -0,0 +1,592 @@
;'use strict';var LazyLoader=(function(){function LazyLoader(){this._loaded={};this._isLoading={};}
LazyLoader.prototype={_js:function(file,callback){var script=document.createElement('script');script.src=file;script.async=false;script.addEventListener('load',callback);document.head.appendChild(script);this._isLoading[file]=script;},_css:function(file,callback){var style=document.createElement('link');style.type='text/css';style.rel='stylesheet';style.href=file;document.head.appendChild(style);callback();},_html:function(domNode,callback){if(domNode.getAttribute('is')){this.load(['/shared/js/html_imports.js'],function(){HtmlImports.populate(callback);}.bind(this));return;}
for(var i=0;i<domNode.childNodes.length;i++){if(domNode.childNodes[i].nodeType==document.COMMENT_NODE){domNode.innerHTML=domNode.childNodes[i].nodeValue;break;}}
window.dispatchEvent(new CustomEvent('lazyload',{detail:domNode}));callback();},getJSON:function(file,mozSystem){return new Promise(function(resolve,reject){var xhr;if(mozSystem){xhr=new XMLHttpRequest({mozSystem:true});}else{xhr=new XMLHttpRequest();}
xhr.open('GET',file,true);xhr.responseType='json';xhr.onerror=function(error){reject(error);};xhr.onload=function(){if(xhr.response!==null){resolve(xhr.response);}else{reject(new Error('No valid JSON object was found ('+
xhr.status+' '+xhr.statusText+')'));}};xhr.send();});},load:function(files,callback){var deferred={};deferred.promise=new Promise(resolve=>{deferred.resolve=resolve;});if(!Array.isArray(files)){files=[files];}
var loadsRemaining=files.length,self=this;function perFileCallback(file){if(self._isLoading[file]){delete self._isLoading[file];}
self._loaded[file]=true;if(--loadsRemaining===0){deferred.resolve();if(callback){callback();}}}
for(var i=0;i<files.length;i++){var file=files[i];if(this._loaded[file.id||file]){perFileCallback(file);}else if(this._isLoading[file]){this._isLoading[file].addEventListener('load',perFileCallback.bind(null,file));}else{var method,idx;if(typeof file==='string'){method=file.match(/\.([^.]+)$/)[1];idx=file;}else{method='html';idx=file.id;}
this['_'+method](file,perFileCallback.bind(null,idx));}}
return deferred.promise;}};return new LazyLoader();}());;'use strict';var MimeMapper={_typeToExtensionMap:{'image/jpeg':'jpg','image/png':'png','image/gif':'gif','image/bmp':'bmp','audio/mpeg':'mp3','audio/mp4':'m4a','audio/ogg':'ogg','audio/webm':'webm','audio/3gpp':'3gp','audio/amr':'amr','video/mp4':'mp4','video/mpeg':'mpg','video/ogg':'ogg','video/webm':'webm','video/3gpp':'3gp','video/3gpp2':'3g2','application/pdf':'pdf','application/vcard':'vcf','text/vcard':'vcf','text/x-vcard':'vcf'},_extensionToTypeMap:{'jpg':'image/jpeg','jpeg':'image/jpeg','jpe':'image/jpeg','png':'image/png','gif':'image/gif','bmp':'image/bmp','mp3':'audio/mpeg','m4a':'audio/mp4','m4b':'audio/mp4','m4p':'audio/mp4','m4r':'audio/mp4','aac':'audio/aac','opus':'audio/ogg','amr':'audio/amr','mp4':'video/mp4','mpeg':'video/mpeg','mpg':'video/mpeg','ogv':'video/ogg','ogx':'video/ogg','webm':'video/webm','3gp':'video/3gpp','3g2':'video/3gpp2','ogg':'video/ogg','pdf':'application/pdf','vcf':'text/vcard'},_parseExtension:function(filename){var array=filename.split('.');return array.length>1?array.pop():'';},isSupportedType:function(mimetype){return(mimetype in this._typeToExtensionMap);},isSupportedExtension:function(extension){return(extension in this._extensionToTypeMap);},isFilenameMatchesType:function(filename,mimetype){var extension=this._parseExtension(filename);var guessedType=this.guessTypeFromExtension(extension);return(guessedType==mimetype);},guessExtensionFromType:function(mimetype){return this._typeToExtensionMap[mimetype];},guessTypeFromExtension:function(extension){return this._extensionToTypeMap[extension];},guessTypeFromFileProperties:function(filename,mimetype){var extension=this._parseExtension(filename);var type=this.isSupportedType(mimetype)?mimetype:this.guessTypeFromExtension(extension);return type||'';},ensureFilenameMatchesType:function(filename,mimetype){if(!this.isFilenameMatchesType(filename,mimetype)){var guessedExt=this.guessExtensionFromType(mimetype);if(guessedExt){filename+='.'+guessedExt;}}
return filename;}};;this.asyncStorage=(function(){'use strict';var DBNAME='asyncStorage';var DBVERSION=1;var STORENAME='keyvaluepairs';var db=null;function withDatabase(f){if(db){f();}else{var openreq=indexedDB.open(DBNAME,DBVERSION);openreq.onerror=function withStoreOnError(){console.error('asyncStorage: can\'t open database:',openreq.error.name);};openreq.onupgradeneeded=function withStoreOnUpgradeNeeded(){openreq.result.createObjectStore(STORENAME);};openreq.onsuccess=function withStoreOnSuccess(){db=openreq.result;f();};}}
function withStore(type,callback,oncomplete){withDatabase(function(){var transaction=db.transaction(STORENAME,type);if(oncomplete){transaction.oncomplete=oncomplete;}
callback(transaction.objectStore(STORENAME));});}
function getItem(key,callback){var req;withStore('readonly',function getItemBody(store){req=store.get(key);req.onerror=function getItemOnError(){console.error('Error in asyncStorage.getItem(): ',req.error.name);};},function onComplete(){var value=req.result;if(value===undefined){value=null;}
callback(value);});}
function setItem(key,value,callback){withStore('readwrite',function setItemBody(store){var req=store.put(value,key);req.onerror=function setItemOnError(){console.error('Error in asyncStorage.setItem(): ',req.error.name);};},callback);}
function removeItem(key,callback){withStore('readwrite',function removeItemBody(store){var req=store.delete(key);req.onerror=function removeItemOnError(){console.error('Error in asyncStorage.removeItem(): ',req.error.name);};},callback);}
function clear(callback){withStore('readwrite',function clearBody(store){var req=store.clear();req.onerror=function clearOnError(){console.error('Error in asyncStorage.clear(): ',req.error.name);};},callback);}
function length(callback){var req;withStore('readonly',function lengthBody(store){req=store.count();req.onerror=function lengthOnError(){console.error('Error in asyncStorage.length(): ',req.error.name);};},function onComplete(){callback(req.result);});}
function key(n,callback){if(n<0){callback(null);return;}
var req;withStore('readonly',function keyBody(store){var advanced=false;req=store.openCursor();req.onsuccess=function keyOnSuccess(){var cursor=req.result;if(!cursor){return;}
if(n===0||advanced){return;}
advanced=true;cursor.advance(n);};req.onerror=function keyOnError(){console.error('Error in asyncStorage.key(): ',req.error.name);};},function onComplete(){var cursor=req.result;callback(cursor?cursor.key:null);});}
return{getItem:getItem,setItem:setItem,removeItem:removeItem,clear:clear,length:length,key:key};}());;(function(exports){'use strict';var ImageUtils=exports.ImageUtils={};const JPEG='image/jpeg';const PNG='image/png';const GIF='image/gif';const BMP='image/bmp';ImageUtils.JPEG=JPEG;ImageUtils.PNG=PNG;ImageUtils.GIF=GIF;ImageUtils.BMP=BMP;ImageUtils.getSizeAndType=function getSizeAndType(imageBlob){if(!(imageBlob instanceof Blob)){console.log('not blob');return Promise.reject(new TypeError('argument is not a Blob'));}
return new Promise(function(resolve,reject){if(imageBlob.size<=16){reject('corrupt image file');return;}
var bytesToRead=32*1024;if(imageBlob.type===PNG||imageBlob.type===GIF||imageBlob.type===BMP){bytesToRead=512;}
findSizeAndType(imageBlob,bytesToRead,success,tryagain);function success(data){resolve(data);}
function tryagain(data){if(data.type===JPEG){findSizeAndType(imageBlob,imageBlob.size,success,failure);}
else{reject(data.error);}}
function failure(data){reject(data.error);}});function findSizeAndType(imageBlob,amountToRead,success,failure){var slice=imageBlob.slice(0,Math.min(amountToRead,imageBlob.size));var reader=new FileReader();reader.readAsArrayBuffer(slice);reader.onloadend=function(){parseImageData(reader.result);};function parseImageData(buffer){var header=new Uint8Array(buffer,0,16);var view=new DataView(buffer);if(header[0]===0x89&&header[1]===0x50&&header[2]===0x4e&&header[3]===0x47&&header[4]===0x0d&&header[5]===0x0a&&header[6]===0x1A&&header[7]===0x0a&&header[12]===0x49&&header[13]===0x48&&header[14]===0x44&&header[15]===0x52)
{try{success({type:PNG,width:view.getUint32(16,false),height:view.getUint32(20,false)});}
catch(ex){failure({error:ex.toString()});}}
else if(header[0]===0x47&&header[1]===0x49&&header[2]===0x46&&header[3]===0x38&&(header[4]===0x37||header[4]===0x39)&&header[5]===0x61)
{try{success({type:GIF,width:view.getUint16(6,true),height:view.getUint16(8,true)});}
catch(ex){failure({error:ex.toString()});}}
else if(header[0]===0x42&&header[1]===0x4D&&view.getUint32(2,true)===imageBlob.size)
{try{var width,height;if(view.getUint16(14,true)===12){width=view.getUint16(18,true);height=view.getUint16(20,true);}
else{width=view.getUint32(18,true);height=view.getUint32(22,true);}
success({type:BMP,width:width,height:height});}
catch(ex){failure({error:ex.toString()});}}
else if(header[0]===0xFF&&header[1]===0xD8){var value={type:JPEG};try{var offset=2;for(;;){if(view.getUint8(offset)!==0xFF){failure({error:'corrupt JPEG file'});}
var segmentType=view.getUint8(offset+1);var segmentSize=view.getUint16(offset+2)+2;if((segmentType>=0xC0&&segmentType<=0xC3)||(segmentType>=0xC5&&segmentType<=0xC7)||(segmentType>=0xC9&&segmentType<=0xCB)||(segmentType>=0xCD&&segmentType<=0xCF))
{value.height=view.getUint16(offset+5,false);value.width=view.getUint16(offset+7,false);success(value);break;}
offset+=segmentSize;if(offset+9>view.byteLength){value.error='corrupt JPEG file';failure(value);break;}}}
catch(ex){failure({error:ex.toString()});}}
else{failure({error:'unknown image type'});}}}};ImageUtils.resizeAndCropToCover=function(inputImageBlob,outputWidth,outputHeight,outputType,encoderOptions)
{if(!outputWidth||!isFinite(outputWidth)||outputWidth<=0||!outputHeight||!isFinite(outputHeight)||outputHeight<=0){return Promise.reject(new TypeError('invalid output dimensions'));}
outputWidth=Math.round(outputWidth);outputHeight=Math.round(outputHeight);return ImageUtils.getSizeAndType(inputImageBlob).then(function resolve(data){var inputWidth=data.width;var inputHeight=data.height;if(inputWidth===outputWidth&&inputHeight===outputHeight){return inputImageBlob;}
return resize(data);},function reject(error){return resize({});});function resize(data){var inputType=data.type;var inputWidth=data.width;var inputHeight=data.height;if(outputType&&outputType!==JPEG&&outputType!==PNG){console.warn('Ignoring unsupported outputType',outputType);outputType=undefined;}
if(!outputType){if(inputType===JPEG||inputType===PNG){outputType=inputType;}
else{outputType=PNG;}}
var url=URL.createObjectURL(inputImageBlob);var mediaFragment;if(inputType===JPEG&&inputWidth>outputWidth&&inputHeight>outputHeight){var reduction=Math.max(outputWidth/inputWidth,outputHeight/inputHeight);mediaFragment=ImageUtils.Downsample.sizeNoMoreThan(reduction);}
else{mediaFragment='';}
return new Promise(function(resolve,reject){var offscreenImage=new Image();offscreenImage.src=url+mediaFragment;offscreenImage.onerror=function(e){cleanupImage();reject('failed to decode image');};offscreenImage.onload=function(){var actualWidth=offscreenImage.width;var actualHeight=offscreenImage.height;var widthScale=outputWidth/actualWidth;var heightScale=outputHeight/actualHeight;var scale=Math.max(widthScale,heightScale);var cropWidth=Math.round(outputWidth/scale);var cropHeight=Math.round(outputHeight/scale);var cropLeft=Math.floor((actualWidth-cropWidth)/2);var cropTop=Math.floor((actualHeight-cropHeight)/2);var canvas=document.createElement('canvas');canvas.width=outputWidth;canvas.height=outputHeight;var context=canvas.getContext('2d',{willReadFrequently:true});context.drawImage(offscreenImage,cropLeft,cropTop,cropWidth,cropHeight,0,0,outputWidth,outputHeight);cleanupImage();canvas.toBlob(function(blob){canvas.width=0;resolve(blob);},outputType,encoderOptions);};function cleanupImage(){offscreenImage.onerror=offscreenImage.onload='';offscreenImage.onload=offscreenImage.onerror=null;offscreenImage.removeAttribute('src');URL.revokeObjectURL(url);}});}};(function(exports){'use strict';function round(x){return Math.round(x*100)/100;}
function MozSampleSize(n,scale){return Object.freeze({dimensionScale:round(scale),areaScale:round(scale*scale),toString:function(){return'#-moz-samplesize='+n;},scale:function(x){return Math.ceil(x*scale);}});}
var NONE=Object.freeze({dimensionScale:1,areaScale:1,toString:function(){return'';},scale:function(x){return x;}});var fragments=[NONE,MozSampleSize(2,1/2),MozSampleSize(3,3/8),MozSampleSize(4,1/4),MozSampleSize(8,1/8)];function sizeAtLeast(scale){scale=round(scale);for(var i=0;i<fragments.length;i++){var f=fragments[i];if(f.dimensionScale<=scale){return f;}}
return fragments[fragments.length-1];}
function sizeNoMoreThan(scale){scale=round(scale);for(var i=fragments.length-1;i>=0;i--){var f=fragments[i];if(f.dimensionScale>=scale){return f;}}
return NONE;}
function areaAtLeast(scale){scale=round(scale);for(var i=0;i<fragments.length;i++){var f=fragments[i];if(f.areaScale<=scale){return f;}}
return fragments[fragments.length-1];}
function areaNoMoreThan(scale){scale=round(scale);for(var i=fragments.length-1;i>=0;i--){var f=fragments[i];if(f.areaScale>=scale){return f;}}
return NONE;}
exports.Downsample={sizeAtLeast:sizeAtLeast,sizeNoMoreThan:sizeNoMoreThan,areaAtLeast:areaAtLeast,areaNoMoreThan:areaNoMoreThan,NONE:NONE,MAX_SIZE_REDUCTION:1/fragments[fragments.length-1].dimensionScale,MAX_AREA_REDUCTION:1/fragments[fragments.length-1].areaScale};}(exports.ImageUtils));})(window);;(function(exports){'use strict';var FontSizeUtils={_cachedContexts:{},_getCachedContext:function(fontSize,fontFamily,fontStyle){fontStyle=fontStyle||'italic';var cache=this._cachedContexts;var ctx=cache[fontSize]&&cache[fontSize][fontFamily]?cache[fontSize][fontFamily][fontStyle]:null;if(!ctx){var canvas=document.createElement('canvas');canvas.setAttribute('moz-opaque','true');canvas.setAttribute('width','1');canvas.setAttribute('height','1');ctx=canvas.getContext('2d',{willReadFrequently:true});ctx.font=fontStyle+' '+fontSize+'px '+fontFamily;if(!cache[fontSize]){cache[fontSize]={};}
if(!cache[fontSize][fontFamily]){cache[fontSize][fontFamily]={};}
cache[fontSize][fontFamily][fontStyle]=ctx;}
return ctx;},resetCache:function(){this._cachedContexts={};},getFontWidth:function(string,fontSize,fontFamily,fontStyle){var ctx=this._getCachedContext(fontSize,fontFamily,fontStyle);return ctx.measureText(string).width;},getMaxFontSizeInfo:function(string,allowedSizes,fontFamily,maxWidth){var fontSize;var resultWidth;var i=allowedSizes.length-1;do{fontSize=allowedSizes[i];resultWidth=this.getFontWidth(string,fontSize,fontFamily);i--;}while(resultWidth>maxWidth&&i>=0);return{fontSize:fontSize,overflow:resultWidth>maxWidth,textWidth:resultWidth};},_overflowCountCache:-1,getOverflowCount:function(string,fontSize,fontFamily,maxWidth){var substring;var resultWidth;var overflowCount=-1;if(string.length>this._overflowCountCache){substring=string.substr(0,string.length-this._overflowCountCache);resultWidth=this.getFontWidth(substring,fontSize,fontFamily);if(resultWidth>maxWidth){overflowCount=this._overflowCountCache;}}
do{overflowCount++;substring=string.substr(0,string.length-overflowCount);resultWidth=this.getFontWidth(substring,fontSize,fontFamily);}while(substring.length>0&&resultWidth>maxWidth);this._overflowCountCache=overflowCount;return overflowCount;},getContentWidth:function(style){var width=parseInt(style.width,10);if(style.boxSizing==='border-box'){width-=(parseInt(style.paddingRight,10)+
parseInt(style.paddingLeft,10));}
return width;},getStyleProperties:function(element){var style=window.getComputedStyle(element);var contentWidth=this.getContentWidth(style);if(isNaN(contentWidth)){contentWidth=0;}
return{fontFamily:style.fontFamily,contentWidth:contentWidth,paddingRight:parseInt(style.paddingRight,10),paddingLeft:parseInt(style.paddingLeft,10),offsetLeft:element.offsetLeft};},getWindowWidth:function(){return window.innerWidth;}};exports.FontSizeUtils=FontSizeUtils;}(this));;(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.GaiaHeader=f()}})(function(){var define,module,exports;return(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){;(function(define){define(function(require,exports,module){'use strict';var debug=0?console.log.bind(console):function(){};var cache={};var MIN=16;var MAX=24;var BUFFER=3;module.exports=function(config){debug('font fit',config);var space=config.space-BUFFER;var min=config.min||MIN;var max=config.max||MAX;var text=trim(config.text);var fontSize=max;var textWidth;var font;do{font=config.font.replace(/\d+px/,fontSize+'px');textWidth=getTextWidth(text,font);}while(textWidth>space&&fontSize!==min&&fontSize--);return{textWidth:textWidth,fontSize:fontSize,overflowing:textWidth>space};};function getTextWidth(text,font){var ctx=getCanvasContext(font);var width=ctx.measureText(text).width;debug('got text width',width);return width;}
function getCanvasContext(font){debug('get canvas context',font);var cached=cache[font];if(cached){return cached;}
var canvas=document.createElement('canvas');canvas.setAttribute('moz-opaque','true');canvas.setAttribute('width','1px');canvas.setAttribute('height','1px');debug('created canvas',canvas);var ctx=canvas.getContext('2d',{willReadFrequently:true});ctx.font=font;return cache[font]=ctx;}
function trim(text){return text.replace(/\s+/g,' ').trim();}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('font-fit',this));},{}],2:[function(require,module,exports){;(function(define){'use strict';define(function(require,exports,module){var textContent=Object.getOwnPropertyDescriptor(Node.prototype,'textContent');var innerHTML=Object.getOwnPropertyDescriptor(Element.prototype,'innerHTML');var removeAttribute=Element.prototype.removeAttribute;var setAttribute=Element.prototype.setAttribute;var noop=function(){};exports.register=function(name,props){var baseProto=getBaseProto(props.extends);var template=props.template||baseProto.templateString;var extensible=props.extensible=props.hasOwnProperty('extensible')?props.extensible:true;delete props.extends;if(template){if(extensible&&props.template){props.templateString=props.template;}
var output=processCss(template,name);props.template=document.createElement('template');props.template.innerHTML=output.template;props.lightCss=output.lightCss;props.globalCss=props.globalCss||'';props.globalCss+=output.globalCss;}
injectGlobalCss(props.globalCss);delete props.globalCss;var descriptors=mixin(props.attrs||{},base.descriptors);props._attrs=props.attrs;delete props.attrs;var proto=createProto(baseProto,props);Object.defineProperties(proto,descriptors);try{return document.registerElement(name,{prototype:proto});}catch(e){if(e.name!=='NotSupportedError'){throw e;}}};var base={properties:{GaiaComponent:true,attributeChanged:noop,attached:noop,detached:noop,created:noop,createdCallback:function(){if(this.dirObserver){addDirObserver();}
injectLightCss(this);this.created();},attributeChangedCallback:function(name,from,to){var prop=toCamelCase(name);if(this._attrs&&this._attrs[prop]){this[prop]=to;}
this.attributeChanged(name,from,to);},attachedCallback:function(){if(this.dirObserver){this.setInnerDirAttributes=setInnerDirAttributes.bind(null,this);document.addEventListener('dirchanged',this.setInnerDirAttributes);}
this.attached();},detachedCallback:function(){if(this.dirObserver){document.removeEventListener('dirchanged',this.setInnerDirAttributes);}
this.detached();},setupShadowRoot:function(){if(!this.template){return;}
var node=document.importNode(this.template.content,true);this.createShadowRoot().appendChild(node);if(this.dirObserver){setInnerDirAttributes(this);}
return this.shadowRoot;},setAttr:function(name,value){var internal=this.shadowRoot.firstElementChild;setAttribute.call(internal,name,value);setAttribute.call(this,name,value);},removeAttr:function(name){var internal=this.shadowRoot.firstElementChild;removeAttribute.call(internal,name);removeAttribute.call(this,name);}},descriptors:{textContent:{set:function(value){textContent.set.call(this,value);if(this.lightStyle){this.appendChild(this.lightStyle);}},get:function(){return textContent.get();}},innerHTML:{set:function(value){innerHTML.set.call(this,value);if(this.lightStyle){this.appendChild(this.lightStyle);}},get:innerHTML.get}}};var defaultPrototype=createProto(HTMLElement.prototype,base.properties);function getBaseProto(proto){if(!proto){return defaultPrototype;}
proto=proto.prototype||proto;return!proto.GaiaComponent?createProto(proto,base.properties):proto;}
function createProto(proto,props){return mixin(Object.create(proto),props);}
var hasShadowCSS=(function(){var div=document.createElement('div');try{div.querySelector(':host');div.querySelector('::content');return true;}
catch(e){return false;}})();var regex={shadowCss:/(?:\:host|\:\:content)[^{]*\{[^}]*\}/g,':host':/(?:\:host)/g,':host()':/\:host\((.+)\)(?: \:\:content)?/g,':host-context':/\:host-context\((.+)\)([^{,]+)?/g,'::content':/(?:\:\:content)/g};function processCss(template,name){var globalCss='';var lightCss='';if(!hasShadowCSS){template=template.replace(regex.shadowCss,function(match){var hostContext=regex[':host-context'].exec(match);if(hostContext){globalCss+=match.replace(regex['::content'],'').replace(regex[':host-context'],'$1 '+name+'$2').replace(/ +/g,' ');}else{lightCss+=match.replace(regex[':host()'],name+'$1').replace(regex[':host'],name).replace(regex['::content'],name);}
return'';});}
return{template:template,lightCss:lightCss,globalCss:globalCss};}
function injectGlobalCss(css){if(!css){return;}
var style=document.createElement('style');style.innerHTML=css.trim();headReady().then(function(){document.head.appendChild(style);});}
function headReady(){return new Promise(function(resolve){if(document.head){return resolve();}
window.addEventListener('load',function fn(){window.removeEventListener('load',fn);resolve();});});}
function injectLightCss(el){if(hasShadowCSS){return;}
var stylesheet=el.querySelector('style');if(!stylesheet){stylesheet=document.createElement('style');stylesheet.setAttribute('scoped','');stylesheet.appendChild(document.createTextNode(el.lightCss));el.appendChild(stylesheet);}
el.lightStyle=stylesheet;}
function toCamelCase(string){return string.replace(/-(.)/g,function replacer(string,p1){return p1.toUpperCase();});}
var dirObserver;function setInnerDirAttributes(component){var dir=component.dir||document.dir;Array.from(component.shadowRoot.children).forEach(element=>{if(element.nodeName!=='STYLE'){element.dir=dir;}});}
function addDirObserver(){if(dirObserver){return;}
dirObserver=new MutationObserver(onChanged);dirObserver.observe(document.documentElement,{attributeFilter:['dir'],attributes:true});function onChanged(mutations){document.dispatchEvent(new Event('dirchanged'));}}
function mixin(target,source){for(var key in source){target[key]=source[key];}
return target;}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-component',this));},{}],3:[function(require,module,exports){(function(define){'use strict';define(function(require,exports,module){var base=window.GAIA_ICONS_BASE_URL||window.COMPONENTS_BASE_URL||'bower_components/';if(!document.documentElement){window.addEventListener('load',load);}else{load();}
function load(){if(isLoaded()){return;}
var link=document.createElement('link');link.rel='stylesheet';link.type='text/css';link.href=base+'gaia-icons/gaia-icons.css';document.head.appendChild(link);exports.loaded=true;}
function isLoaded(){return exports.loaded||document.querySelector('link[href*=gaia-icons]')||document.documentElement.classList.contains('gaia-icons-loaded');}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-icons',this));},{}],4:[function(require,module,exports){;(function(define){'use strict';define(function(require,exports,module){var component=require('gaia-component');var fontFit=require('font-fit');require('gaia-icons');var debug=0?console.log.bind(console):function(){};const KNOWN_ACTIONS={menu:'menu',back:'back',close:'close'};const TITLE_FONT='italic 300 24px FiraSans';const TITLE_PADDING=10;const MINIMUM_FONT_SIZE_CENTERED=20;const MINIMUM_FONT_SIZE_UNCENTERED=16;const MAXIMUM_FONT_SIZE=23;module.exports=component.register('gaia-header',{extensible:false,dirObserver:true,created:function(){debug('created');this.setupShadowRoot();this.els={actionButton:this.shadowRoot.querySelector('.action-button'),titles:this.getElementsByTagName('h1')};this.els.actionButton.addEventListener('click',e=>this.onActionButtonClick(e));this.observer=new MutationObserver(this.onMutation.bind(this));this.ignoreDir=this.hasAttribute('ignore-dir');this.titleEnd=this.getAttribute('title-end');this.titleStart=this.getAttribute('title-start');this.noFontFit=this.getAttribute('no-font-fit');this.notFlush=this.hasAttribute('not-flush');this.action=this.getAttribute('action');this.unresolved={};this.pending={};this._resizeThrottlingId=null;this.onResize=this.onResize.bind(this);},attached:function(){debug('attached');this.runFontFitSoon();this.observerStart();window.addEventListener('resize',this.onResize);},detached:function(){debug('detached');window.removeEventListener('resize',this.onResize);this.observerStop();this.clearPending();},clearPending:function(){for(var key in this.pending){this.pending[key].clear();delete this.pending[key];}
window.cancelAnimationFrame(this._resizeThrottlingId);this._resizeThrottlingId=null;},runFontFit:function(){debug('run font-fit');if(this.noFontFit){return Promise.resolve();}
var titles=this.els.titles;var space=this.getTitleSpace();var styles=[].map.call(titles,el=>this.getTitleStyle(el,space));return this.setTitleStylesSoon(styles);},runFontFitSoon:function(){debug('run font-fit soon');if(this.pending.runFontFitSoon){return;}
this.pending.runFontFitSoon=this.nextTick(()=>{delete this.pending.runFontFitSoon;this.runFontFit();});},getTitleStyle:function(el,space){debug('get el style',el,space);var text=el.textContent;var styleId=space.start+text+space.end+'#'+space.value;if(!text||!text.trim()){return debug('exit: no text');}
if(getStyleId(el)===styleId){return debug('exit: no change');}
var marginStart=this.getTitleMarginStart();var textSpace=space.value-Math.abs(marginStart);var fontFitResult=this.fontFit(text,textSpace,{min:MINIMUM_FONT_SIZE_CENTERED});var overflowing=fontFitResult.overflowing;var padding={start:0,end:0};if(overflowing){debug('title overflowing');padding.start=!space.start?TITLE_PADDING:0;padding.end=!space.end?TITLE_PADDING:0;textSpace=space.value-padding.start-padding.end;fontFitResult=this.fontFit(text,textSpace);marginStart=0;}
return{id:styleId,fontSize:fontFitResult.fontSize,marginStart:marginStart,overflowing:overflowing,padding:padding};},setTitleStylesSoon:function(styles){debug('set title styles soon',styles);var key='setStyleTitlesSoon';this._titleStyles=styles;if(this.unresolved[key]){return this.unresolved[key];}
this.unresolved[key]=new Promise((resolve)=>{this.pending[key]=this.nextTick(()=>{var styles=this._titleStyles;var els=this.els.titles;[].forEach.call(els,(el,i)=>{if(!styles[i]){return debug('exit');}
this.setTitleStyle(el,styles[i]);});delete this._titleStyles;delete this.unresolved[key];delete this.pending[key];resolve();});});},setTitleStyle:function(el,style){debug('set title style',style);this.observerStop();if(this.ignoreDir){el.style.marginLeft=style.marginStart+'px';el.style.paddingLeft=style.padding.start+'px';el.style.paddingRight=style.padding.end+'px';}else{el.style.marginInlineStart=style.marginStart+'px';el.style.paddingInlineStart=style.padding.start+'px';el.style.paddingInlineEnd=style.padding.end+'px';}
el.style.fontSize=style.fontSize+'px';setStyleId(el,style.id);this.observerStart();},fontFit:function(text,space,opts={}){debug('font fit:',text,space,opts);var fontFitArgs={font:TITLE_FONT,min:opts.min||MINIMUM_FONT_SIZE_UNCENTERED,max:MAXIMUM_FONT_SIZE,text:text,space:space};return fontFit(fontFitArgs);},observerStart:function(){if(this.observing){return;}
this.observer.observe(this,{childList:true,attributes:true,subtree:true});this.observing=true;debug('observer started');},observerStop:function(){if(!this.observing){return;}
this.observer.disconnect();this.observing=false;debug('observer stopped');},onResize:function(e){debug('onResize',this._resizeThrottlingId);if(this._resizeThrottlingId!==null){return;}
this._resizeThrottlingId=window.requestAnimationFrame(()=>{this._resizeThrottlingId=null;this.runFontFitSoon();});},onMutation:function(mutations){debug('on mutation',mutations);if(!this.pending.runFontFitSoon){this.runFontFit();}},getTitleSpace:function(){var start=this.titleStart;var end=this.titleEnd;var space=this.getWidth()-start-end;var result={value:space,start:start,end:end};debug('get title space',result);return result;},getWidth:function(){var value=this.notFlush?this.clientWidth:window.innerWidth;debug('get width',value);return value;},triggerAction:function(){if(this.action){this.els.actionButton.click();}},onActionButtonClick:function(){debug('action button click');var config={detail:{type:this.action}};var e=new CustomEvent('action',config);setTimeout(()=>this.dispatchEvent(e));},getTitleMarginStart:function(){var start=this.titleStart;var end=this.titleEnd;var marginStart=end-start;debug('get title margin start',marginStart);return marginStart;},getButtonsBeforeTitle:function(){var children=this.children;var l=children.length;var els=[];for(var i=0;i<l;i++){var el=children[i];if(el.tagName==='H1'){break;}
if(!contributesToLayout(el)){continue;}
els.push(el);}
if(this.action){els.push(this.els.actionButton);}
return els;},getButtonsAfterTitle:function(){var children=this.children;var els=[];for(var i=children.length-1;i>=0;i--){var el=children[i];if(el.tagName==='H1'){break;}
if(!contributesToLayout(el)){continue;}
els.push(el);}
return els;},sumButtonWidths:function(buttons){var defaultWidth=50;var sum=buttons.reduce((prev,button)=>{var isStandardButton=button===this.els.actionButton;var width=isStandardButton?defaultWidth:button.clientWidth;return prev+width;},0);debug('sum button widths',buttons,sum);return sum;},attrs:{action:{get:function(){return this._action;},set:function(value){var action=KNOWN_ACTIONS[value];if(action===this._action){return;}
this.setAttr('action',action);this._action=action;}},titleStart:{get:function(){debug('get title-start');if('_titleStart'in this){return this._titleStart;}
var buttons=this.getButtonsBeforeTitle();var value=this.sumButtonWidths(buttons);debug('get title-start',buttons,value);return value;},set:function(value){debug('set title-start',value);value=parseInt(value,10);if(value===this._titleStart||isNaN(value)){return;}
this.setAttr('title-start',value);this._titleStart=value;debug('set');}},titleEnd:{get:function(){debug('get title-end');if('_titleEnd'in this){return this._titleEnd;}
var buttons=this.getButtonsAfterTitle();return this.sumButtonWidths(buttons);},set:function(value){debug('set title-end',value);value=parseInt(value,10);if(value===this._titleEnd||isNaN(value)){return;}
this.setAttr('title-end',value);this._titleEnd=value;}},noFontFit:{get:function(){return this._noFontFit||false;},set:function(value){debug('set no-font-fit',value);value=!!(value||value==='');if(value===this.noFontFit){return;}
this._noFontFit=value;if(value){this.setAttr('no-font-fit','');}
else{this.removeAttr('no-font-fit');}}},ignoreDir:{get:function(){return this._ignoreDir||false;},set:function(value){debug('set ignore-dir',value);value=!!(value||value==='');if(value===this.ignoreDir){return;}
this._ignoreDir=value;this.dirObserver=!value;if(value){this.setAttr('ignore-dir','');}
else{this.removeAttr('ignore-dir');}}}},template:`<div class="inner">
<button class="action-button">
<content select="[l10n-action]"></content>
</button>
<content></content>
</div>
<style>
:host {
display: block;
-moz-user-select: none;
--gaia-header-button-color:
var(--header-button-color,
var(--header-color,
var(--link-color,
inherit)));
}
/**
* [hidden]
*/
:host[hidden] {
display: none;
}
/** Reset
---------------------------------------------------------*/
::-moz-focus-inner { border: 0; }
/** Inner
---------------------------------------------------------*/
.inner {
display: flex;
min-height: 50px;
-moz-user-select: none;
background:
var(--header-background,
var(--background,
#fff));
}
/** Action Button
---------------------------------------------------------*/
/**
* 1. Hidden by default
*/
.action-button {
position: relative;
display: none; /* 1 */
width: 50px;
font-size: 30px;
margin: 0;
padding: 0;
border: 0;
outline: 0;
align-items: center;
background: none;
cursor: pointer;
transition: opacity 200ms 280ms;
color:
var(--header-action-button-color,
var(--header-icon-color,
var(--gaia-header-button-color)));
}
/**
* [action=back]
* [action=menu]
* [action=close]
*
* 1. For icon vertical-alignment
*/
[action=back] .action-button,
[action=menu] .action-button,
[action=close] .action-button {
display: flex; /* 1 */
}
/**
* :active
*/
.action-button:active {
transition: none;
opacity: 0.2;
}
/** Action Button Icon
---------------------------------------------------------*/
.action-button:before {
font-family: 'gaia-icons';
font-style: normal;
text-rendering: optimizeLegibility;
font-weight: 500;
}
[action=close] .action-button:before { content: 'close' }
[action=menu] .action-button:before { content: 'menu' }
[action=back]:-moz-dir(ltr) .action-button:before { content: 'left' }
[action=back]:-moz-dir(rtl) .action-button:before { content: 'right' }
/** Action Button Icon
---------------------------------------------------------*/
/**
* 1. To enable vertical alignment.
*/
.action-button:before {
display: block;
}
/** Action Button Text
---------------------------------------------------------*/
/**
* To provide custom localized content for
* the action-button, we allow the user
* to provide an element with the class
* .l10n-action. This node is then
* pulled inside the real action-button.
*
* Example:
*
* <gaia-header action="back">
* <span l10n-action aria-label="Back">Localized text</span>
* <h1>title</h1>
* </gaia-header>
*/
::content [l10n-action] {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
font-size: 0;
}
/** Title
---------------------------------------------------------*/
/**
* 1. Vertically center text. We can't use flexbox
* here as it breaks text-overflow ellipsis
* without an inner div.
*/
::content h1 {
flex: 1;
margin: 0;
padding: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: center;
line-height: 50px; /* 1 */
font-weight: 300;
font-style: italic;
font-size: 24px;
color:
var(--header-title-color,
var(--header-color,
var(--title-color,
var(--text-color,
inherit))));
}
/**
* [ignore-dir]
*
* When the <gaia-header> component has an [ignore-dir] attribute, header
* direction is forced to LTR but we still want the <h1> text to be reversed
* so that strings like '1 selected' become 'selected 1'.
*
* When we're happy for <gaia-header> to be fully RTL responsive we won't need
* these rules anymore, but this depends on all Gaia apps being ready.
*
* This should be safe to remove when bug 1179459 lands.
*/
:host[ignore-dir] {
direction: ltr;
}
:host[ignore-dir]:-moz-dir(rtl) h1 {
direction: rtl;
}
/** Buttons
---------------------------------------------------------*/
::content a,
::content button {
position: relative;
z-index: 1;
box-sizing: border-box;
display: flex;
width: auto;
height: auto;
min-width: 50px;
margin: 0;
padding: 0 10px;
outline: 0;
border: 0;
font-size: 14px;
line-height: 1;
align-items: center;
justify-content: center;
text-decoration: none;
text-align: center;
background: none;
border-radius: 0;
font-style: italic;
cursor: pointer;
transition: opacity 200ms 280ms;
color: var(--gaia-header-button-color);
}
/**
* :active
*/
::content a:active,
::content button:active {
transition: none;
opacity: 0.2;
}
/**
* [hidden]
*/
::content a[hidden],
::content button[hidden] {
display: none;
}
/**
* [disabled]
*/
::content a[disabled],
::content button[disabled] {
pointer-events: none;
color: var(--header-disabled-button-color);
}
/** Icon Buttons
---------------------------------------------------------*/
/**
* Icons are a different color to text
*/
::content .icon,
::content [data-icon] {
color:
var(--header-icon-color,
var(--gaia-header-button-color));
}
/**
* If users want their action button
* to be in the component's light-dom
* they can add an .action class
* to make it look like the
* shadow action button.
*/
::content .action {
color:
var(--header-action-button-color,
var(--header-icon-color,
var(--gaia-header-button-color)));
}
/**
* [data-icon]:empty
*
* Icon buttons with no textContent,
* should always be 50px.
*
* This is to prevent buttons being
* larger than they should be before
* icon-font has loaded.
*/
::content [data-icon]:empty {
width: 50px;
}
</style>`,nextTick:nextTick});function contributesToLayout(el){return el.localName!=='style'&&!el.hasAttribute('l10n-action');}
function setStyleId(el,id){el._styleId=id;}
function getStyleId(el){return el._styleId;}
function nextTick(fn){var cleared;Promise.resolve().then(()=>{if(!cleared){fn();}});return{clear:function(){cleared=true;}};}});})(typeof define=='function'&&define.amd?define:(function(n,w){'use strict';return typeof module=='object'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-header',this));},{"font-fit":1,"gaia-component":2,"gaia-icons":3}]},{},[4])(4)});;'use strict';var BlobView=(function(){function fail(msg){throw Error(msg);}
var decoderCache={};function getDecoder(encoding){if(encoding in decoderCache){return decoderCache[encoding];}
var decoder=decoderCache[encoding]=new TextDecoder(encoding);return decoder;}
function BlobView(blob,sliceOffset,sliceLength,slice,viewOffset,viewLength,littleEndian)
{this.blob=blob;this.sliceOffset=sliceOffset;this.sliceLength=sliceLength;this.slice=slice;this.viewOffset=viewOffset;this.viewLength=viewLength;this.littleEndian=littleEndian;this.view=new DataView(slice,viewOffset,viewLength);this.buffer=slice;this.byteLength=viewLength;this.byteOffset=viewOffset;this.index=0;}
BlobView.get=function(blob,offset,length,callback,littleEndian){if(offset<0){fail('negative offset');}
if(length<0){fail('negative length');}
if(offset>blob.size){fail('offset larger than blob size');}
if(offset+length>blob.size){length=blob.size-offset;}
var slice=blob.slice(offset,offset+length);var reader=new FileReader();reader.readAsArrayBuffer(slice);reader.onloadend=function(){var result=null;if(reader.result){result=new BlobView(blob,offset,length,reader.result,0,length,littleEndian||false);}
callback(result,reader.error);};};BlobView.getFromArrayBuffer=function(buffer,offset,length,littleEndian){return new BlobView(null,offset,length,buffer,offset,length,littleEndian);};BlobView.prototype={constructor:BlobView,getMore:function(offset,length,callback){if(!this.blob){fail('no blob backing this BlobView');}
if(offset>=this.sliceOffset&&offset+length<=this.sliceOffset+this.sliceLength){callback(new BlobView(this.blob,this.sliceOffset,this.sliceLength,this.slice,offset-this.sliceOffset,length,this.littleEndian));}
else{BlobView.get(this.blob,offset,length,callback,this.littleEndian);}},littleEndian:function(){this.littleEndian=true;},bigEndian:function(){this.littleEndian=false;},getUint8:function(offset){return this.view.getUint8(offset);},getInt8:function(offset){return this.view.getInt8(offset);},getUint16:function(offset,le){return this.view.getUint16(offset,le!==undefined?le:this.littleEndian);},getInt16:function(offset,le){return this.view.getInt16(offset,le!==undefined?le:this.littleEndian);},getUint32:function(offset,le){return this.view.getUint32(offset,le!==undefined?le:this.littleEndian);},getInt32:function(offset,le){return this.view.getInt32(offset,le!==undefined?le:this.littleEndian);},getFloat32:function(offset,le){return this.view.getFloat32(offset,le!==undefined?le:this.littleEndian);},getFloat64:function(offset,le){return this.view.getFloat64(offset,le!==undefined?le:this.littleEndian);},readByte:function(){return this.view.getInt8(this.index++);},readUnsignedByte:function(){return this.view.getUint8(this.index++);},readShort:function(le){var val=this.view.getInt16(this.index,le!==undefined?le:this.littleEndian);this.index+=2;return val;},readUnsignedShort:function(le){var val=this.view.getUint16(this.index,le!==undefined?le:this.littleEndian);this.index+=2;return val;},readInt:function(le){var val=this.view.getInt32(this.index,le!==undefined?le:this.littleEndian);this.index+=4;return val;},readUnsignedInt:function(le){var val=this.view.getUint32(this.index,le!==undefined?le:this.littleEndian);this.index+=4;return val;},readFloat:function(le){var val=this.view.getFloat32(this.index,le!==undefined?le:this.littleEndian);this.index+=4;return val;},readDouble:function(le){var val=this.view.getFloat64(this.index,le!==undefined?le:this.littleEndian);this.index+=8;return val;},tell:function(){return this.index;},remaining:function(){return this.byteLength-this.index;},seek:function(index){if(index<0){fail('negative index');}
if(index>this.byteLength){fail('index greater than buffer size');}
this.index=index;},advance:function(n){var index=this.index+n;if(index<0){fail('advance past beginning of buffer');}
if(index>this.byteLength){fail('advance past end of buffer');}
this.index=index;},getUnsignedByteArray:function(offset,n){return new Uint8Array(this.buffer,offset+this.viewOffset,n);},readUnsignedByteArray:function(n){var val=new Uint8Array(this.buffer,this.index+this.viewOffset,n);this.index+=n;return val;},getBit:function(offset,bit){var byte=this.view.getUint8(offset);return(byte&(1<<bit))!==0;},getUint24:function(offset,le){var b1,b2,b3;if(le!==undefined?le:this.littleEndian){b1=this.view.getUint8(offset);b2=this.view.getUint8(offset+1);b3=this.view.getUint8(offset+2);}
else{b3=this.view.getUint8(offset);b2=this.view.getUint8(offset+1);b1=this.view.getUint8(offset+2);}
return(b3<<16)+(b2<<8)+b1;},readUint24:function(le){var value=this.getUint24(this.index,le);this.index+=3;return value;},getBinaryText:function(offset,len){var bytes=new Uint8Array(this.buffer,offset+this.viewOffset,len);return String.fromCharCode.apply(String,bytes);},readBinaryText:function(len){var s=this.getBinaryText(this.index,len);this.index+=len;return s;},getLatin1Text:function(offset,len){var bytes=new Uint8Array(this.buffer,offset+this.viewOffset,len);return getDecoder('latin1').decode(bytes);},readLatin1Text:function(len){var s=this.getLatin1Text(this.index,len);this.index+=len;return s;},getUTF8Text:function(offset,len){var bytes=new Uint8Array(this.buffer,offset+this.viewOffset,len);return getDecoder('utf-8').decode(bytes);},readUTF8Text:function(len){var s=this.getUTF8Text(this.index,len);this.index+=len;return s;},getUTF16Text:function(offset,len,le){if(len%2){fail('len must be a multiple of two');}
var bytes=new Uint8Array(this.buffer,offset+this.viewOffset,len);if(le===null||le===undefined){var BOM=(bytes[0]<<8)+bytes[1];if(BOM===0xFEFF){bytes=bytes.subarray(2);le=false;}else if(BOM===0xFFFE){bytes=bytes.subarray(2);le=true;}else{le=true;}}
var encoding=le?'utf-16le':'utf-16be';return getDecoder(encoding).decode(bytes);},readUTF16Text:function(len,le){var s=this.getUTF16Text(this.index,len,le);this.index+=len;return s;},getID3Uint28BE:function(offset){var b1=this.view.getUint8(offset)&0x7f;var b2=this.view.getUint8(offset+1)&0x7f;var b3=this.view.getUint8(offset+2)&0x7f;var b4=this.view.getUint8(offset+3)&0x7f;return(b1<<21)|(b2<<14)|(b3<<7)|b4;},readID3Uint28BE:function(){var value=this.getID3Uint28BE(this.index);this.index+=4;return value;},readNullTerminatedLatin1Text:function(size,advance_by_size=false){var bytes=new Uint8Array(this.buffer,this.viewOffset+this.index,size);var nil=bytes.indexOf(0);if(nil!==-1){bytes=bytes.subarray(0,nil);}
var s=getDecoder('latin1').decode(bytes);if(nil===-1||advance_by_size){this.index+=size;}else{this.index+=nil+1;}
return s;},readNullTerminatedUTF8Text:function(size,advance_by_size=false){var bytes=new Uint8Array(this.buffer,this.viewOffset+this.index,size);var nil=bytes.indexOf(0);if(nil!==-1){bytes=bytes.subarray(0,nil);}
var s=getDecoder('utf-8').decode(bytes);if(nil===-1||advance_by_size){this.index+=size;}else{this.index+=nil+1;}
return s;},readNullTerminatedUTF16Text:function(size,le,advance_by_size=false){if(size%2){fail('size must be a multiple of two');}
for(var len=0;len<size;len+=2){if(this.getUint16(this.index+len,le)===0){break;}}
var s=this.getUTF16Text(this.index,len,le);if(len===size||advance_by_size){this.index+=size;}else{this.index+=len+2;}
return s;}};return{get:BlobView.get,getFromArrayBuffer:BlobView.getFromArrayBuffer};}());'use strict';var MetadataFormats=(function(){var formats=[{file:'js/metadata/forward_lock.js',get module(){return ForwardLockMetadata;},match:function(header){return header.getBinaryText(0,9)==='LOCKED 1 ';}},{file:'js/metadata/id3v2.js',get module(){return ID3v2Metadata;},match:function(header){return header.getBinaryText(0,3)==='ID3';}},{file:'js/metadata/ogg.js',get module(){return OggMetadata;},match:function(header){return header.getBinaryText(0,4)==='OggS';}},{file:'js/metadata/flac.js',get module(){return FLACMetadata;},match:function(header){return header.getBinaryText(0,4)==='fLaC';}},{file:'js/metadata/mp4.js',get module(){return MP4Metadata;},match:function(header){return header.getBinaryText(4,4)==='ftyp';}},{file:'js/metadata/id3v1.js',get module(){return ID3v1Metadata;},match:function(header){return(header.getUint16(0,false)&0xFFFE)===0xFFFA;}}];function MetadataParser(formatInfo){this._formatInfo=formatInfo;}
MetadataParser.prototype={parse:function(header){var info=this._formatInfo;return LazyLoader.load(info.file).then(()=>{return info.module.parse(header);});}};function findParser(header){for(var i=0;i<formats.length;i++){if(formats[i].match(header)){return new MetadataParser(formats[i]);}}
return null;}
return{findParser:findParser};})();'use strict';var AudioMetadata=(function(){function parse(blob){var filename=blob.name;if(filename){if(filename.slice(0,5)==='DCIM/'&&filename.slice(-4).toLowerCase()==='.3gp'){return Promise.reject('skipping 3gp video file');}}
if(blob.size<128){return Promise.reject('file is empty or too small');}
return new Promise(function(resolve,reject){var headersize=Math.min(64*1024,blob.size);BlobView.get(blob,0,headersize,function(header,error){if(error){reject(error);return;}
try{var parser=MetadataFormats.findParser(header);var promise;if(parser){promise=parser.parse(header);}else{promise=checkPlayability(blob);}
resolve(promise.then(function(metadata){return addDefaultMetadata(metadata||{},filename);}));}catch(e){console.error('AudioMetadata.parse:',e,e.stack);reject(e);}});});}
function addDefaultMetadata(metadata,filename){if(!metadata.artist){metadata.artist='';}
if(!metadata.album){metadata.album='';}
if(!metadata.title){if(filename){var p1=filename.lastIndexOf('/');var p2=filename.lastIndexOf('.');if(p2<=p1){p2=filename.length;}
metadata.title=filename.substring(p1+1,p2);}else{metadata.title='';}}
metadata.rated=metadata.played=0;return metadata;}
function checkPlayability(blob){var player=new Audio();player.mozAudioChannelType='content';var canplay=blob.type&&player.canPlayType(blob.type);if(canplay==='probably'){return Promise.resolve();}else{return new Promise(function(resolve,reject){var url=URL.createObjectURL(blob);player.src=url;const CANPLAY_TIMEOUT=3000;var timeoutId=setTimeout(()=>{console.error('No oncanplay or error events seen yet.','Assuming file is corrupt:',blob.name);player.onerror();},CANPLAY_TIMEOUT);player.onerror=function(){clearTimeout(timeoutId);URL.revokeObjectURL(url);player.removeAttribute('src');player.load();reject('Unplayable music file');};player.oncanplay=function(){clearTimeout(timeoutId);URL.revokeObjectURL(url);player.removeAttribute('src');player.load();resolve();};});}}
return{parse:parse};})();;'use strict';var AlbumArtCache=(function(){var THUMBNAIL_WIDTH=300;var THUMBNAIL_HEIGHT=300;var L1Cache={'thumbnail':{},'fullsize':{}};function getFullSizeURL(fileinfo,noPlaceholder){if(!fileinfo.metadata.picture){return Promise.resolve(noPlaceholder?null:getDefaultCoverURL(fileinfo));}
var cacheKey=makeCacheKey(fileinfo);if(cacheKey&&cacheKey in L1Cache.fullsize){return Promise.resolve(L1Cache.fullsize[cacheKey]);}
return getAlbumArtBlob(fileinfo).then(function(blob){return makeAndCacheURL(cacheKey,blob,'fullsize');});}
function getFullSizeBlob(fileinfo,noPlaceholder){if(!fileinfo.metadata.picture){if(noPlaceholder){return Promise.resolve(null);}
return getBlobFromURL(getDefaultCoverURL(fileinfo));}
return getAlbumArtBlob(fileinfo);}
function getThumbnailURL(fileinfo,noPlaceholder){if(!fileinfo.metadata.picture){return Promise.resolve(noPlaceholder?null:getDefaultCoverURL(fileinfo));}
var cacheKey=makeCacheKey(fileinfo);if(cacheKey&&cacheKey in L1Cache.thumbnail){return Promise.resolve(L1Cache.thumbnail[cacheKey]);}
return checkL2Cache(cacheKey).then(function(cachedBlob){return cachedBlob||createThumbnail(cacheKey,fileinfo);}).then(function(blob){return makeAndCacheURL(cacheKey,blob,'thumbnail');});}
function getThumbnailBlob(fileinfo,noPlaceholder){if(!fileinfo.metadata.picture){if(noPlaceholder){return Promise.resolve(null);}
return getBlobFromURL(getDefaultCoverURL(fileinfo));}
var cacheKey=makeCacheKey(fileinfo);return checkL2Cache(cacheKey).then(function(cachedBlob){return cachedBlob||createThumbnail(cacheKey,fileinfo);});}
function getDefaultCoverURL(fileinfo){var metadata=fileinfo.metadata;var infoForHash=(!metadata.album&&!metadata.artist)?metadata.title:metadata.album+metadata.artist;var hashedNumber=(Math.abs(hash(infoForHash))%10)+1;return'/style/images/AlbumArt'+hashedNumber+'_small.png';}
function hash(str){var hashCode=0;if(str.length===0){return hashCode;}
for(var i=0;i<str.length;i++){var c=str.charCodeAt(i);hashCode=((hashCode<<5)-hashCode)+c;hashCode=hashCode&hashCode;}
return hashCode;}
function makeCacheKey(fileinfo){var metadata=fileinfo.metadata;if(metadata.picture.filename){return'external.'+metadata.picture.filename;}else if(metadata.picture.flavor==='embedded'){var album=metadata.album;var artist=metadata.artist;var size=metadata.picture.end-metadata.picture.start;if(album||artist){return'thumbnail.'+album+'.'+artist+'.'+size;}else{return'thumbnail.'+(fileinfo.name||fileinfo.blob.name);}}
return null;}
function checkL2Cache(cacheKey){if(!cacheKey){return Promise.resolve(null);}else{return new Promise(function(resolve,reject){asyncStorage.getItem(cacheKey,function(blob){resolve(blob);});});}}
function makeAndCacheURL(cacheKey,blob,type){var url=URL.createObjectURL(blob);if(cacheKey){L1Cache[type][cacheKey]=url;}
return url;}
function createThumbnail(cacheKey,fileinfo){return getAlbumArtBlob(fileinfo).then(function(blob){return ImageUtils.resizeAndCropToCover(blob,THUMBNAIL_WIDTH,THUMBNAIL_HEIGHT);}).then(function(thumbnailBlob){if(cacheKey){asyncStorage.setItem(cacheKey,thumbnailBlob);}
return thumbnailBlob;});}
function getAlbumArtBlob(fileinfo){var picture=fileinfo.metadata.picture;if(picture.blob){return Promise.resolve(picture.blob);}else if(picture.filename){return LazyLoader.load('/js/metadata/album_art.js').then(()=>{return new Promise((resolve,reject)=>{var getreq=AlbumArt.pictureStorage.get(picture.filename);getreq.onsuccess=function(){resolve(this.result);};getreq.onerror=function(){reject(this.error);};});});}else if(picture.start){return getSongBlob(fileinfo).then((blob)=>{return blob.slice(picture.start,picture.end,picture.type);});}else{var err=new Error('unknown picture flavor: '+picture.flavor);console.error(err);return Promise.reject(err);}}
function getSongBlob(fileinfo){if(fileinfo.blob){return Promise.resolve(fileinfo.blob);}else{return Database.getFile(fileinfo);}}
function getBlobFromURL(url){return new Promise(function(resolve,reject){var xhr=new XMLHttpRequest();xhr.open('GET',url,true);xhr.responseType='blob';xhr.onload=function(){resolve(xhr.response);};xhr.onerror=function(){reject(null);};xhr.send();});}
return{getFullSizeURL:getFullSizeURL,getFullSizeBlob:getFullSizeBlob,getThumbnailURL:getThumbnailURL,getThumbnailBlob:getThumbnailBlob};})();;'use strict';function formatTime(secs){if(isNaN(secs)){return;}
secs=Math.floor(secs);var formatedTime;var seconds=secs%60;var minutes=Math.floor(secs/60)%60;var hours=Math.floor(secs/3600);if(hours===0){formatedTime=(minutes<10?'0'+minutes:minutes)+':'+
(seconds<10?'0'+seconds:seconds);}else{formatedTime=(hours<10?'0'+hours:hours)+':'+
(minutes<10?'0'+minutes:minutes)+':'+
(seconds<10?'0'+seconds:seconds);}
return formatedTime;}
function createListElement(option,data,index,highlight){var li=document.createElement('li');li.className='list-item';li.setAttribute('role','presentation');var a=document.createElement('a');a.dataset.index=index;a.dataset.option=option;a.setAttribute('role','option');var titleBdi;li.appendChild(a);function highlightText(result,text){var textContent=result.textContent;var textLowerCased=textContent.toLocaleLowerCase();var index=Normalizer.toAscii(textLowerCased).indexOf(text);if(index>=0){var innerHTML=Sanitizer.createSafeHTML`
${textContent.substring(0, index)}
<span class="search-highlight">
${textContent.substring(index, index + text.length)}
</span>
${textContent.substring(index + text.length)}`;result.innerHTML=Sanitizer.unwrapSafeHTML(innerHTML);}}
switch(option){case'playlist':titleBdi=document.createElement('bdi');titleBdi.className='list-playlist-title';if(data.metadata.l10nId){titleBdi.textContent=navigator.mozL10n.get(data.metadata.l10nId);titleBdi.dataset.l10nId=data.metadata.l10nId;}else{titleBdi.textContent=data.metadata.title||navigator.mozL10n.get('unknownTitle');titleBdi.dataset.l10nId=data.metadata.title?'':'unknownTitle';}
a.dataset.keyRange='all';a.dataset.option=data.option;a.appendChild(titleBdi);if(index===0){var shuffleIcon=document.createElement('div');shuffleIcon.className='list-playlist-icon';shuffleIcon.dataset.icon='shuffle';shuffleIcon.setAttribute('data-l10n-id','shuffle-toggle');a.appendChild(shuffleIcon);}
break;case'artist':case'album':case'title':var artistBdi;var albumImg;albumImg=document.createElement('img');albumImg.className='list-album-art';li.appendChild(albumImg);LazyLoader.load('js/metadata/album_art_cache.js').then(()=>{return AlbumArtCache.getThumbnailURL(data);}).then((url)=>{showImage(albumImg,url);});if(option==='artist'){artistBdi=document.createElement('bdi');artistBdi.className='list-single-title';artistBdi.textContent=data.metadata.artist||navigator.mozL10n.get('unknownArtist');artistBdi.dataset.l10nId=data.metadata.artist?'':'unknownArtist';if(highlight){highlightText(artistBdi,highlight);}
a.appendChild(artistBdi);}else{var albumOrTitleBdi=document.createElement('bdi');artistBdi=document.createElement('bdi');albumOrTitleBdi.className='list-main-title';artistBdi.className='list-sub-title';if(option==='album'){albumOrTitleBdi.textContent=data.metadata.album||navigator.mozL10n.get('unknownAlbum');albumOrTitleBdi.dataset.l10nId=data.metadata.album?'':'unknownAlbum';}else{albumOrTitleBdi.textContent=data.metadata.title||navigator.mozL10n.get('unknownTitle');albumOrTitleBdi.dataset.l10nId=data.metadata.title?'':'unknownTitle';}
artistBdi.textContent=data.metadata.artist||navigator.mozL10n.get('unknownArtist');artistBdi.dataset.l10nId=data.metadata.artist?'':'unknownArtist';if(highlight){highlightText(albumOrTitleBdi,highlight);}
a.appendChild(albumOrTitleBdi);a.appendChild(artistBdi);}
a.dataset.keyRange=data.metadata[option];a.dataset.option=option;break;case'song':case'song-index':var songTitle=data.metadata.title||navigator.mozL10n.get('unknownTitle');var indexBdi=document.createElement('bdi');indexBdi.className='list-song-index';if(option==='song-index'){indexBdi.textContent=index+1;}else{var trackNum=data.metadata.tracknum;if(data.metadata.discnum&&data.multidisc){trackNum=data.metadata.discnum+'.'+
(trackNum<10?'0'+trackNum:trackNum);}
indexBdi.textContent=trackNum;}
titleBdi=document.createElement('bdi');titleBdi.className='list-song-title';titleBdi.textContent=songTitle;titleBdi.dataset.l10nId=data.metadata.title?'':'unknownTitle';var lengthBdi=document.createElement('bdi');lengthBdi.className='list-song-length';a.appendChild(indexBdi);a.appendChild(titleBdi);a.appendChild(lengthBdi);break;}
return li;}
function showImage(image,url,option){image.classList.remove(option);image.src='';if(option==='fadeIn'){image.style.opacity=0;}
image.addEventListener('load',handler);function handler(evt){evt.target.removeEventListener('load',handler);image.classList.add(option);}
image.src=url;};'use strict';var PlaybackQueue=(function(){var SETTINGS_OPTION_KEY='settings_option_key';var Repeat={OFF:0,LIST:1,SONG:2,next:function(val){return(val+1)%3;}};function posmod(a,b){var r=a%b;return r<0?r+b:r;}
function fillIndices(length){var indices=new Array(length);for(var i=0;i<length;i++){indices[i]=i;}
return indices;}
function shuffle(list){for(var i=list.length-1;i>=1;i--){var j=Math.floor(Math.random()*(i+1));if(j<i){var tmp=list[j];list[j]=list[i];list[i]=tmp;}}}
function BaseQueue(){this._index=null;}
BaseQueue.prototype={_init:function(index){if(this.length===0){throw Error('cannot have an empty queue');}
this._index=index||0;this._shuffle(playbackSettings.shuffle,index!==undefined);},_shuffle:function(enabled,keepIndex=true){this._shuffleTime=Date.now();if(!enabled){if(keepIndex){this._index=this.index;}
delete this._shuffledList;return;}
this._shuffledList=fillIndices(this.length);var oldIndex=null;if(keepIndex){oldIndex=this._shuffledList.splice(this._index,1)[0];this._index=0;}
shuffle(this._shuffledList);if(keepIndex){this._shuffledList.unshift(oldIndex);}},next:function(automatic=false){return this.advance(1,automatic);},previous:function(){this.advance(-1);},advance:function(offset,automatic=false){var next;var justShuffled=false;if(this._shuffleTime<shuffleTime){this._shuffle(playbackSettings.shuffle);justShuffled=true;}
switch(PlaybackQueue.repeat){case Repeat.OFF:next=Math.max(this._index+offset,0);break;case Repeat.LIST:next=posmod(this._index+offset,this.length);var cycled=next!==this._index+offset;if(playbackSettings.shuffle&&cycled&&!justShuffled){this._shuffle(true);}
break;case Repeat.SONG:next=automatic?this._index:Math.max(this._index+offset,0);break;default:throw new Error('unexpected repeat status: '+this.repeat);}
if(next>=this.length){this._index=null;return false;}
this._index=next;return true;},get index(){return this._shuffledList?this._shuffledList[this._index]:this._index;},get rawIndex(){return this._index;}};function StaticQueue(fileinfos,index){this._fileinfos=fileinfos;this._init(index);}
StaticQueue.prototype=new BaseQueue();Object.defineProperty(StaticQueue.prototype,'length',{get:function(){return this._fileinfos.length;}});StaticQueue.prototype.current=function(){return Promise.resolve(this._fileinfos[this.index]);};function DynamicQueue(query,index){this._query=query;this._init(index);}
DynamicQueue.prototype=new BaseQueue();Object.defineProperty(DynamicQueue.prototype,'length',{get:function(){return this._query.count;}});DynamicQueue.prototype.current=function(){var query=this._query;return new Promise((resolve,reject)=>{var handle=Database.advancedEnumerate(query.key,query.range,query.direction,this.index,(record)=>{Database.cancelEnumeration(handle);resolve(record);});});};var playbackSettings=null;var shuffleTime=0;function loadSettings(){return new Promise((resolve,reject)=>{asyncStorage.getItem(SETTINGS_OPTION_KEY,(settings)=>{if(settings){playbackSettings=settings;}else{playbackSettings={repeat:Repeat.OFF,shuffle:false};}
resolve();});});}
function saveSettings(){return new Promise((resolve,reject)=>{asyncStorage.setItem(SETTINGS_OPTION_KEY,playbackSettings,()=>{resolve();});});}
return{StaticQueue:StaticQueue,DynamicQueue:DynamicQueue,Repeat:Repeat,loadSettings:loadSettings,get repeat(){return playbackSettings.repeat;},set repeat(val){playbackSettings.repeat=val;saveSettings();return val;},get shuffle(){return playbackSettings.shuffle;},set shuffle(val){playbackSettings.shuffle=val;shuffleTime=Date.now();saveSettings();return val;},};})();;'use strict';var TYPE_LIST='list';var TYPE_SINGLE='single';var PLAYSTATUS_STOPPED='STOPPED';var PLAYSTATUS_PLAYING='PLAYING';var PLAYSTATUS_PAUSED='PAUSED';var PLAYSTATUS_FWD_SEEK='FWD_SEEK';var PLAYSTATUS_REV_SEEK='REV_SEEK';var INTERRUPT_BEGIN='mozinterruptbegin';var PlayerView={_repeatModes:['off','list','song'],get view(){return document.getElementById('views-player');},get audio(){return document.getElementById('player-audio');},get foreCoverImage(){return document.querySelector('.cover-image.visible');},get backCoverImage(){return document.querySelector('.cover-image:not(.visible)');},get playStatus(){return this._playStatus;},set playStatus(val){this._playStatus=val;},get isQueued(){return Boolean(this.queue&&this.queue.length);},init:function pv_init(type=TYPE_LIST,autoplay=true){this.artist=document.getElementById('player-cover-artist');this.album=document.getElementById('player-cover-album');this.artistText=document.querySelector('#player-cover-artist bdi');this.albumText=document.querySelector('#player-cover-album bdi');this.timeoutID;this.cover=document.getElementById('player-cover');this.coverImageURL=null;this.shareButton=document.getElementById('player-cover-share');this.repeatButton=document.getElementById('player-album-repeat');this.shuffleButton=document.getElementById('player-album-shuffle');this.ratings=document.getElementById('player-album-rating').children;this.seekSlider=document.getElementById('player-seek');this.seekRegion=document.getElementById('player-seek-bar');this.seekBar=document.getElementById('player-seek-bar-progress');this.seekIndicator=document.getElementById('player-seek-bar-indicator');this.seekElapsed=document.getElementById('player-seek-elapsed');this.seekRemaining=document.getElementById('player-seek-remaining');this.playControl=document.getElementById('player-controls-play');this.previousControl=document.getElementById('player-controls-previous');this.nextControl=document.getElementById('player-controls-next');this.banner=document.getElementById('info-banner');this.isTouching=false;this.isFastSeeking=false;this.playStatus=PLAYSTATUS_STOPPED;this.pausedPosition=null;this.handle=null;this.currentFileInfo=null;this.playingBlob=null;this.setSeekBar(0,0);this.intervalID=null;this.view.addEventListener('click',this);this.view.addEventListener('contextmenu',this);this.seekRegion.addEventListener('touchstart',this);this.seekRegion.addEventListener('touchmove',this);this.seekRegion.addEventListener('touchend',this);this.seekSlider.addEventListener('keypress',this);this.previousControl.addEventListener('touchend',this);this.nextControl.addEventListener('touchend',this);this.audio.addEventListener('play',this);this.audio.addEventListener('pause',this);this.audio.addEventListener('playing',this);this.audio.addEventListener('durationchange',this);this.audio.addEventListener('timeupdate',this);this.audio.addEventListener('ended',this);this.audio.addEventListener('mozinterruptbegin',this);this.audio.addEventListener('mozinterruptend',this);window.addEventListener('visibilitychange',this);window.addEventListener('storage',this._handleInterpageMessage.bind(this));navigator.mozL10n.ready(this.updateL10n.bind(this));this.type=type;this.autoplay=autoplay;if(this.type===TYPE_SINGLE){this.shuffleButton.disabled=true;this.repeatButton.disabled=true;this.previousControl.disabled=true;this.nextControl.disabled=true;}},checkSCOStatus:function pv_checkSCOStatus(){if(typeof MusicComms!=='undefined'&&MusicComms.enabled){var SCOStatus=MusicComms.isSCOEnabled;this.playControl.disabled=this.previousControl.disabled=this.nextControl.disabled=SCOStatus;this.seekRegion.parentNode.classList.toggle('disabled',SCOStatus);this.banner.classList.toggle('visible',SCOStatus);}},clean:function pv_clean(){if(this.handle){Database.cancelEnumeration(this.handle);}
this.queue=null;this.playingBlob=null;this.coverImageURL=null;this.foreCoverImage.style.backgroundImage='';},activate:function pv_activate(queue){this.queue=queue;this.shuffleButton.disabled=(this.queue.length<2);this.setRepeat(PlaybackQueue.repeat);this.setShuffle(PlaybackQueue.shuffle);},showInfo:function pv_showInfo(){this.cover.classList.add('slideOut');if(this.timeoutID){window.clearTimeout(this.timeoutID);}
this.timeoutID=window.setTimeout(function pv_hideInfo(){this.cover.classList.remove('slideOut');}.bind(this),5000);},setInfo:function pv_setInfo(fileinfo){this.currentFileInfo=fileinfo;var metadata=fileinfo.metadata;if(typeof ModeManager!=='undefined'){ModeManager.playerTitle=metadata.title;ModeManager.updateTitle();if(metadata.locked||this.type===TYPE_SINGLE){this.shareButton.classList.add('hidden');this.artist.classList.add('hidden-cover-share');this.album.classList.add('hidden-cover-share');}else{this.shareButton.classList.remove('hidden');this.artist.classList.remove('hidden-cover-share');this.album.classList.remove('hidden-cover-share');}}else{var titleBar=document.querySelector('#title-text bdi');titleBar.textContent=metadata.title||navigator.mozL10n.get('unknownTitle');titleBar.dataset.l10nId=metadata.title?'':'unknownTitle';}
this.artistText.textContent=metadata.artist||navigator.mozL10n.get('unknownArtist');this.artistText.dataset.l10nId=metadata.artist?'':'unknownArtist';this.albumText.textContent=metadata.album||navigator.mozL10n.get('unknownAlbum');this.albumText.dataset.l10nId=metadata.album?'':'unknownAlbum';this.setCoverImage(fileinfo);},setCoverImage:function pv_setCoverImage(fileinfo){LazyLoader.load('js/metadata/album_art_cache.js').then(()=>{return AlbumArtCache.getFullSizeURL(fileinfo);}).then((url)=>{if(this.coverImageURL!==url){this.coverImageURL=url;var back=this.backCoverImage,fore=this.foreCoverImage;back.style.backgroundImage='url('+url+')';back.classList.add('visible');fore.classList.remove('visible');}});},getRepeat:function pv_getRepeat(){return this._repeatModes.indexOf(this.repeatButton.value);},setRepeat:function pv_setRepeat(value){this.repeatButton.value=this._repeatModes[value];this.repeatButton.setAttribute('data-l10n-id','repeat-'+this._repeatModes[value]);},setShuffle:function pv_setShuffle(value){this.shuffleButton.classList.toggle('shuffle-on',value);this.shuffleButton.setAttribute('aria-pressed',value);},setRatings:function pv_setRatings(rated){for(var i=0;i<5;i++){var rating=this.ratings[i];if(i===rated-1){rating.setAttribute('aria-checked',true);}else{rating.setAttribute('aria-checked',false);}
if(i<rated){rating.classList.add('star-on');}else{rating.classList.remove('star-on');}}},setAudioSrc:function pv_setAudioSrc(file){var url=URL.createObjectURL(file);this.playingBlob=file;this.audio.removeAttribute('src');this.audio.load();this.audio.mozAudioChannelType='content';this.audio.src=url;this.audio.load();this.audio.play();this.audio.onloadeddata=function(evt){URL.revokeObjectURL(url);};this.audio.onerror=(function(evt){if(this.onerror){this.onerror(evt);}}).bind(this);this.setSeekBar(0,0);},updateRemoteMetadata:function pv_updateRemoteMetadata(){if(typeof MusicComms==='undefined'||this.queue.length===0){return;}
var metadata=this.currentFileInfo.metadata;var notifyMetadata={title:metadata.title||navigator.mozL10n.get('unknownTitle'),artist:metadata.artist||navigator.mozL10n.get('unknownArtist'),album:metadata.album||navigator.mozL10n.get('unknownAlbum'),duration:this.audio.duration*1000,mediaNumber:this.rawIndex+1,totalMediaCount:this.queue.length};if(this.audio.currentTime===0){LazyLoader.load('js/metadata/album_art_cache.js').then(()=>{return AlbumArtCache.getThumbnailBlob(this.currentFileInfo);}).then((blob)=>{notifyMetadata.picture=blob;MusicComms.notifyMetadataChanged(notifyMetadata);});}else{MusicComms.notifyMetadataChanged(notifyMetadata);}},updateRemotePlayStatus:function pv_updateRemotePlayStatus(){if(typeof MusicComms==='undefined'){return;}
var position=this.pausedPosition?this.pausedPosition:this.audio.currentTime;var info={playStatus:this.playStatus,duration:this.audio.duration*1000,position:position*1000};this.pausedPosition=(this.playStatus===PLAYSTATUS_PLAYING)?null:this.audio.currentTime;MusicComms.notifyStatusChanged(info);},PLAYER_IS_OCCUPIED_BY:'music-player-is-occupied-by',_handleInterpageMessage:function(evt){if(evt.key===this.PLAYER_IS_OCCUPIED_BY){if(evt.newValue&&evt.newValue!==location.href){this.pause();}}},_sendInterpageMessage:function(){window.localStorage.setItem(this.PLAYER_IS_OCCUPIED_BY,location.href);},_clearInterpageMessage:function(){var whoIsPlaying=window.localStorage.getItem(this.PLAYER_IS_OCCUPIED_BY);if(whoIsPlaying&&whoIsPlaying===window.location.href){window.localStorage.removeItem(this.PLAYER_IS_OCCUPIED_BY);}},start:function pv_start(autoplay=true){this.checkSCOStatus();this._sendInterpageMessage();this.showInfo();this.queue.current().then((songData)=>{this.setInfo(songData);if(songData.blob){return songData.blob;}
this.setRatings(songData.metadata.rated);Database.incrementPlayCount(songData);return Database.getFile(songData,true);}).then((file)=>{this.setAudioSrc(file);if(!autoplay||!this.autoplay||MusicComms.isSCOEnabled){this.pause();}}).catch(function(msg){console.error(msg);});},play:function pv_play(targetIndex){this.checkSCOStatus();this._sendInterpageMessage();this.showInfo();if(this.audio.duration>20&&this.audio.duration-this.audio.currentTime<1){this.next(true);}else{this.audio.play();}},pause:function pv_pause(){this.checkSCOStatus();this._clearInterpageMessage();this.audio.pause();},stop:function pv_stop(){this.pause();this.audio.removeAttribute('src');this.audio.load();this.clean();if(typeof ModeManager!=='undefined'){ModeManager.playerTitle=null;if(ModeManager.currentMode===MODE_PLAYER){ModeManager.pop();}else{ModeManager.updateTitle();ModeManager.updatePlayerIcon();}}
this.playStatus=PLAYSTATUS_STOPPED;this.updateRemotePlayStatus();},next:function pv_next(isAutomatic){if(this.type===TYPE_SINGLE){this.start(false);}else if(this.queue.next(isAutomatic)){this.start();}else{this.stop();}},previous:function pv_previous(){if(this.audio.currentTime<=3){this.queue.previous();}
this.start();},startFastSeeking:function pv_startFastSeeking(direction){this.isTouching=this.isFastSeeking=true;var offset=direction*2;this.prevPlayStatus=this.playStatus;this.playStatus=direction?PLAYSTATUS_FWD_SEEK:PLAYSTATUS_REV_SEEK;this.updateRemotePlayStatus();this.intervalID=window.setInterval(function(){this.seekAudio(this.audio.currentTime+offset);}.bind(this),15);},stopFastSeeking:function pv_stopFastSeeking(){this.isTouching=this.isFastSeeking=false;if(this.intervalID){window.clearInterval(this.intervalID);}
this.playStatus=this.prevPlayStatus;this.prevPlayStatus=null;this.updateRemotePlayStatus();},updateSeekBar:function pv_updateSeekBar(){if(this.isTouching){return;}
if(typeof ModeManager==='undefined'||ModeManager.currentMode===MODE_PLAYER){this.seekAudio();}},seekAudio:function pv_seekAudio(seekTime){if(seekTime!==undefined){this.audio.currentTime=Math.floor(seekTime);}
this.setSeekBar(this.audio.duration,this.audio.currentTime);},setSeekBar:function pv_setSeekBar(endTime,currentTime){if(this.seekBar.max!=endTime){navigator.mozL10n.setAttributes(this.seekSlider,'playbackSeekBar',{'duration':formatTime(endTime)});}
this.seekBar.max=isFinite(endTime)?endTime:0;this.seekBar.value=currentTime;var formattedCurrentTime=formatTime(currentTime);this.seekSlider.setAttribute('aria-valuetext',formattedCurrentTime);this.seekSlider.setAttribute('aria-valuemax',this.seekBar.max);this.seekSlider.setAttribute('aria-valuenow',currentTime);var ratio=(isFinite(endTime)&&endTime!==0)?(currentTime/endTime):0;var x=(ratio*this.seekBar.offsetWidth-
this.seekIndicator.offsetWidth/2);if(this.isLTR){x=x+'px';}else{if(x<0){x=Math.abs(x)+'px';}else{x='-'+x+'px';}}
this.seekIndicator.style.transform='translateX('+x+')';this.seekElapsed.textContent=formattedCurrentTime;var remainingTime=endTime-currentTime;this.seekRemaining.textContent=(remainingTime>0)?'-'+formatTime(remainingTime):'---:--';},share:function pv_shareFile(){var songData=this.currentFileInfo;if(songData.metadata.locked){return;}
LazyLoader.load('js/metadata/album_art_cache.js').then(()=>{return Promise.all([Database.getFile(songData),AlbumArtCache.getThumbnailBlob(songData)]);}).then(function([file,pictureBlob]){var filename=songData.name,name=filename.substring(filename.lastIndexOf('/')+1);var activityData={type:'audio/*',number:1,blobs:[file],filenames:[name],filepaths:[filename],metadata:[{title:songData.metadata.title,artist:songData.metadata.artist,album:songData.metadata.album,picture:pictureBlob}]};if(PlayerView.playStatus!==PLAYSTATUS_PLAYING){var a=new MozActivity({name:'share',data:activityData});a.onerror=function(e){console.warn('share activity error:',a.error.name);};}
else{(function(){var hack_activity_property='_hack_hack_shut_up';var hack_setting_property='music._hack.pause_please';navigator.mozSettings.addObserver(hack_setting_property,observer);activityData[hack_activity_property]=hack_setting_property;var a=new MozActivity({name:'share',data:activityData});a.onerror=a.onsuccess=cleanup;function observer(e){PlayerView.pause();}
function cleanup(){navigator.mozSettings.removeObserver(hack_setting_property,observer);if(PlayerView.playStatus===PLAYSTATUS_PAUSED){PlayerView.play();}}}());}});},handleEvent:function pv_handleEvent(evt){var target=evt.target;if(!target){return;}
switch(evt.type){case'click':switch(target.id){case'player-cover':case'player-cover-image-1':case'player-cover-image-2':this.showInfo();break;case'player-controls-play':if(this.playControl.classList.contains('is-pause')){this.play();}else{this.pause();}
break;case'player-album-repeat':this.showInfo();var repeat=PlaybackQueue.Repeat.next(this.getRepeat());PlaybackQueue.repeat=repeat;this.setRepeat(repeat);break;case'player-album-shuffle':this.showInfo();var shuffle=!target.classList.contains('shuffle-on');PlaybackQueue.shuffle=shuffle;this.setShuffle(shuffle);break;case'player-cover-share':this.share();break;}
if(target.dataset.rating){this.showInfo();var songData=this.currentFileInfo;var targetRating=parseInt(target.dataset.rating,10);var newRating=(targetRating===songData.metadata.rated)?targetRating-1:targetRating;Database.setSongRating(songData,newRating);this.setRatings(newRating);}
break;case'play':this.playControl.classList.remove('is-pause');this.playStatus=PLAYSTATUS_PLAYING;this.playControl.setAttribute('data-l10n-id','playbackPause');this.updateRemotePlayStatus();break;case'pause':this.playControl.classList.add('is-pause');this.playStatus=PLAYSTATUS_PAUSED;this.playControl.setAttribute('data-l10n-id','playbackPlay');this.updateRemotePlayStatus();break;case'touchstart':case'touchmove':if(evt.type==='touchstart'){this.isTouching=true;this.seekIndicator.classList.add('highlight');}
if(this.isTouching&&this.audio.duration>0){var touch=evt.touches[0];var x=(touch.clientX-target.offsetLeft)/target.offsetWidth;if(x<0){x=0;}
if(x>1){x=1;}
if(this.isLTR){this.seekTime=x*this.seekBar.max;}else{this.seekTime=this.audio.duration-x*this.seekBar.max;}
this.setSeekBar(this.audio.duration,this.seekTime);}
break;case'touchend':if(this.isFastSeeking){this.stopFastSeeking();}else if(target.id==='player-seek-bar'){this.seekIndicator.classList.remove('highlight');if(this.audio.duration>0&&this.isTouching){this.seekAudio(this.seekTime);this.seekTime=0;}
this.isTouching=false;}else if(target.id==='player-controls-previous'){this.previous();}else if(target.id==='player-controls-next'){this.next();}
break;case'keypress':var step=Math.max(this.audio.duration/20,2);if(evt.keyCode==evt.DOM_VK_DOWN){this.seekAudio(this.audio.currentTime-step);}else if(evt.keyCode==evt.DOM_VK_UP){this.seekAudio(this.audio.currentTime+step);}
break;case'contextmenu':if(target.id==='player-controls-next'){this.startFastSeeking(1);}else if(target.id==='player-controls-previous'){this.startFastSeeking(-1);}
break;case'durationchange':case'timeupdate':this.updateSeekBar();if(evt.type==='durationchange'||this.audio.currentTime===0){this.updateRemoteMetadata();}
break;case'ended':this.next(true);break;case'visibilitychange':if(document.hidden){this.audio.removeEventListener('timeupdate',this);}else{this.audio.addEventListener('timeupdate',this);this.updateSeekBar();}
break;case'mozinterruptbegin':this.playStatus=INTERRUPT_BEGIN;this.updateRemotePlayStatus();break;case'mozinterruptend':this.playStatus=PLAYSTATUS_PLAYING;this.updateRemotePlayStatus();break;default:return;}},updateL10n:function pv_updateL10n(){this.isLTR=navigator.mozL10n.language.direction==='ltr'?true:false;}};;'use strict';navigator.mozL10n.once(function onLocalizationInit(){navigator.mozSetMessageHandler('activity',handleOpenActivity);});function handleOpenActivity(request){var data=request.source.data;var blob=request.source.data.blob;var header=document.getElementById('header');var saveButton=document.getElementById('title-save');var banner=document.getElementById('banner');var message=document.getElementById('message');var storage;var saved=false;if(data.allowSave&&data.filename&&checkFilename()){saveButton.hidden=false;saveButton.disabled=true;header.runFontFit();getStorageIfAvailable('music',blob.size,function(ds){storage=ds;saveButton.disabled=false;});}
playBlob(blob);function playBlob(blob){PlayerView.init(TYPE_SINGLE);PlayerView.stop();PlaybackQueue.loadSettings().then(()=>{return AudioMetadata.parse(blob);}).then((metadata)=>{var fileinfo={metadata:metadata,name:blob.name,blob:blob};PlayerView.activate(new PlaybackQueue.StaticQueue([fileinfo]));PlayerView.start();}).catch((e)=>{console.error(e);alert(navigator.mozL10n.get('audioinvalid'));done();});}
header.addEventListener('action',done);saveButton.addEventListener('click',save);window.addEventListener('visibilitychange',function onVisibilityChanged(){if(document.hidden){done();}});function done(){PlayerView.stop();request.postResult({saved:saved});}
function save(){saveButton.hidden=true;document.getElementById('title-text').textContent=document.getElementById('title-text').textContent;getUnusedFilename(storage,data.filename,function(filename){var savereq=storage.addNamed(blob,filename);savereq.onsuccess=function(){saved=filename;showBanner(navigator.mozL10n.get('saved',{title:document.getElementById('title-text').textContent}));};savereq.onerror=function(e){console.error('Error saving',filename,e);};});}
function checkFilename(){var dotIdx=data.filename.lastIndexOf('.'),ext;if(dotIdx>-1){ext=data.filename.substr(dotIdx+1);if(ext==='ogg'){return true;}else{return MimeMapper.guessTypeFromExtension(ext)===blob.type;}}else{return false;}}
function showBanner(msg){message.textContent=msg;banner.hidden=false;setTimeout(function(){banner.hidden=true;},3000);}}

View file

@ -0,0 +1,249 @@
;(function(window,undefined){'use strict';function L10nError(message,id,loc){this.name='L10nError';this.message=message;this.id=id;this.loc=loc;}
L10nError.prototype=Object.create(Error.prototype);L10nError.prototype.constructor=L10nError;var io={_load:function(type,url,callback,sync){var xhr=new XMLHttpRequest();var needParse;if(xhr.overrideMimeType){xhr.overrideMimeType(type);}
xhr.open('GET',url,!sync);if(type==='application/json'){if(sync){needParse=true;}else{xhr.responseType='json';}}
xhr.addEventListener('load',function io_onload(e){if(e.target.status===200||e.target.status===0){var res=e.target.response||e.target.responseText;callback(null,needParse?JSON.parse(res):res);}else{callback(new L10nError('Not found: '+url));}});xhr.addEventListener('error',callback);xhr.addEventListener('timeout',callback);try{xhr.send(null);}catch(e){if(e.name==='NS_ERROR_FILE_NOT_FOUND'){callback(new L10nError('Not found: '+url));}else{throw e;}}},load:function(url,callback,sync){return io._load('text/plain',url,callback,sync);},loadJSON:function(url,callback,sync){return io._load('application/json',url,callback,sync);}};function EventEmitter(){}
EventEmitter.prototype.emit=function ee_emit(){if(!this._listeners){return;}
var args=Array.prototype.slice.call(arguments);var type=args.shift();if(!this._listeners[type]){return;}
var typeListeners=this._listeners[type].slice();for(var i=0;i<typeListeners.length;i++){typeListeners[i].apply(this,args);}};EventEmitter.prototype.addEventListener=function ee_add(type,listener){if(!this._listeners){this._listeners={};}
if(!(type in this._listeners)){this._listeners[type]=[];}
this._listeners[type].push(listener);};EventEmitter.prototype.removeEventListener=function ee_rm(type,listener){if(!this._listeners){return;}
var typeListeners=this._listeners[type];var pos=typeListeners.indexOf(listener);if(pos===-1){return;}
typeListeners.splice(pos,1);};function getPluralRule(lang){var locales2rules={'af':3,'ak':4,'am':4,'ar':1,'asa':3,'az':0,'be':11,'bem':3,'bez':3,'bg':3,'bh':4,'bm':0,'bn':3,'bo':0,'br':20,'brx':3,'bs':11,'ca':3,'cgg':3,'chr':3,'cs':12,'cy':17,'da':3,'de':3,'dv':3,'dz':0,'ee':3,'el':3,'en':3,'eo':3,'es':3,'et':3,'eu':3,'fa':0,'ff':5,'fi':3,'fil':4,'fo':3,'fr':5,'fur':3,'fy':3,'ga':8,'gd':24,'gl':3,'gsw':3,'gu':3,'guw':4,'gv':23,'ha':3,'haw':3,'he':2,'hi':4,'hr':11,'hu':0,'id':0,'ig':0,'ii':0,'is':3,'it':3,'iu':7,'ja':0,'jmc':3,'jv':0,'ka':0,'kab':5,'kaj':3,'kcg':3,'kde':0,'kea':0,'kk':3,'kl':3,'km':0,'kn':0,'ko':0,'ksb':3,'ksh':21,'ku':3,'kw':7,'lag':18,'lb':3,'lg':3,'ln':4,'lo':0,'lt':10,'lv':6,'mas':3,'mg':4,'mk':16,'ml':3,'mn':3,'mo':9,'mr':3,'ms':0,'mt':15,'my':0,'nah':3,'naq':7,'nb':3,'nd':3,'ne':3,'nl':3,'nn':3,'no':3,'nr':3,'nso':4,'ny':3,'nyn':3,'om':3,'or':3,'pa':3,'pap':3,'pl':13,'ps':3,'pt':3,'rm':3,'ro':9,'rof':3,'ru':11,'rwk':3,'sah':0,'saq':3,'se':7,'seh':3,'ses':0,'sg':0,'sh':11,'shi':19,'sk':12,'sl':14,'sma':7,'smi':7,'smj':7,'smn':7,'sms':7,'sn':3,'so':3,'sq':3,'sr':11,'ss':3,'ssy':3,'st':3,'sv':3,'sw':3,'syr':3,'ta':3,'te':3,'teo':3,'th':0,'ti':4,'tig':3,'tk':3,'tl':4,'tn':3,'to':0,'tr':0,'ts':3,'tzm':22,'uk':11,'ur':3,'ve':3,'vi':0,'vun':3,'wa':4,'wae':3,'wo':0,'xh':3,'xog':3,'yo':0,'zh':0,'zu':3};function isIn(n,list){return list.indexOf(n)!==-1;}
function isBetween(n,start,end){return typeof n===typeof start&&start<=n&&n<=end;}
var pluralRules={'0':function(){return'other';},'1':function(n){if((isBetween((n%100),3,10))){return'few';}
if(n===0){return'zero';}
if((isBetween((n%100),11,99))){return'many';}
if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'2':function(n){if(n!==0&&(n%10)===0){return'many';}
if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'3':function(n){if(n===1){return'one';}
return'other';},'4':function(n){if((isBetween(n,0,1))){return'one';}
return'other';},'5':function(n){if((isBetween(n,0,2))&&n!==2){return'one';}
return'other';},'6':function(n){if(n===0){return'zero';}
if((n%10)===1&&(n%100)!==11){return'one';}
return'other';},'7':function(n){if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'8':function(n){if((isBetween(n,3,6))){return'few';}
if((isBetween(n,7,10))){return'many';}
if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'9':function(n){if(n===0||n!==1&&(isBetween((n%100),1,19))){return'few';}
if(n===1){return'one';}
return'other';},'10':function(n){if((isBetween((n%10),2,9))&&!(isBetween((n%100),11,19))){return'few';}
if((n%10)===1&&!(isBetween((n%100),11,19))){return'one';}
return'other';},'11':function(n){if((isBetween((n%10),2,4))&&!(isBetween((n%100),12,14))){return'few';}
if((n%10)===0||(isBetween((n%10),5,9))||(isBetween((n%100),11,14))){return'many';}
if((n%10)===1&&(n%100)!==11){return'one';}
return'other';},'12':function(n){if((isBetween(n,2,4))){return'few';}
if(n===1){return'one';}
return'other';},'13':function(n){if((isBetween((n%10),2,4))&&!(isBetween((n%100),12,14))){return'few';}
if(n!==1&&(isBetween((n%10),0,1))||(isBetween((n%10),5,9))||(isBetween((n%100),12,14))){return'many';}
if(n===1){return'one';}
return'other';},'14':function(n){if((isBetween((n%100),3,4))){return'few';}
if((n%100)===2){return'two';}
if((n%100)===1){return'one';}
return'other';},'15':function(n){if(n===0||(isBetween((n%100),2,10))){return'few';}
if((isBetween((n%100),11,19))){return'many';}
if(n===1){return'one';}
return'other';},'16':function(n){if((n%10)===1&&n!==11){return'one';}
return'other';},'17':function(n){if(n===3){return'few';}
if(n===0){return'zero';}
if(n===6){return'many';}
if(n===2){return'two';}
if(n===1){return'one';}
return'other';},'18':function(n){if(n===0){return'zero';}
if((isBetween(n,0,2))&&n!==0&&n!==2){return'one';}
return'other';},'19':function(n){if((isBetween(n,2,10))){return'few';}
if((isBetween(n,0,1))){return'one';}
return'other';},'20':function(n){if((isBetween((n%10),3,4)||((n%10)===9))&&!(isBetween((n%100),10,19)||isBetween((n%100),70,79)||isBetween((n%100),90,99))){return'few';}
if((n%1000000)===0&&n!==0){return'many';}
if((n%10)===2&&!isIn((n%100),[12,72,92])){return'two';}
if((n%10)===1&&!isIn((n%100),[11,71,91])){return'one';}
return'other';},'21':function(n){if(n===0){return'zero';}
if(n===1){return'one';}
return'other';},'22':function(n){if((isBetween(n,0,1))||(isBetween(n,11,99))){return'one';}
return'other';},'23':function(n){if((isBetween((n%10),1,2))||(n%20)===0){return'one';}
return'other';},'24':function(n){if((isBetween(n,3,10)||isBetween(n,13,19))){return'few';}
if(isIn(n,[2,12])){return'two';}
if(isIn(n,[1,11])){return'one';}
return'other';}};var index=locales2rules[lang.replace(/-.*$/,'')];if(!(index in pluralRules)){return function(){return'other';};}
return pluralRules[index];}
var MAX_PLACEABLES=100;var PropertiesParser={patterns:null,entryIds:null,init:function(){this.patterns={comment:/^\s*#|^\s*$/,entity:/^([^=\s]+)\s*=\s*(.*)$/,multiline:/[^\\]\\$/,index:/\{\[\s*(\w+)(?:\(([^\)]*)\))?\s*\]\}/i,unicode:/\\u([0-9a-fA-F]{1,4})/g,entries:/[^\r\n]+/g,controlChars:/\\([\\\n\r\t\b\f\{\}\"\'])/g,placeables:/\{\{\s*([^\s]*?)\s*\}\}/,};},parse:function(ctx,source){if(!this.patterns){this.init();}
var ast=[];this.entryIds=Object.create(null);var entries=source.match(this.patterns.entries);if(!entries){return ast;}
for(var i=0;i<entries.length;i++){var line=entries[i];if(this.patterns.comment.test(line)){continue;}
while(this.patterns.multiline.test(line)&&i<entries.length){line=line.slice(0,-1)+entries[++i].trim();}
var entityMatch=line.match(this.patterns.entity);if(entityMatch){try{this.parseEntity(entityMatch[1],entityMatch[2],ast);}catch(e){if(ctx){ctx._emitter.emit('parseerror',e);}else{throw e;}}}}
return ast;},parseEntity:function(id,value,ast){var name,key;var pos=id.indexOf('[');if(pos!==-1){name=id.substr(0,pos);key=id.substring(pos+1,id.length-1);}else{name=id;key=null;}
var nameElements=name.split('.');if(nameElements.length>2){throw new L10nError('Error in ID: "'+name+'".'+' Nested attributes are not supported.');}
var attr;if(nameElements.length>1){name=nameElements[0];attr=nameElements[1];if(attr[0]==='$'){throw new L10nError('Attribute can\'t start with "$"',id);}}else{attr=null;}
this.setEntityValue(name,attr,key,this.unescapeString(value),ast);},setEntityValue:function(id,attr,key,rawValue,ast){var pos,v;var value=rawValue.indexOf('{{')>-1?this.parseString(rawValue):rawValue;if(attr){pos=this.entryIds[id];if(pos===undefined){v={$i:id};if(key){v[attr]={};v[attr][key]=value;}else{v[attr]=value;}
ast.push(v);this.entryIds[id]=ast.length-1;return;}
if(key){if(typeof(ast[pos][attr])==='string'){ast[pos][attr]={$x:this.parseIndex(ast[pos][attr]),$v:{}};}
ast[pos][attr].$v[key]=value;return;}
ast[pos][attr]=value;return;}
if(key){pos=this.entryIds[id];if(pos===undefined){v={};v[key]=value;ast.push({$i:id,$v:v});this.entryIds[id]=ast.length-1;return;}
if(typeof(ast[pos].$v)==='string'){ast[pos].$x=this.parseIndex(ast[pos].$v);ast[pos].$v={};}
ast[pos].$v[key]=value;return;}
ast.push({$i:id,$v:value});this.entryIds[id]=ast.length-1;},parseString:function(str){var chunks=str.split(this.patterns.placeables);var complexStr=[];var len=chunks.length;var placeablesCount=(len-1)/2;if(placeablesCount>=MAX_PLACEABLES){throw new L10nError('Too many placeables ('+placeablesCount+', max allowed is '+MAX_PLACEABLES+')');}
for(var i=0;i<chunks.length;i++){if(chunks[i].length===0){continue;}
if(i%2===1){complexStr.push({t:'idOrVar',v:chunks[i]});}else{complexStr.push(chunks[i]);}}
return complexStr;},unescapeString:function(str){if(str.lastIndexOf('\\')!==-1){str=str.replace(this.patterns.controlChars,'$1');}
return str.replace(this.patterns.unicode,function(match,token){return unescape('%u'+'0000'.slice(token.length)+token);});},parseIndex:function(str){var match=str.match(this.patterns.index);if(!match){throw new L10nError('Malformed index');}
if(match[2]){return[{t:'idOrVar',v:match[1]},match[2]];}else{return[{t:'idOrVar',v:match[1]}];}}};var KNOWN_MACROS=['plural'];var MAX_PLACEABLE_LENGTH=2500;var rePlaceables=/\{\{\s*(.+?)\s*\}\}/g;var nonLatin1=/[^\x01-\xFF]/;var FSI='\u2068';var PDI='\u2069';function createEntry(node,env){var keys=Object.keys(node);if(typeof node.$v==='string'&&keys.length===2){return node.$v;}
var attrs;for(var i=0,key;key=keys[i];i++){if(key[0]==='$'){continue;}
if(!attrs){attrs=Object.create(null);}
attrs[key]=createAttribute(node[key],env,node.$i+'.'+key);}
return{id:node.$i,value:node.$v!==undefined?node.$v:null,index:node.$x||null,attrs:attrs||null,env:env,dirty:false};}
function createAttribute(node,env,id){if(typeof node==='string'){return node;}
return{id:id,value:node.$v||(node!==undefined?node:null),index:node.$x||null,env:env,dirty:false};}
function format(args,entity){if(typeof entity==='string'){return[{},entity];}
if(entity.dirty){throw new L10nError('Cyclic reference detected: '+entity.id);}
entity.dirty=true;var rv;try{rv=resolveValue({},args,entity.env,entity.value,entity.index);}finally{entity.dirty=false;}
return rv;}
function resolveIdentifier(args,env,id){if(KNOWN_MACROS.indexOf(id)>-1){return[{},env['__'+id]];}
if(args&&args.hasOwnProperty(id)){if(typeof args[id]==='string'||(typeof args[id]==='number'&&!isNaN(args[id]))){return[{},args[id]];}else{throw new L10nError('Arg must be a string or a number: '+id);}}
if(id in env&&id!=='__proto__'){return format(args,env[id]);}
throw new L10nError('Unknown reference: '+id);}
function subPlaceable(locals,args,env,id){var res;try{res=resolveIdentifier(args,env,id);}catch(err){return[{error:err},'{{ '+id+' }}'];}
var value=res[1];if(typeof value==='number'){return res;}
if(typeof value==='string'){if(value.length>=MAX_PLACEABLE_LENGTH){throw new L10nError('Too many characters in placeable ('+
value.length+', max allowed is '+
MAX_PLACEABLE_LENGTH+')');}
if(locals.contextIsNonLatin1||value.match(nonLatin1)){res[1]=FSI+value+PDI;}
return res;}
return[{},'{{ '+id+' }}'];}
function interpolate(locals,args,env,arr){return arr.reduce(function(prev,cur){if(typeof cur==='string'){return[prev[0],prev[1]+cur];}else if(cur.t==='idOrVar'){var placeable=subPlaceable(locals,args,env,cur.v);return[prev[0],prev[1]+placeable[1]];}},[locals,'']);}
function resolveSelector(args,env,expr,index){var selectorName=index[0].v;var selector=resolveIdentifier(args,env,selectorName)[1];if(typeof selector!=='function'){return selector;}
var argValue=index[1]?resolveIdentifier(args,env,index[1])[1]:undefined;if(selector===env.__plural){if(argValue===0&&'zero'in expr){return'zero';}
if(argValue===1&&'one'in expr){return'one';}
if(argValue===2&&'two'in expr){return'two';}}
return selector(argValue);}
function resolveValue(locals,args,env,expr,index){if(!expr){return[locals,expr];}
if(typeof expr==='string'||typeof expr==='boolean'||typeof expr==='number'){return[locals,expr];}
if(Array.isArray(expr)){locals.contextIsNonLatin1=expr.some(function($_){return typeof($_)==='string'&&$_.match(nonLatin1);});return interpolate(locals,args,env,expr);}
if(index){var selector=resolveSelector(args,env,expr,index);if(expr.hasOwnProperty(selector)){return resolveValue(locals,args,env,expr[selector]);}}
if('other'in expr){return resolveValue(locals,args,env,expr.other);}
throw new L10nError('Unresolvable value');}
var Resolver={createEntry:createEntry,format:format,rePlaceables:rePlaceables};function walkContent(node,fn){if(typeof node==='string'){return fn(node);}
if(node.t==='idOrVar'){return node;}
var rv=Array.isArray(node)?[]:{};var keys=Object.keys(node);for(var i=0,key;(key=keys[i]);i++){if(key==='$i'||key==='$x'){rv[key]=node[key];}else{rv[key]=walkContent(node[key],fn);}}
return rv;}
var reAlphas=/[a-zA-Z]/g;var reVowels=/[aeiouAEIOU]/g;var ACCENTED_MAP='\u0226\u0181\u0187\u1E12\u1E16\u0191\u0193\u0126\u012A'+'\u0134\u0136\u013F\u1E3E\u0220\u01FE\u01A4\u024A\u0158'+'\u015E\u0166\u016C\u1E7C\u1E86\u1E8A\u1E8E\u1E90'+'[\\]^_`'+'\u0227\u0180\u0188\u1E13\u1E17\u0192\u0260\u0127\u012B'+'\u0135\u0137\u0140\u1E3F\u019E\u01FF\u01A5\u024B\u0159'+'\u015F\u0167\u016D\u1E7D\u1E87\u1E8B\u1E8F\u1E91';var FLIPPED_MAP='\u2200\u0510\u2183p\u018E\u025F\u05E4HI\u017F'+'\u04FC\u02E5WNO\u0500\xD2\u1D1AS\u22A5\u2229\u0245'+'\uFF2DX\u028EZ'+'[\\]\u1D65_,'+'\u0250q\u0254p\u01DD\u025F\u0183\u0265\u0131\u027E'+'\u029E\u0285\u026Fuodb\u0279s\u0287n\u028C\u028Dx\u028Ez';function makeLonger(val){return val.replace(reVowels,function(match){return match+match.toLowerCase();});}
function replaceChars(map,val){return val.replace(reAlphas,function(match){return map.charAt(match.charCodeAt(0)-65);});}
var reWords=/[^\W0-9_]+/g;function makeRTL(val){return val.replace(reWords,function(match){return'\u202e'+match+'\u202c';});}
var reExcluded=/(%[EO]?\w|\{\s*.+?\s*\}|&[#\w]+;|<\s*.+?\s*>)/;function mapContent(fn,val){if(!val){return val;}
var parts=val.split(reExcluded);var modified=parts.map(function(part){if(reExcluded.test(part)){return part;}
return fn(part);});return modified.join('');}
function Pseudo(id,name,charMap,modFn){this.id=id;this.translate=mapContent.bind(null,function(val){return replaceChars(charMap,modFn(val));});this.name=this.translate(name);}
var PSEUDO={'fr-x-psaccent':new Pseudo('fr-x-psaccent','Runtime Accented',ACCENTED_MAP,makeLonger),'ar-x-psbidi':new Pseudo('ar-x-psbidi','Runtime Bidi',FLIPPED_MAP,makeRTL)};function Locale(id,ctx){this.id=id;this.ctx=ctx;this.isReady=false;this.entries=Object.create(null);this.entries.__plural=getPluralRule(this.isPseudo()?this.ctx.defaultLocale:id);}
Locale.prototype.isPseudo=function(){return this.ctx.qps.indexOf(this.id)!==-1;};var bindingsIO={extra:function(id,ver,path,type,callback,errback){if(type==='properties'){type='text';}
navigator.mozApps.getLocalizationResource(id,ver,path,type).then(callback.bind(null,null),errback);},app:function(id,ver,path,type,callback,errback,sync){switch(type){case'properties':io.load(path,callback,sync);break;case'json':io.loadJSON(path,callback,sync);break;}},};Locale.prototype.build=function L_build(callback){var sync=!callback;var ctx=this.ctx;var self=this;var l10nLoads=ctx.resLinks.length;function onL10nLoaded(err){if(err){ctx._emitter.emit('fetcherror',err);}
if(--l10nLoads<=0){self.isReady=true;if(callback){callback();}}}
if(l10nLoads===0){onL10nLoaded();return;}
function onJSONLoaded(err,json){if(!err&&json){self.addAST(json);}
onL10nLoaded(err);}
function onPropLoaded(err,source){if(!err&&source){var ast=PropertiesParser.parse(ctx,source);self.addAST(ast);}
onL10nLoaded(err);}
var idToFetch=this.isPseudo()?ctx.defaultLocale:this.id;var appVersion=null;var source='app';if(typeof(navigator)!=='undefined'){source=navigator.mozL10n._config.localeSources[this.id]||'app';appVersion=navigator.mozL10n._config.appVersion;}
for(var i=0;i<ctx.resLinks.length;i++){var resLink=decodeURI(ctx.resLinks[i]);var path=resLink.replace('{locale}',idToFetch);var type=path.substr(path.lastIndexOf('.')+1);var cb;switch(type){case'json':cb=onJSONLoaded;break;case'properties':cb=onPropLoaded;break;}
bindingsIO[source](this.id,appVersion,path,type,cb,onL10nLoaded,sync);}};function createPseudoEntry(node,entries){return Resolver.createEntry(walkContent(node,PSEUDO[this.id].translate),entries);}
Locale.prototype.addAST=function(ast){var createEntry=this.isPseudo()?createPseudoEntry.bind(this):Resolver.createEntry;for(var i=0;i<ast.length;i++){this.entries[ast[i].$i]=createEntry(ast[i],this.entries);}};function Context(id){this.id=id;this.isReady=false;this.isLoading=false;this.defaultLocale='en-US';this.availableLocales=[];this.supportedLocales=[];this.qps=[];this.resLinks=[];this.locales={};this._emitter=new EventEmitter();this._ready=new Promise(this.once.bind(this));}
function reportMissing(id,err){this._emitter.emit('notfounderror',err);return id;}
function getWithFallback(id){var cur=0;var loc;var locale;while(loc=this.supportedLocales[cur]){locale=this.getLocale(loc);if(!locale.isReady){locale.build(null);}
var entry=locale.entries[id];if(entry===undefined){cur++;reportMissing.call(this,id,new L10nError('"'+id+'"'+' not found in '+loc+' in '+this.id,id,loc));continue;}
return entry;}
throw new L10nError('"'+id+'"'+' missing from all supported locales in '+this.id,id);}
function formatTuple(args,entity){try{return Resolver.format(args,entity);}catch(err){this._emitter.emit('resolveerror',err);var locals={error:err};return[locals,entity.id];}}
function formatValue(args,entity){if(typeof entity==='string'){return entity;}
return formatTuple.call(this,args,entity)[1];}
function formatEntity(args,entity){var entityTuple=formatTuple.call(this,args,entity);var value=entityTuple[1];var formatted={value:value,attrs:null,};if(entity.attrs){formatted.attrs=Object.create(null);}
for(var key in entity.attrs){var attrTuple=formatTuple.call(this,args,entity.attrs[key]);formatted.attrs[key]=attrTuple[1];}
return formatted;}
function formatAsync(fn,id,args){return this._ready.then(getWithFallback.bind(this,id)).then(fn.bind(this,args),reportMissing.bind(this,id));}
Context.prototype.formatValue=function(id,args){return formatAsync.call(this,formatValue,id,args);};Context.prototype.formatEntity=function(id,args){return formatAsync.call(this,formatEntity,id,args);};function legacyGet(fn,id,args){if(!this.isReady){throw new L10nError('Context not ready');}
var entry;try{entry=getWithFallback.call(this,id);}catch(err){if(err.loc){throw err;}
reportMissing.call(this,id,err);return'';}
return fn.call(this,args,entry);}
Context.prototype.get=function(id,args){return legacyGet.call(this,formatValue,id,args);};Context.prototype.getEntity=function(id,args){return legacyGet.call(this,formatEntity,id,args);};Context.prototype.getLocale=function getLocale(code){var locales=this.locales;if(locales[code]){return locales[code];}
return locales[code]=new Locale(code,this);};function negotiate(available,requested,defaultLocale){var supportedLocale;for(var i=0;i<requested.length;i++){var locale=requested[i];if(available.indexOf(locale)!==-1){supportedLocale=locale;break;}}
if(!supportedLocale||supportedLocale===defaultLocale){return[defaultLocale];}
return[supportedLocale,defaultLocale];}
function freeze(supported){var locale=this.getLocale(supported[0]);if(locale.isReady){setReady.call(this,supported);}else{locale.build(setReady.bind(this,supported));}}
function setReady(supported){this.supportedLocales=supported;this.isReady=true;this._emitter.emit('ready');}
Context.prototype.registerLocales=function(defLocale,available){if(defLocale){this.defaultLocale=defLocale;}
this.availableLocales=[this.defaultLocale];this.qps=Object.keys(PSEUDO);if(available){for(var i=0,loc;loc=available[i];i++){if(this.availableLocales.indexOf(loc)===-1){this.availableLocales.push(loc);var pos=this.qps.indexOf(loc);if(pos!==-1){this.qps.splice(pos,1);}}}}};Context.prototype.requestLocales=function requestLocales(){if(this.isLoading&&!this.isReady){throw new L10nError('Context not ready');}
this.isLoading=true;var requested=Array.prototype.slice.call(arguments);if(requested.length===0){throw new L10nError('No locales requested');}
var supported=negotiate(this.availableLocales.concat(this.qps),requested,this.defaultLocale);if(this.supportedLocales[0]!==supported[0]){freeze.call(this,supported);}};Context.prototype.addEventListener=function(type,listener){this._emitter.addEventListener(type,listener);};Context.prototype.removeEventListener=function(type,listener){this._emitter.removeEventListener(type,listener);};Context.prototype.ready=function(callback){if(this.isReady){setTimeout(callback);}
this.addEventListener('ready',callback);};Context.prototype.once=function(callback){if(this.isReady){setTimeout(callback);return;}
var callAndRemove=(function(){this.removeEventListener('ready',callAndRemove);callback();}).bind(this);this.addEventListener('ready',callAndRemove);};var allowed={elements:['a','em','strong','small','s','cite','q','dfn','abbr','data','time','code','var','samp','kbd','sub','sup','i','b','u','mark','ruby','rt','rp','bdi','bdo','span','br','wbr'],attributes:{global:['title','aria-label','aria-valuetext','aria-moz-hint'],a:['download'],area:['download','alt'],input:['alt','placeholder'],menuitem:['label'],menu:['label'],optgroup:['label'],option:['label'],track:['label'],img:['alt'],textarea:['placeholder'],th:['abbr']}};var rtlList=['ar','he','fa','ps','ar-x-psbidi','ur'];var nodeObserver=null;var pendingElements=null;var moConfig={attributes:true,characterData:false,childList:true,subtree:true,attributeFilter:['data-l10n-id','data-l10n-args']};navigator.mozL10n={ctx:null,get:function get(id,ctxdata){return navigator.mozL10n.ctx.get(id,ctxdata);},formatValue:function(id,ctxdata){return navigator.mozL10n.ctx.formatValue(id,ctxdata);},formatEntity:function(id,ctxdata){return navigator.mozL10n.ctx.formatEntity(id,ctxdata);},translateFragment:function(fragment){return translateFragment.call(navigator.mozL10n,fragment);},setAttributes:setL10nAttributes,getAttributes:getL10nAttributes,ready:function ready(callback){return navigator.mozL10n.ctx.ready(callback);},once:function once(callback){return navigator.mozL10n.ctx.once(callback);},get readyState(){return navigator.mozL10n.ctx.isReady?'complete':'loading';},language:{set code(lang){navigator.mozL10n.ctx.requestLocales(lang);},get code(){return navigator.mozL10n.ctx.supportedLocales[0];},get direction(){return getDirection(navigator.mozL10n.ctx.supportedLocales[0]);}},qps:PSEUDO,_config:{appVersion:null,localeSources:Object.create(null),isPretranslated:false,},_getInternalAPI:function(){return{Error:L10nError,Context:Context,Locale:Locale,Resolver:Resolver,getPluralRule:getPluralRule,rePlaceables:rePlaceables,translateDocument:translateDocument,onMetaInjected:onMetaInjected,PropertiesParser:PropertiesParser,walkContent:walkContent,buildLocaleList:buildLocaleList};}};function getDirection(lang){return(rtlList.indexOf(lang)>=0)?'rtl':'ltr';}
var readyStates={loading:0,interactive:1,complete:2};function whenInteractive(callback){if(readyStates[document.readyState]>=readyStates.interactive){callback();return;}
document.addEventListener('readystatechange',function l10n_onrsc(){if(readyStates[document.readyState]>=readyStates.interactive){document.removeEventListener('readystatechange',l10n_onrsc);callback();}});}
function initObserver(){nodeObserver=new MutationObserver(onMutations.bind(navigator.mozL10n));nodeObserver.observe(document,moConfig);}
function init(pretranslate){if(!pretranslate){initObserver();}
initResources.call(navigator.mozL10n);}
function initResources(){var meta={};var nodes=document.head.querySelectorAll('link[rel="localization"],'+'meta[name="availableLanguages"],'+'meta[name="defaultLanguage"],'+'meta[name="appVersion"],'+'script[type="application/l10n"]');for(var i=0,node;node=nodes[i];i++){var type=node.getAttribute('rel')||node.nodeName.toLowerCase();switch(type){case'localization':this.ctx.resLinks.push(node.getAttribute('href'));break;case'meta':onMetaInjected.call(this,node,meta);break;case'script':onScriptInjected.call(this,node);break;}}
var additionalLanguagesPromise;if(navigator.mozApps&&navigator.mozApps.getAdditionalLanguages){additionalLanguagesPromise=navigator.mozApps.getAdditionalLanguages().catch(function(e){console.error('Error while loading getAdditionalLanguages',e);});document.addEventListener('additionallanguageschange',function(evt){registerLocales.call(this,meta,evt.detail);this.ctx.requestLocales.apply(this.ctx,navigator.languages||[navigator.language]);}.bind(this));}else{additionalLanguagesPromise=Promise.resolve();}
additionalLanguagesPromise.then(function(extraLangs){registerLocales.call(this,meta,extraLangs);initLocale.call(this);}.bind(this));}
function registerLocales(meta,extraLangs){var locales=buildLocaleList.call(this,meta,extraLangs);navigator.mozL10n._config.localeSources=locales[1];this.ctx.registerLocales(locales[0],Object.keys(locales[1]));}
function getMatchingLangpack(appVersion,langpacks){for(var i=0,langpack;(langpack=langpacks[i]);i++){if(langpack.target===appVersion){return langpack;}}
return null;}
function buildLocaleList(meta,extraLangs){var loc,lp;var localeSources=Object.create(null);var defaultLocale=meta.defaultLanguage||this.ctx.defaultLocale;if(meta.availableLanguages){for(loc in meta.availableLanguages){localeSources[loc]='app';}}
if(extraLangs){for(loc in extraLangs){lp=getMatchingLangpack(this._config.appVersion,extraLangs[loc]);if(!lp){continue;}
if(!(loc in localeSources)||!meta.availableLanguages[loc]||parseInt(lp.revision)>meta.availableLanguages[loc]){localeSources[loc]='extra';}}}
if(!(defaultLocale in localeSources)){localeSources[defaultLocale]='app';}
return[defaultLocale,localeSources];}
function splitAvailableLanguagesString(str){var langs={};str.split(',').forEach(function(lang){lang=lang.trim().split(':');langs[lang[0]]=parseInt(lang[1]);});return langs;}
function onMetaInjected(node,meta){switch(node.getAttribute('name')){case'availableLanguages':meta.availableLanguages=splitAvailableLanguagesString(node.getAttribute('content'));break;case'defaultLanguage':meta.defaultLanguage=node.getAttribute('content');break;case'appVersion':navigator.mozL10n._config.appVersion=node.getAttribute('content');break;}}
function onScriptInjected(node){var lang=node.getAttribute('lang');var locale=this.ctx.getLocale(lang);locale.addAST(JSON.parse(node.textContent));}
function initLocale(){this.ctx.requestLocales.apply(this.ctx,navigator.languages||[navigator.language]);window.addEventListener('languagechange',function l10n_langchange(){this.ctx.requestLocales.apply(this.ctx,navigator.languages||[navigator.language]);}.bind(this));}
function localizeMutations(mutations){var mutation;var targets=new Set();for(var i=0;i<mutations.length;i++){mutation=mutations[i];if(mutation.type==='childList'){var addedNode;for(var j=0;j<mutation.addedNodes.length;j++){addedNode=mutation.addedNodes[j];if(addedNode.nodeType!==Node.ELEMENT_NODE){continue;}
targets.add(addedNode);}}
if(mutation.type==='attributes'){targets.add(mutation.target);}}
targets.forEach(function(target){if(target.childElementCount){translateFragment.call(this,target);}else if(target.hasAttribute('data-l10n-id')){translateElement.call(this,target);}},this);}
function onMutations(mutations,self){self.disconnect();localizeMutations.call(this,mutations);self.observe(document,moConfig);}
function onReady(){if(!navigator.mozL10n._config.isPretranslated){translateDocument.call(this);}
navigator.mozL10n._config.isPretranslated=false;if(pendingElements){for(var i=0,element;element=pendingElements[i];i++){translateElement.call(this,element);}
pendingElements=null;}
if(!nodeObserver){initObserver();}
fireLocalizedEvent.call(this);}
function fireLocalizedEvent(){var event=new CustomEvent('localized',{'bubbles':false,'cancelable':false,'detail':{'language':this.ctx.supportedLocales[0]}});window.dispatchEvent(event);}
var reOverlay=/<|&#?\w+;/;var reHtml=/[&<>]/g;var htmlEntities={'&':'&amp;','<':'&lt;','>':'&gt;',};function translateDocument(){document.documentElement.lang=this.language.code;document.documentElement.dir=this.language.direction;translateFragment.call(this,document.documentElement);}
function translateFragment(element){if(typeof element.hasAttribute==='function'&&element.hasAttribute('data-l10n-id')){translateElement.call(this,element);}
var nodes=getTranslatableChildren(element);for(var i=0;i<nodes.length;i++){translateElement.call(this,nodes[i]);}}
function setL10nAttributes(element,id,args){element.setAttribute('data-l10n-id',id);if(args){element.setAttribute('data-l10n-args',JSON.stringify(args));}}
function getL10nAttributes(element){return{id:element.getAttribute('data-l10n-id'),args:JSON.parse(element.getAttribute('data-l10n-args'))};}
function getTranslatableChildren(element){return element?element.querySelectorAll('*[data-l10n-id]'):[];}
function camelCaseToDashed(string){if(string==='ariaValueText'){return'aria-valuetext';}
return string.replace(/[A-Z]/g,function(match){return'-'+match.toLowerCase();}).replace(/^-/,'');}
function escapeL10nArgs(match){return htmlEntities[match];}
function translateElement(element){if(!this.ctx.isReady){if(!pendingElements){pendingElements=[];}
pendingElements.push(element);return;}
var l10nId=element.getAttribute('data-l10n-id');if(!l10nId){return false;}
var l10nArgs=element.getAttribute('data-l10n-args');var entity=this.ctx.getEntity(l10nId,l10nArgs?JSON.parse(l10nArgs.replace(reHtml,escapeL10nArgs)):undefined);var value=entity.value;if(typeof value==='string'){if(!reOverlay.test(value)){element.textContent=value;}else{var translation=element.ownerDocument.createElement('template');translation.innerHTML=value;overlayElement(element,translation.content);}}
for(var key in entity.attrs){var attrName=camelCaseToDashed(key);if(isAttrAllowed({name:attrName},element)){element.setAttribute(attrName,entity.attrs[key]);}}}
function overlayElement(sourceElement,translationElement){var result=translationElement.ownerDocument.createDocumentFragment();var k,attr;var childElement;while((childElement=translationElement.childNodes[0])){translationElement.removeChild(childElement);if(childElement.nodeType===Node.TEXT_NODE){result.appendChild(childElement);continue;}
var index=getIndexOfType(childElement);var sourceChild=getNthElementOfType(sourceElement,childElement,index);if(sourceChild){overlayElement(sourceChild,childElement);result.appendChild(sourceChild);continue;}
if(isElementAllowed(childElement)){var sanitizedChild=childElement.ownerDocument.createElement(childElement.nodeName);overlayElement(sanitizedChild,childElement);result.appendChild(sanitizedChild);continue;}
result.appendChild(document.createTextNode(childElement.textContent));}
sourceElement.textContent='';sourceElement.appendChild(result);if(translationElement.attributes){for(k=0,attr;(attr=translationElement.attributes[k]);k++){if(isAttrAllowed(attr,sourceElement)){sourceElement.setAttribute(attr.name,attr.value);}}}}
function isElementAllowed(element){return allowed.elements.indexOf(element.tagName.toLowerCase())!==-1;}
function isAttrAllowed(attr,element){var attrName=attr.name.toLowerCase();var tagName=element.tagName.toLowerCase();if(allowed.attributes.global.indexOf(attrName)!==-1){return true;}
if(!allowed.attributes[tagName]){return false;}
if(allowed.attributes[tagName].indexOf(attrName)!==-1){return true;}
if(tagName==='input'&&attrName==='value'){var type=element.type.toLowerCase();if(type==='submit'||type==='button'||type==='reset'){return true;}}
return false;}
function getNthElementOfType(context,element,index){var nthOfType=0;for(var i=0,child;child=context.children[i];i++){if(child.nodeType===Node.ELEMENT_NODE&&child.tagName===element.tagName){if(nthOfType===index){return child;}
nthOfType++;}}
return null;}
function getIndexOfType(element){var index=0;var child;while((child=element.previousElementSibling)){if(child.tagName===element.tagName){index++;}}
return index;}
var DEBUG=false;navigator.mozL10n.ctx=new Context(window.document?document.URL:null);navigator.mozL10n.ctx.ready(onReady.bind(navigator.mozL10n));navigator.mozL10n.ctx.addEventListener('notfounderror',function reportMissingEntity(e){if(DEBUG||e.loc==='en-US'){console.warn(e.toString());}});if(DEBUG){navigator.mozL10n.ctx.addEventListener('fetcherror',console.error.bind(console));navigator.mozL10n.ctx.addEventListener('parseerror',console.error.bind(console));navigator.mozL10n.ctx.addEventListener('resolveerror',console.error.bind(console));}
if(window.document){navigator.mozL10n._config.isPretranslated=document.documentElement.lang===navigator.language;var forcePretranslate=!navigator.mozL10n._config.isPretranslated;whenInteractive(init.bind(navigator.mozL10n,forcePretranslate));}
document.l10n={setAttributes:navigator.mozL10n.setAttributes,getAttributes:navigator.mozL10n.getAttributes,formatValue:function(id,args){return navigator.mozL10n.formatValue(id,args);},translateFragment:function(frag){return Promise.resolve(navigator.mozL10n.translateFragment(frag));},ready:new Promise(function(resolve){navigator.mozL10n.once(resolve);}),formatValues:function(){var keys=arguments;var resp=keys.map(function(key){if(Array.isArray(key)){return navigator.mozL10n.formatValue(key[0],key[1]);}
return navigator.mozL10n.formatValue(key);});return Promise.all(resp);},requestLanguages:function(langs){navigator.mozL10n.ctx.requestLocales.apply(navigator.mozL10n.ctx,langs);},pseudo:{'fr-x-psaccent':{getName:function(){return Promise.resolve(navigator.mozL10n.qps['fr-x-psaccent'].name);},processString:function(s){return Promise.resolve(navigator.mozL10n.qps['fr-x-psaccent'].translate(s));}},'ar-x-psbidi':{getName:function(){return Promise.resolve(navigator.mozL10n.qps['ar-x-psbidi'].name);},processString:function(s){return Promise.resolve(navigator.mozL10n.qps['ar-x-psbidi'].translate(s));}}},};navigator.mozL10n.ready(function(){document.documentElement.setAttribute('langs',navigator.mozL10n.ctx.supportedLocales.join(' '));});navigator.mozL10n.once(function(){window.addEventListener('localized',function(){document.dispatchEvent(new CustomEvent('DOMRetranslated',{bubbles:false,cancelable:false}));});});})(this);;'use strict';function getStorageIfAvailable(kind,size,success,error){var storage=navigator.getDeviceStorage(kind);storage.available().onsuccess=function(e){if(e.target.result!=='available'){if(error){error(e.target.result);}}
else{storage.freeSpace().onsuccess=function(e){if(e.target.result<size){if(error){error(e.target.result);}}
else{success(storage);}};}};};'use strict';function getUnusedFilename(storage,name,callback){var getreq=storage.get(name);getreq.onerror=function(){callback(name);};getreq.onsuccess=function(){var version=0;var p=name.lastIndexOf('/');var dir=name.substring(0,p+1);var file=name.substring(p+1);p=file.lastIndexOf('.');if(p===-1){p=file.length;}
var ext=file.substring(p);var base=file.substring(0,p);var parts=base.match(/^(.*)_(\d{1,2})$/);if(parts){base=parts[1];version=parseInt(parts[2]);}
var newname=dir+base+'_'+(version+1)+ext;getUnusedFilename(storage,newname,callback);};}

View file

@ -0,0 +1,215 @@
<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
<meta charset="utf-8">
<meta name="theme-group" content="theme-media">
<meta name="theme-color" content="var(--header-background)">
<title>Music OGA</title>
<!-- Include shared building blocks -->
<link rel="stylesheet" type="text/css" href="shared/elements/gaia-icons/gaia-icons.css">
<link rel="stylesheet" type="text/css" href="shared/elements/gaia-theme/gaia-theme.css">
<link rel="stylesheet" type="text/css" href="shared/style/confirm.css">
<link rel="stylesheet" type="text/css" href="shared/style/input_areas.css">
<link rel="stylesheet" type="text/css" href="shared/style/progress_activity.css">
<link rel="stylesheet" type="text/css" href="shared/style/status.css">
<link rel="stylesheet" type="text/css" href="shared/style/tabs.css">
<link rel="stylesheet" type="text/css" href="style/music.css">
<!-- Localization -->
<meta name="defaultLanguage" content="en-US">
<meta name="availableLanguages" content="ar:201601260730, bg:201601260730, bn-BD:201601260730, ca:201601260730, cs:201601260730, da:201601260730, de:201601260730, el:201601260730, en-US:201601260730, es:201601260730, eu:201601260730, fr:201601260730, gl:201601260730, hr:201601260730, hu:201601260730, it:201601260730, ja:201601260730, km:201601260730, ko:201601260730, lt:201601260730, mk:201601260730, ms:201601260730, ne-NP:201601260730, nl:201601260730, pa:201601260730, pl:201601260730, pt-BR:201601260730, ro:201601260730, ru:201601260730, sk:201601260730, sq:201601260730, sr-Cyrl:201601260730, sr-Latn:201601260730, sv-SE:201601260730, tr:201601260730, zh-CN:201601260730, zh-TW:201601260730">
<link rel="localization" href="/locales-obj/index.{locale}.json">
<!-- Shared code -->
<!-- <script defer="" src="shared/js/l10n.js"></script> -->
<!-- <script defer="" src="shared/js/mediadb.js"></script> -->
<!-- <script defer="" src="shared/js/lazy_loader.js"></script> -->
<!-- <script defer="" src="shared/js/font_size_utils.js"></script> -->
<!-- <script defer="" src="shared/js/accessibility_helper.js"></script> -->
<!-- <script defer="" src="shared/js/async_storage.js"></script> -->
<!-- <script defer="" src="shared/js/image_utils.js"></script> -->
<!-- <script defer="" src="shared/js/omadrm/fl.js"></script> -->
<!-- <script defer="" src="shared/js/sanitizer.js"></script> -->
<!-- Web components -->
<!-- <script defer="" src="shared/js/component_utils.js"></script> -->
<!-- <script defer="" src="shared/elements/gaia_subheader/script.js"></script> -->
<!-- <script defer="" src="shared/elements/gaia-header/dist/gaia-header.js"></script> -->
<!-- Specific code -->
<!-- <script defer="" src="js/utils.js"></script> -->
<!-- <script defer="" src="js/music.js"></script> -->
<!-- <script defer="" src="js/db.js"></script> -->
<!-- <script defer="" src="js/ui/title_bar.js"></script> -->
<!-- <script defer="" src="js/ui/tab_bar.js"></script> -->
<!-- <script defer="" src="js/ui/views/mode_manager.js"></script> --><script src="./gaia_build_defer_index.js" defer="" type="text/javascript"></script>
<!-- Lazy load code -->
<!--
<script defer src="shared/js/text_normalizer.js"></script>
<script defer src="shared/js/bluetooth_helper.js"></script>
<script defer src="shared/js/media/remote_controls.js"></script>
<script defer src="js/metadata/*.js"></script>
<script defer src="js/communications.js"></script>
<script defer src="js/ui/views/tiles_view.js"></script>
<script defer src="js/ui/views/list_view.js"></script>
<script defer src="js/ui/views/subList_view.js"></script>
<script defer src="js/ui/views/search_view.js"></script>
-->
<meta content="2.5" name="appVersion"></head>
<body role="application" class="theme-media">
<gaia-header id="title" action="back" no-font-fit="">
<h1 id="title-text"><bdi data-l10n-id="music">Music</bdi></h1>
<button aria-label="Go to player view" id="title-player" data-icon="play-circle" data-l10n-id="go-to-player-view" hidden=""></button>
<button id="title-done" data-l10n-id="done" hidden="">Done</button>
</gaia-header>
<div id="views">
<div id="views-tiles" class="view bb-tabpanel hidden" aria-labelledby="tabs-mix" role="tabpanel">
<form id="views-tiles-search" role="search" class="skin-dark">
<button id="views-tiles-search-close" data-l10n-id="search-close" type="submit">close</button>
<p>
<input id="views-tiles-search-input" dir="auto" x-inputmode="verbatim" data-l10n-id="search-music" placeholder="Search Music" type="search">
<button id="views-tiles-search-clear" type="reset">Clear</button>
</p>
</form>
<div id="views-tiles-anchor"></div>
</div>
<div id="views-list" class="view bb-tabpanel hidden" role="tabpanel">
<form id="views-list-search" role="search" class="skin-dark">
<button id="views-list-search-close" data-l10n-id="search-close" type="submit">close</button>
<p>
<input id="views-list-search-input" x-inputmode="verbatim" data-l10n-id="search-music" placeholder="Search Music" type="search">
<button id="views-list-search-clear" type="reset">Clear</button>
</p>
</form>
<div id="views-list-anchor" role="listbox"></div>
</div>
<div id="views-sublist" class="view hidden">
<div id="views-sublist-header">
<img id="views-sublist-header-image">
<div id="views-sublist-header-controls">
<bdi id="views-sublist-header-name">Name</bdi>
<button aria-label="Play" id="views-sublist-controls-play" class="album-controls-button" data-icon="play" data-l10n-id="playbackPlay"></button>
<button aria-label="Shuffle" id="views-sublist-controls-shuffle" class="album-controls-button" data-icon="shuffle" data-l10n-id="shuffle-toggle"></button>
</div>
</div>
<!-- Bug 968456. Scrollable area needs to be inside an opaque background div to help gecko -->
<div id="views-scrollable-sublist-anchor"><div id="views-sublist-anchor" role="listbox"></div></div>
</div>
<div id="views-player" class="view hidden">
<div id="player-cover">
<!-- We have two cover image elements so we can crossfade between
album art. -->
<div id="player-cover-image-1" class="cover-image visible"></div>
<div id="player-cover-image-2" class="cover-image"></div>
<div id="player-cover-caption">
<div id="player-cover-artist"><bdi data-l10n-id="songArtist">Song artist</bdi></div>
<div id="player-cover-album"><bdi data-l10n-id="songAlbum">Song album</bdi></div>
<button aria-label="Share" id="player-cover-share" class="player-cover-button" data-icon="share" data-l10n-id="share-song"></button>
</div>
<div id="player-cover-buttons">
<button aria-label="Repeat off" id="player-album-repeat" data-l10n-id="repeat-off" value="off" class="player-cover-button" data-icon="repeat"></button>
<div aria-label="Rating" id="player-album-rating" data-l10n-id="player-album-rating" role="radiogroup">
<button aria-label="1 stars" class="rating-star" data-rating="1" role="radio" data-l10n-id="rating-star" data-l10n-args="{&quot;n&quot;:&quot;1&quot;}"></button>
<button aria-label="2 stars" class="rating-star" data-rating="2" role="radio" data-l10n-id="rating-star" data-l10n-args="{&quot;n&quot;:&quot;2&quot;}"></button>
<button aria-label="3 stars" class="rating-star" data-rating="3" role="radio" data-l10n-id="rating-star" data-l10n-args="{&quot;n&quot;:&quot;3&quot;}"></button>
<button aria-label="4 stars" class="rating-star" data-rating="4" role="radio" data-l10n-id="rating-star" data-l10n-args="{&quot;n&quot;:&quot;4&quot;}"></button>
<button aria-label="5 stars" class="rating-star" data-rating="5" role="radio" data-l10n-id="rating-star" data-l10n-args="{&quot;n&quot;:&quot;5&quot;}"></button>
</div>
<button aria-label="Shuffle" id="player-album-shuffle" class="player-cover-button" data-icon="shuffle" aria-pressed="true" data-l10n-id="shuffle-toggle"></button>
</div>
<section id="info-banner" role="status">
<p data-l10n-id="music-paused-notification">Music paused during the call</p>
</section>
</div>
<div id="player-seek" role="slider" aria-valuemin="0">
<span id="player-seek-elapsed" dir="ltr">00:00</span>
<div id="player-seek-bar">
<progress id="player-seek-bar-progress" value="0"></progress>
<div id="player-seek-bar-indicator"></div>
</div>
<span id="player-seek-remaining" dir="ltr">00:00</span>
</div>
<div id="player-controls" dir="ltr">
<button aria-label="Previous" id="player-controls-previous" class="player-controls-button" data-icon="skip-back" data-l10n-id="playbackPrevious"></button>
<button aria-label="Pause" id="player-controls-play" class="player-controls-button is-pause" data-icon="pause" data-l10n-id="playbackPause"></button>
<button aria-label="Next" id="player-controls-next" class="player-controls-button" data-icon="skip-forward" data-l10n-id="playbackNext"></button>
</div>
<audio id="player-audio" class="hidden"></audio>
</div>
<div id="views-search" class="view hidden">
<form id="views-search-form" role="search" class="skin-dark">
<button id="views-search-close" data-l10n-id="search-close" type="submit">close</button>
<p>
<input id="views-search-input" dir="auto" x-inputmode="verbatim" data-l10n-id="search-music" placeholder="Search Music" type="search">
<button id="views-search-clear" type="reset">Clear</button>
</p>
</form>
<div id="views-search-no-result" class="search-category hidden">
<p id="search-no-result" data-l10n-id="search-no-result">No music found</p>
</div>
<div id="views-search-anchor">
<div id="views-search-artists" class="search-category hidden">
<gaia-subheader skin="dark">
<span data-l10n-id="search-artists">Artists</span>
(<span class="search-result-count"></span>)
</gaia-subheader>
<div class="search-results" role="listbox"></div>
</div>
<div id="views-search-albums" class="search-category hidden">
<gaia-subheader skin="dark">
<span data-l10n-id="search-albums">Albums</span>
(<span class="search-result-count"></span>)
</gaia-subheader>
<div class="search-results" role="listbox"></div>
</div>
<div id="views-search-titles" class="search-category hidden">
<gaia-subheader skin="dark">
<span data-l10n-id="search-titles">Tracks</span>
(<span class="search-result-count"></span>)
</gaia-subheader>
<div class="search-results" role="listbox"></div>
</div>
</div>
</div>
</div>
<!-- BB tabs -->
<div id="tabs">
<ul role="tablist" class="bb-tablist skin-dark">
<li id="mix" role="presentation">
<a aria-label="Mix" id="tabs-mix" data-option="mix" role="tab" tabindex="0" aria-selected="false" aria-controls="views-tiles" data-icon="grid" data-l10n-id="mix-tab"></a>
</li>
<li id="playlists" role="presentation">
<a aria-label="Playlists" id="tabs-playlists" data-option="playlist" role="tab" tabindex="0" aria-selected="false" aria-controls="views-list" data-icon="playlist" data-l10n-id="playlists-tab"></a>
</li>
<li id="artists" role="presentation">
<a aria-label="Artists" id="tabs-artists" data-option="artist" role="tab" tabindex="0" aria-selected="false" aria-controls="views-list" data-icon="artist" data-l10n-id="artists-tab"></a>
</li>
<li id="albums" role="presentation">
<a aria-label="Albums" id="tabs-albums" data-option="album" role="tab" tabindex="0" aria-selected="false" aria-controls="views-list" data-icon="album" data-l10n-id="albums-tab"></a>
</li>
<li id="songs" role="presentation">
<a aria-label="Songs" id="tabs-songs" data-option="title" role="tab" tabindex="0" aria-selected="false" aria-controls="views-list" data-icon="songs" data-l10n-id="songs-tab"></a>
</li>
</ul>
</div>
<!-- display scanning progress over the titlebar -->
<div id="scan-progress" class="hidden">
<progress id="scan-spinner" class="hidden"></progress>
<div id="scan-count"></div>
<div id="scan-artist-container"><bdi id="scan-artist"></bdi></div>
<div id="scan-title-container"><bdi id="scan-title"></bdi></div>
</div>
<!-- display messages like "Scanning", "No Songs" and "No SD Card" here -->
<form id="overlay" role="dialog" data-type="confirm" class="hidden">
<section id="overlay-content">
<h1 id="overlay-title"></h1>
<p id="overlay-text"></p>
</section>
<menu id="overlay-menu" class="hidden">
<button type="button" id="overlay-cancel-button" class="full" data-l10n-id="overlay-cancel-button">Cancel</button>
</menu>
</form>
<!-- display this at startup while we load music -->
<div id="spinner-overlay"><progress id="spinner"></progress></div>
</body>
</html>

View file

@ -0,0 +1,189 @@
/* exported MusicComms */
/* global Database, INTERRUPT_BEGIN, MediaRemoteControls, ModeManager,
MODE_PLAYER, PlaybackQueue, PlayerView, PLAYSTATUS_PLAYING,
PLAYSTATUS_STOPPED */
'use strict';
var MusicComms = {
commands: {
play: function(event) {
this.commands.playpause.call(this, event);
},
// For those bluetooth devices that do not keep, request or receive
// the play status, because the play status may not sync with the player,
// they will just send "play" or "playpause" when pressing the "playpause"
// button, so for the "play" and "playpause" commands, we will check
// the play status for the player then decide we should play or pause.
playpause: function(event) {
this._getPlayerReady(() => {
var isResumedBySCO = this.isSCOEnabled;
this.isSCOEnabled = event.detail.isSCOConnected;
// Check if it's resumed by the SCO disconnection, if so, we need to
// recover the player to the original status.
if (isResumedBySCO) {
if (this._statusBeforeSCO === PLAYSTATUS_PLAYING ||
this._statusBeforeSCO === INTERRUPT_BEGIN) {
PlayerView.play();
} else {
PlayerView.pause();
}
} else {
// Play in shuffle order if music app is launched remotely.
if (PlayerView.playStatus === PLAYSTATUS_STOPPED) {
Database.count('metadata.title', null, (count) => {
var info = {
key: 'metadata.title',
range: null,
direction: 'next',
option: 'title',
count: count
};
PlaybackQueue.shuffle = true;
PlayerView.activate(new PlaybackQueue.DynamicQueue(info));
PlayerView.start();
});
} else if (PlayerView.playStatus === PLAYSTATUS_PLAYING) {
PlayerView.pause();
} else {
PlayerView.play();
}
}
});
},
pause: function(event) {
this.isSCOEnabled = event.detail.isSCOConnected;
if (!this._isPlayerActivated()) {
return;
}
// Record the current play status so that we can recover the player to
// the original status after SCO is disconnected.
if (this.isSCOEnabled) {
this._statusBeforeSCO = PlayerView.playStatus;
}
PlayerView.pause();
},
stop: function(event) {
if (!this._isPlayerActivated()) {
return;
}
PlayerView.stop();
},
next: function(event) {
if (!this._isPlayerActivated()) {
return;
}
PlayerView.next();
},
previous: function(event) {
if (!this._isPlayerActivated()) {
return;
}
PlayerView.previous();
},
seekpress: function(event) {
if (!this._isPlayerActivated()) {
return;
}
if (!PlayerView.isTouching) {
PlayerView.startFastSeeking(event.detail.direction);
}
},
seekrelease: function(event) {
if (!this._isPlayerActivated()) {
return;
}
PlayerView.stopFastSeeking();
},
updatemetadata: function() {
// After A2DP is connected, some bluetooth devices will try to synchronize
// the playing metadata with the player, if the player is not ready, we
// have to initial the player to have the metadata, even the player is
// stopped.
this._getPlayerReady(function() {
PlayerView.updateRemoteMetadata();
});
},
updateplaystatus: function() {
// After A2DP is connected, some bluetooth devices will try to synchronize
// the playstatus with the player, if the player is not ready, we have to
// initial the player to have the play status.
this._getPlayerReady(function() {
PlayerView.updateRemotePlayStatus();
});
}
},
enabled: false,
isSCOEnabled: false,
_statusBeforeSCO: null,
init: function() {
// The Media Remote Controls object will handle the remote commands.
this.mrc = new MediaRemoteControls();
// Add command listeners base on what commands the MusicComms has.
for (var command in this.commands) {
this.mrc.addCommandListener(command, this.commands[command].bind(this));
}
// Update the SCO status after the mrc is ready, so that we can know the
// current SCO connection and reflect it to the player.
this.mrc.start(this.updateSCOStatus.bind(this));
this.mrc.notifyAppInfo({
origin: window.location.origin,
icon: window.location.origin + '/style/icons/default_84.png'
});
this.enabled = true;
},
_getPlayerReady: function(callback) {
ModeManager.waitForView(MODE_PLAYER, callback);
},
_isPlayerActivated: function() {
return (typeof PlayerView !== 'undefined' &&
PlayerView.playStatus !== PLAYSTATUS_STOPPED);
},
notifyMetadataChanged: function(metadata) {
if (this.enabled) {
this.mrc.notifyMetadataChanged(metadata);
}
},
notifyStatusChanged: function(info) {
if (this.enabled) {
this.mrc.notifyStatusChanged(info);
}
},
updateSCOStatus: function() {
if (this.enabled) {
this.mrc.getSCOStatus(function(status) {
this.isSCOEnabled = status;
}.bind(this));
}
}
};

View file

@ -0,0 +1,24 @@
;'use strict';var Database=(function(){var musicdb;function init(){var excludedFolders=['Ringtones','Notifications','Alarms'];var excludeFilter=new RegExp('^(/[^/]*/)?('+excludedFolders.join('|')+')/','i');musicdb=new MediaDB('music',metadataParserWrapper,{indexes:['metadata.album','metadata.artist','metadata.title','metadata.rated','metadata.played','date'],excludeFilter:excludeFilter,batchSize:1,autoscan:false,updateRecord:updateRecord,reparsedRecord:reparsedRecord,version:3});function metadataParserWrapper(file,onsuccess,onerror){var files=['/js/metadata_scripts.js','/js/metadata/album_art.js'];LazyLoader.load(files).then(()=>{return AudioMetadata.parse(file);}).then((metadata)=>{return AlbumArt.process(file,metadata);}).then(onsuccess,onerror);}
var startedReparsing=false;function updateRecord(record,oldVersion,newVersion){if(oldVersion===2){record.needsReparse=true;if(!startedReparsing){startedReparsing=true;App.showOverlay('upgrade');}}
return record.metadata;}
function reparsedRecord(oldMetadata,newMetadata){newMetadata.rated=oldMetadata.rated;newMetadata.played=oldMetadata.played;return newMetadata;}
musicdb.onupgrading=function(event){App.showOverlay('upgrade');};musicdb.onunavailable=function(event){var why;switch(event.detail){case MediaDB.NOCARD:why='nocard';break;case MediaDB.UNMOUNTED:why='unmounted';break;}
App.dbUnavailable(why);};musicdb.oncardremoved=function(){App.dbUnavailable('cardremoved');};musicdb.onenumerable=startupOnEnumerable;var refreshOnReady=false;function startupOnEnumerable(){App.dbEnumerable(function(){if(musicdb.state===MediaDB.READY){onReady();}else{musicdb.onready=onReady;}});}
function onReady(){App.dbReady(refreshOnReady,function(){musicdb.scan();});refreshOnReady=true;}
var filesDeletedWhileScanning=0;var filesFoundWhileScanning=0;var filesFoundBatch=0;var scanning=false;var SCAN_UPDATE_BATCH_SIZE=25;var DELETE_BATCH_TIMEOUT=500;var deleteTimer=null;var firstScanDone=false;musicdb.onscanstart=function(){scanning=true;filesFoundWhileScanning=0;filesFoundBatch=0;filesDeletedWhileScanning=0;};musicdb.onscanend=function(){scanning=false;TitleBar.hideScanProgress();if(filesFoundBatch>0||filesDeletedWhileScanning>0){filesFoundWhileScanning=0;filesFoundBatch=0;filesDeletedWhileScanning=0;App.refreshViews();}
if(!firstScanDone){firstScanDone=true;window.performance.mark('fullyLoaded');}};musicdb.oncreated=function(event){if(scanning){var metadata=event.detail[0].metadata;var n=event.detail.length;filesFoundWhileScanning+=n;filesFoundBatch+=n;TitleBar.showScanProgress({count:filesFoundWhileScanning,artist:metadata.artist,title:metadata.title});if(filesFoundBatch>SCAN_UPDATE_BATCH_SIZE){filesFoundBatch=0;App.refreshViews();}}
else{App.refreshViews();}};musicdb.ondeleted=function(event){if(scanning){filesDeletedWhileScanning+=event.detail.length;}
else{if(deleteTimer){clearTimeout(deleteTimer);}
deleteTimer=setTimeout(function(){deleteTimer=null;App.refreshViews();},DELETE_BATCH_TIMEOUT);}};}
function incrementPlayCount(fileinfo){fileinfo.metadata.played++;musicdb.updateMetadata(fileinfo.name,{played:fileinfo.metadata.played});}
function setSongRating(fileinfo,rated){fileinfo.metadata.rated=rated;musicdb.updateMetadata(fileinfo.name,{rated:fileinfo.metadata.rated});}
function getFile(fileinfo,decrypt=false){return new Promise((resolve,reject)=>{musicdb.getFile(fileinfo.name,(file)=>{if(file){resolve(file);}else{reject('unable to get file: '+fileinfo.name);}});}).then((blob)=>{if(!decrypt||!fileinfo.metadata.locked){return blob;}
return new Promise(function(resolve,reject){ForwardLock.getKey(function(secret){ForwardLock.unlockBlob(secret,blob,resolve,null,reject);});});});}
function enumerate(...args){return musicdb.enumerate(...args);}
function enumerateAll(...args){return musicdb.enumerateAll(...args);}
function advancedEnumerate(...args){return musicdb.advancedEnumerate(...args);}
function count(...args){return musicdb.count(...args);}
function search(key,query,callback){query=Normalizer.toAscii(query.toLocaleLowerCase());var direction=(key==='title')?'next':'nextunique';return musicdb.enumerate('metadata.'+key,null,direction,(result)=>{if(result===null){callback(result);return;}
var resultLowerCased=result.metadata[key].toLocaleLowerCase();if(Normalizer.toAscii(resultLowerCased).indexOf(query)!==-1){callback(result);}});}
function cancelEnumeration(handle){musicdb.cancelEnumeration(handle);}
return{init:init,incrementPlayCount:incrementPlayCount,setSongRating:setSongRating,getFile:getFile,enumerate:enumerate,enumerateAll:enumerateAll,advancedEnumerate:advancedEnumerate,count:count,search:search,cancelEnumeration:cancelEnumeration,get initialScanComplete(){return musicdb.initialScanComplete;}};})();

View file

@ -0,0 +1,231 @@
/* exported AlbumArt */
'use strict';
/*
* Metadata describing the cover art for a track. Cover art comes in one of
* three flavors: embedded (stored in the audio track's metadata), unsynced
* (like embedded, but stored in an unsynchronized block of ID3 data; we
* ultimately save it in an external file), or external (stored as a separate
* file in the same directory as the audio track).
*
* @typedef {Object} Picture
* @property {String} flavor How the art was stored; one of "embedded",
* "unsynced", or "external".
* @property {Number} [start] The offset in bytes to where the picture is
* stored in the audio file; only applies when flavor="embedded".
* @property {Number} [end] The offset in bytes to the end of where the
* picture is stored in the audio file; only applies when flavor="embedded".
* @property {Number} [type] The mimetype of the picture; only applies when
* flavor="embedded".
* @property {String} [filename] The path on the filesystem to the original
* (full-size) picture; only applies when flavor="external" or "unsynced".
*/
var AlbumArt = (function() {
var pictureStorage = navigator.getDeviceStorage('pictures');
// A cache of metadata Picture objects for albums with external cover art. The
// key is the directory name for the song in question.
var externalCoverCache = {};
// A cache of filenames for saved cover art (generated from unsynced ID3
// tags). The value is the absolute path name.
var savedCoverCache = new Set();
/**
* Perform additional processing for cover art, such as checking for external
* artwork and saving temporary image blobs (for unsynchronized ID3 data).
*
* @param {Blob} blob The audio file.
* @param {Metadata} metadata The metadata for the file.
* @return {Promise} A Promise resolving to the metadata object with any
* additional cover art fields added as necessary.
*/
function process(blob, metadata) {
// If a blob isn't backed by an actual file, we can't do anything here
// except return what we have.
var filename = blob.name;
if (!filename) {
return Promise.resolve(metadata);
}
if (!metadata.picture) {
// We don't have any embedded album art; see if there's any external album
// art in the same directory.
var lastSlash = filename.lastIndexOf('/');
var dirName = filename.substring(0, lastSlash + 1);
// First, check if we've recently fetched this cover; if so, just use the
// cached results so we're not going out to the disk more than necessary.
if (dirName in externalCoverCache) {
metadata.picture = externalCoverCache[dirName];
return Promise.resolve(metadata);
}
// Try to find external album art using a handful of common names. The
// possibilities listed here appear to be the most common, based on a
// brief survey of what people use in the wild.
return new Promise(function(resolve, reject) {
var possibleFilenames = ['folder.jpg', 'cover.jpg', 'front.jpg'];
var tryFetchExternalCover = function(index) {
if (index === possibleFilenames.length) {
// We couldn't find any external album art.
externalCoverCache[dirName] = null;
resolve(metadata);
return;
}
var externalCoverFilename = dirName + possibleFilenames[index];
var getcoverrequest = pictureStorage.get(externalCoverFilename);
getcoverrequest.onsuccess = function() {
metadata.picture = { flavor: 'external',
filename: externalCoverFilename };
// Cache the picture object we generated to make things faster.
externalCoverCache[dirName] = metadata.picture;
resolve(metadata);
};
getcoverrequest.onerror = function() {
tryFetchExternalCover(index + 1);
};
};
tryFetchExternalCover(0);
});
} else if (metadata.picture.blob) {
// We have album art in a separate blob that we need to save somewhere.
// Two reasons :
// - we had an unsynced ID3 frame with the art and needed to de-unsync
// it.
// - we had album art from a VorbisComment.
//
// First, try to make a unique filename for the image based on the artist,
// album, and file size. The file size is essentially a poor man's
// checksum to make sure we aren't reusing an inappropriate image, such as
// if the user updated the embedded art.
var albumKey;
if (metadata.artist || metadata.album) {
// Don't let the artist or album strings be too long; VFAT has a maximum
// of 255 characters for the path, and we need some room for the rest of
// it!
var artist = (metadata.artist || '').substr(0, 64);
var album = (metadata.album || '').substr(0, 64);
albumKey = artist + '.' + album;
} else {
// If there's no album or artist, use the path to the file instead; we
// truncate from the end to help ensure uniqueness.
albumKey = filename.substr(-128);
}
var coverBlob = metadata.picture.blob;
delete metadata.picture.blob;
// coverBlob is always a JPEG or PNG.
var extension = coverBlob.type === 'image/jpeg' ? '.jpg' : '.png';
var imageFilename = vfatEscape(albumKey) + '.' + coverBlob.size +
extension;
var storageName = getStorageName(filename);
return checkSaveCover(coverBlob, imageFilename, storageName).then(
function(savedFile) {
metadata.picture.filename = savedFile;
return metadata;
}, function(err) {
delete metadata.picture;
return metadata;
}
);
} else {
// We have embedded album art! All the processing is already done, so we
// can just return.
return Promise.resolve(metadata);
}
}
/**
* Escape any characters that are illegal on the VFAT filesystem.
*
* @param {string} str The string to escape.
* @return {string} The escaped string.
*/
function vfatEscape(str) {
return str.replace(/["*\/:<>?\|]/g, '_');
}
/**
* Get the name of the storage area for an absolute filename, with leading
* and trailing slashes (e.g. '/sdcard/'). If the filename is relative,
* return the empty string (i.e. use the default storage area.)
*
* @param {string} filename The path to the file.
* @return {string} The file's storage area, or the empty string if the path
* was relative.
*/
function getStorageName(filename) {
// `filename` is usually a fully qualified name (perhaps something like
// /sdcard/Music/file.mp3). On desktop, it's a relative name, but desktop
// only has one storage area anyway.
if (filename[0] === '/') {
var slashIndex = filename.indexOf('/', 1);
if (slashIndex < 0) {
var err = Error('handleCoverArt: Bad filename: "' + filename + '"');
console.error(err);
return Promise.reject(err);
}
// Get the storage name, e.g. /sdcard/
return filename.substring(0, slashIndex + 1);
}
return '';
}
/**
* Check for the existence of an image on the audio file's storage area,
* and if it's not present, try to save it.
*
* @param {Blob} coverBlob The blob for the full-size cover art.
* @param {string} imageFilename A relative filename for the image.
* @param {string} storageName The name of the storage area too use for
* saving the image. May be an empty string or a path with trailing '/'.
* For instance, to store on the SD card, pass '/sdcard/'.
* @return {Promise} A Promise that resolves when finished, providing the
* filename of the saved image.
*/
function checkSaveCover(coverBlob, imageFilename, storageName) {
// We want to put the image in the same storage area as the audio track it's
// for. Since the audio track could be in any storage area, we examine its
// filename to get the storage name; the storage name is always the first
// part of the (absolute) filename, so we grab that and build an absolute
// path for the image. This will ensure that the generic deviceStorage we
// use for pictures ("pictureStorage") puts the image where we want it.
var imageAbsPath = storageName + '.music/covers/' + imageFilename;
if (savedCoverCache.has(imageAbsPath)) {
return Promise.resolve(imageAbsPath);
}
return new Promise(function(resolve, reject) {
var getrequest = pictureStorage.get(imageAbsPath);
// We already have the image. We're done!
getrequest.onsuccess = function() {
savedCoverCache.add(imageAbsPath);
resolve(imageAbsPath);
};
// We don't have the image yet. Let's save it.
getrequest.onerror = function() {
var saverequest = pictureStorage.addNamed(coverBlob, imageAbsPath);
saverequest.onerror = function() {
console.error('Could not save cover image', imageFilename);
};
// Don't bother waiting for saving to finish. Just return.
savedCoverCache.add(imageAbsPath);
resolve(imageAbsPath);
};
});
}
return {
process: process,
pictureStorage: pictureStorage
};
})();

View file

@ -0,0 +1,27 @@
;'use strict';var AlbumArtCache=(function(){var THUMBNAIL_WIDTH=300;var THUMBNAIL_HEIGHT=300;var L1Cache={'thumbnail':{},'fullsize':{}};function getFullSizeURL(fileinfo,noPlaceholder){if(!fileinfo.metadata.picture){return Promise.resolve(noPlaceholder?null:getDefaultCoverURL(fileinfo));}
var cacheKey=makeCacheKey(fileinfo);if(cacheKey&&cacheKey in L1Cache.fullsize){return Promise.resolve(L1Cache.fullsize[cacheKey]);}
return getAlbumArtBlob(fileinfo).then(function(blob){return makeAndCacheURL(cacheKey,blob,'fullsize');});}
function getFullSizeBlob(fileinfo,noPlaceholder){if(!fileinfo.metadata.picture){if(noPlaceholder){return Promise.resolve(null);}
return getBlobFromURL(getDefaultCoverURL(fileinfo));}
return getAlbumArtBlob(fileinfo);}
function getThumbnailURL(fileinfo,noPlaceholder){if(!fileinfo.metadata.picture){return Promise.resolve(noPlaceholder?null:getDefaultCoverURL(fileinfo));}
var cacheKey=makeCacheKey(fileinfo);if(cacheKey&&cacheKey in L1Cache.thumbnail){return Promise.resolve(L1Cache.thumbnail[cacheKey]);}
return checkL2Cache(cacheKey).then(function(cachedBlob){return cachedBlob||createThumbnail(cacheKey,fileinfo);}).then(function(blob){return makeAndCacheURL(cacheKey,blob,'thumbnail');});}
function getThumbnailBlob(fileinfo,noPlaceholder){if(!fileinfo.metadata.picture){if(noPlaceholder){return Promise.resolve(null);}
return getBlobFromURL(getDefaultCoverURL(fileinfo));}
var cacheKey=makeCacheKey(fileinfo);return checkL2Cache(cacheKey).then(function(cachedBlob){return cachedBlob||createThumbnail(cacheKey,fileinfo);});}
function getDefaultCoverURL(fileinfo){var metadata=fileinfo.metadata;var infoForHash=(!metadata.album&&!metadata.artist)?metadata.title:metadata.album+metadata.artist;var hashedNumber=(Math.abs(hash(infoForHash))%10)+1;return'/style/images/AlbumArt'+hashedNumber+'_small.png';}
function hash(str){var hashCode=0;if(str.length===0){return hashCode;}
for(var i=0;i<str.length;i++){var c=str.charCodeAt(i);hashCode=((hashCode<<5)-hashCode)+c;hashCode=hashCode&hashCode;}
return hashCode;}
function makeCacheKey(fileinfo){var metadata=fileinfo.metadata;if(metadata.picture.filename){return'external.'+metadata.picture.filename;}else if(metadata.picture.flavor==='embedded'){var album=metadata.album;var artist=metadata.artist;var size=metadata.picture.end-metadata.picture.start;if(album||artist){return'thumbnail.'+album+'.'+artist+'.'+size;}else{return'thumbnail.'+(fileinfo.name||fileinfo.blob.name);}}
return null;}
function checkL2Cache(cacheKey){if(!cacheKey){return Promise.resolve(null);}else{return new Promise(function(resolve,reject){asyncStorage.getItem(cacheKey,function(blob){resolve(blob);});});}}
function makeAndCacheURL(cacheKey,blob,type){var url=URL.createObjectURL(blob);if(cacheKey){L1Cache[type][cacheKey]=url;}
return url;}
function createThumbnail(cacheKey,fileinfo){return getAlbumArtBlob(fileinfo).then(function(blob){return ImageUtils.resizeAndCropToCover(blob,THUMBNAIL_WIDTH,THUMBNAIL_HEIGHT);}).then(function(thumbnailBlob){if(cacheKey){asyncStorage.setItem(cacheKey,thumbnailBlob);}
return thumbnailBlob;});}
function getAlbumArtBlob(fileinfo){var picture=fileinfo.metadata.picture;if(picture.blob){return Promise.resolve(picture.blob);}else if(picture.filename){return LazyLoader.load('/js/metadata/album_art.js').then(()=>{return new Promise((resolve,reject)=>{var getreq=AlbumArt.pictureStorage.get(picture.filename);getreq.onsuccess=function(){resolve(this.result);};getreq.onerror=function(){reject(this.error);};});});}else if(picture.start){return getSongBlob(fileinfo).then((blob)=>{return blob.slice(picture.start,picture.end,picture.type);});}else{var err=new Error('unknown picture flavor: '+picture.flavor);console.error(err);return Promise.reject(err);}}
function getSongBlob(fileinfo){if(fileinfo.blob){return Promise.resolve(fileinfo.blob);}else{return Database.getFile(fileinfo);}}
function getBlobFromURL(url){return new Promise(function(resolve,reject){var xhr=new XMLHttpRequest();xhr.open('GET',url,true);xhr.responseType='blob';xhr.onload=function(){resolve(xhr.response);};xhr.onerror=function(){reject(null);};xhr.send();});}
return{getFullSizeURL:getFullSizeURL,getFullSizeBlob:getFullSizeBlob,getThumbnailURL:getThumbnailURL,getThumbnailBlob:getThumbnailBlob};})();

View file

@ -0,0 +1,174 @@
/* global BlobView, MetadataFormats */
/* exported AudioMetadata */
'use strict';
// XXX We're hiding the fact that these are JSdoc comments because our linter
// refuses to accept "property" as a valid tag. Grumble grumble.
/*
* Metadata for a track.
*
* @typedef {Object} Metadata
* @property {String} tag_format The format of the tag (e.g. id3v2.4).
* @property {String} artist The track's artist.
* @property {String} album The track's album.
* @property {String} title The track's title.
* @property {Number} [tracknum] The number of the track on the album.
* @property {Number} [trackcount] The total number of tracks in the album.
* @property {Number} [discnum] The number of the disc on the album.
* @property {Number} [disccount] The total number of discs in the album.
* @property {Picture} [picture] The cover art, if any.
* @property {Number} rated The track's rating; starts at 0.
* @property {Number} played The track's play count; starts at 0.
*/
/**
* Parse the metadata for an audio file.
*/
var AudioMetadata = (function() {
/**
* Parse the specified blob and return a Promise with the metadata.
*
* @param {Blob} blob The audio file to parse.
* @return {Promise} A Promise returning the parsed metadata object.
*/
function parse(blob) {
var filename = blob.name;
// If blob.name exists, it should be an audio file from system
// otherwise it should be an audio blob that probably from network/process
// we can still parse it but we don't need to care about the filename
if (filename) {
// If the file is in the DCIM/ directory and has a .3gp extension
// then it is a video, not a music file and we ignore it
if (filename.slice(0, 5) === 'DCIM/' &&
filename.slice(-4).toLowerCase() === '.3gp') {
return Promise.reject('skipping 3gp video file');
}
}
// If the file is too small to be a music file then ignore it
if (blob.size < 128) {
return Promise.reject('file is empty or too small');
}
// Read the start of the file, figure out what kind it is, and call
// the appropriate parser. Start off with an 64kb chunk of data.
// If the metadata is in that initial chunk we won't have to read again.
return new Promise(function(resolve, reject) {
var headersize = Math.min(64 * 1024, blob.size);
BlobView.get(blob, 0, headersize, function(header, error) {
if (error) {
reject(error);
return;
}
try {
var parser = MetadataFormats.findParser(header);
var promise;
if (parser) {
promise = parser.parse(header);
} else {
// This is some kind of file that we don't know about.
// Let's see if we can play it.
promise = checkPlayability(blob);
}
resolve(promise.then(function(metadata) {
return addDefaultMetadata(metadata || {}, filename);
}));
} catch (e) {
console.error('AudioMetadata.parse:', e, e.stack);
reject(e);
}
});
});
}
/**
* Fill in any default metadata fields, such as a fallback for the title, and
* the rating/playcount.
*
* @param {Object} metadata The metadata from one of our parsers.
* @param {String} filename The name of the underlying file, if any.
* @return {Object} The updated metdata object.
*/
function addDefaultMetadata(metadata, filename) {
if (!metadata.artist) {
metadata.artist = '';
}
if (!metadata.album) {
metadata.album = '';
}
if (!metadata.title) {
// If the blob has a name, use that as a default title in case
// we can't find one in the file
if (filename) {
var p1 = filename.lastIndexOf('/');
var p2 = filename.lastIndexOf('.');
if (p2 <= p1) {
p2 = filename.length;
}
metadata.title = filename.substring(p1 + 1, p2);
} else {
metadata.title = '';
}
}
metadata.rated = metadata.played = 0;
return metadata;
}
/**
* Check if a blob can be played as an audio file.
*
* @param {Blob} blob The file to test.
* @return {Promise} A promise that resolves successfully if the file is
* playable.
*/
function checkPlayability(blob) {
var player = new Audio();
player.mozAudioChannelType = 'content';
var canplay = blob.type && player.canPlayType(blob.type);
if (canplay === 'probably') {
return Promise.resolve();
} else {
return new Promise(function(resolve, reject) {
var url = URL.createObjectURL(blob);
player.src = url;
// XXX: There seems to have been a gecko regression, and error events
// are no longer being fired when we try to play some invalid audio
// files. To work around this, we use a timeout to assume the file is
// unplayable if we nave not gotten any events within a reasonable
// amount of time. See also bugs 1208331 and 1198169.
const CANPLAY_TIMEOUT = 3000;
var timeoutId = setTimeout(() => {
console.error('No oncanplay or error events seen yet.',
'Assuming file is corrupt:', blob.name);
player.onerror();
}, CANPLAY_TIMEOUT);
player.onerror = function() {
clearTimeout(timeoutId);
URL.revokeObjectURL(url);
player.removeAttribute('src');
player.load();
reject('Unplayable music file');
};
player.oncanplay = function() {
clearTimeout(timeoutId);
URL.revokeObjectURL(url);
player.removeAttribute('src');
player.load();
resolve();
};
});
}
}
return {
parse: parse
};
})();

View file

@ -0,0 +1,175 @@
/* global LazyLoader, VorbisPictureComment */
/* exported FLACMetadata */
'use strict';
/**
* Parse metadata for FLAC files (this is very similar to Ogg files, but with a
* different container format).
*
* Format information:
* http://flac.sourceforge.net/format.html
*/
var FLACMetadata = (function() {
// Fields that should be stored as integers, not strings
var INTFIELDS = [
'tracknum', 'trackcount', 'discnum', 'disccount'
];
// Map FLAC field names to metadata property names
var FLACFIELDS = {
title: 'title',
artist: 'artist',
album: 'album',
tracknumber: 'tracknum',
tracktotal: 'trackcount',
discnumber: 'discnum',
disctotal: 'disccount'
};
/**
* Parse a file and return a Promise with the metadata.
*
* @param {BlobView} blobview The audio file to parse.
* @return {Promise} A Promise returning the parsed metadata object.
*/
function parse(blobview) {
// First four bytes are "fLaC" or we wouldn't be here.
blobview.seek(4);
var metadata = {tag_format: 'flac'};
var has_vorbis_comment = false;
var has_picture = false;
function processBlock(block) {
if (block.block_type === 4) {
readAllComments(block.view, metadata);
has_vorbis_comment = true;
} else if (block.block_type === 6) {
metadata.picture = VorbisPictureComment.readPicFrame(block.view);
has_picture = true;
}
return (!has_vorbis_comment || !has_picture);
}
return LazyLoader.load('js/metadata/vorbis_picture.js').then(() => {
return findMetadataBlocks(blobview, processBlock);
}).then(() => {
return metadata;
});
}
/**
* Step over metadata blocks until we find the proper metadata block.
*
* @param {BlobView} blobview The BlobView for the file.
* @param {function} callback The callback to process the block with.
* @return {Promise} A Promise that resolves when all relevant metadata blocks
* have been processed.
*/
function findMetadataBlocks(blobview, callback) {
return readMetadataBlockHeader(blobview).then((block) => {
if (callback(block) && !block.last) {
block.view.advance(block.length - block.view.index);
findMetadataBlocks(block.view, callback);
}
});
}
/**
* Read a metadata block header and fetch its contents from the Blob, plus
* enough extra data to read the next block's header.
*
* @param {BlobView} blobview The BlobView for the file.
* @return {Promise} A Promise resolving to an object with the following
* fields:
* {Boolean} last True if this is the last metadata block.
* {Number} block_type The block's type, as an integer.
* {Number} length The size in bytes of the block's body (excluding the
* header).
* {BlobView} view The BlobView with the block's data, starting at the
* beginning of the metadata block's content (not the header).
*/
function readMetadataBlockHeader(blobview) {
return new Promise(function(resolve, reject) {
var header = blobview.readUnsignedByte();
var last = (header & 0x80) === 0x80;
var block_type = header & 0x7F;
var length = blobview.readUint24(false);
// Get the contents of this block, plus enough to read the next block's
// header if necessary.
blobview.getMore(blobview.viewOffset + blobview.index, length + 4,
function(more, err) {
if (err) {
reject(err);
return;
}
resolve({
last: last,
block_type: block_type,
length: length,
view: more
});
});
});
}
/**
* Read all the comments in a metadata header block.
*
* @param {BlobView} page The audio file being parsed.
* @param {Metadata} metadata The (partially filled-in) metadata object.
*/
function readAllComments(page, metadata) {
var vendor_string_length = page.readUnsignedInt(true);
page.advance(vendor_string_length); // skip vendor string
var num_comments = page.readUnsignedInt(true);
for (var i = 0; i < num_comments; i++) {
try {
var comment = readComment(page);
if (comment) {
if (!(comment.field in metadata)) {
metadata[comment.field] = comment.value;
} else {
// We already have a value, so append this new one.
metadata[comment.field] += ' / ' + comment.value;
}
}
} catch (e) {
console.warn('Error parsing vorbis comment', e);
}
}
}
/**
* Read a single comment field.
*
* @param {BlobView} page The audio file being parsed.
*/
function readComment(page) {
var comment_length = page.readUnsignedInt(true);
var comment = page.readUTF8Text(comment_length);
var equal = comment.indexOf('=');
if (equal === -1) {
throw new Error('missing delimiter in comment');
}
var fieldname = comment.substring(0, equal).toLowerCase().replace(' ', '');
var propname = FLACFIELDS[fieldname];
if (propname) { // Do we care about this field?
var value = comment.substring(equal + 1);
if (INTFIELDS.indexOf(propname) !== -1) {
value = parseInt(value, 10);
}
return {field: propname, value: value};
}
return null;
}
return {
parse: parse
};
})();

View file

@ -0,0 +1,115 @@
/* global FLACMetadata, ForwardLockMetadata, ID3v1Metadata, ID3v2Metadata,
LazyLoader, MP4Metadata, OggMetadata */
/* exported MetadataFormats */
'use strict';
/**
* Delegates metadata parsing to the appropriate parser based on magic header
* values.
*/
var MetadataFormats = (function() {
/*
* This is the list of formats that we know how to parse. Each format has
* three properties:
*
* @property {String} file The path to the file for parsing this metadata
* format.
* @property {Object} module A getter that returns the module object for this
* parser. Note: It *must* be a getter because it needs to be evaluated
* *after* the file is loaded.
* @property {Function} match A function that takes a BlobView of the file
* and returns true if the file uses this metadata format.
*/
var formats = [
{
file: 'js/metadata/forward_lock.js',
get module() { return ForwardLockMetadata; },
match: function(header) {
return header.getBinaryText(0, 9) === 'LOCKED 1 ';
}
},
{
file: 'js/metadata/id3v2.js',
get module() { return ID3v2Metadata; },
match: function(header) {
return header.getBinaryText(0, 3) === 'ID3';
}
},
{
file: 'js/metadata/ogg.js',
get module() { return OggMetadata; },
match: function(header) {
return header.getBinaryText(0, 4) === 'OggS';
}
},
{
file: 'js/metadata/flac.js',
get module() { return FLACMetadata; },
match: function(header) {
return header.getBinaryText(0, 4) === 'fLaC';
}
},
{
file: 'js/metadata/mp4.js',
get module() { return MP4Metadata; },
match: function(header) {
return header.getBinaryText(4, 4) === 'ftyp';
}
},
{
file: 'js/metadata/id3v1.js',
get module() { return ID3v1Metadata; },
match: function(header) {
return (header.getUint16(0, false) & 0xFFFE) === 0xFFFA;
}
}
];
/**
* Create a new metadata parser for a particular file format.
*
* @param {Object} formatInfo A description of the file format containing a
* `file` attribute for the file to load, and a `module` attribute returning
* the module that contains the parse() method we should call.
*/
function MetadataParser(formatInfo) {
this._formatInfo = formatInfo;
}
MetadataParser.prototype = {
/**
* Parse a file and return a Promise with the metadata.
*
* @param {BlobView} header The file in question.
* @return {Promise} A Promise that resolves with the completed metadata
* object.
*/
parse: function(header) {
var info = this._formatInfo;
return LazyLoader.load(info.file).then(() => {
return info.module.parse(header);
});
}
};
/**
* Find the appropriate metadata parser for a given file.
*
* @param {BlobView} header The file in question.
* @return {MetadataParser} The metadata parser to use for this file.
*/
function findParser(header) {
for (var i = 0; i < formats.length; i++) {
if (formats[i].match(header)) {
return new MetadataParser(formats[i]);
}
}
return null;
}
return {
findParser: findParser
};
})();

View file

@ -0,0 +1,56 @@
/* global AudioMetadata, ForwardLock */
/* exported ForwardLockMetadata */
'use strict';
/**
* Parse metadata for ForwardLocked files. Generally, this will forward on to
* the metadata parser for the underlying format.
*/
var ForwardLockMetadata = (function() {
/**
* Parse a file and return a Promise with the metadata.
*
* @param {BlobView} locked The audio file to parse.
* @return {Promise} A Promise returning the parsed metadata object.
*/
function parse(locked) {
return new Promise(function(resolve, reject) {
ForwardLock.getKey(function(secret) {
ForwardLock.unlockBlob(secret, locked.blob, callback, reject);
function callback(unlocked, unlockedMetadata) {
// Now that we have the unlocked content of the locked file, pass it
// back to AudioMetadata.parse to get the metadata. When we're done,
// add some extra metadata to indicate that this is locked content (so
// it isn't shared) and to specify the vendor that locked it.
resolve(AudioMetadata.parse(unlocked).then(function(metadata) {
metadata.locked = true;
if (unlockedMetadata.vendor) {
metadata.vendor = unlockedMetadata.vendor;
}
if (!metadata.title) {
metadata.title = unlockedMetadata.name;
}
if (metadata.picture && metadata.picture.flavor === 'embedded') {
// Grab the slice for the embedded album art while we still have
// the decrypted blob to look at!
metadata.picture = {
flavor: 'unsynced',
blob: unlocked.slice(metadata.picture.start,
metadata.picture.end,
metadata.picture.type)
};
}
return metadata;
}));
}
});
});
}
return {
parse: parse
};
})();

View file

@ -0,0 +1,79 @@
/* global BlobView */
/* exported ID3v1Metadata */
'use strict';
/**
* Parse files with ID3v1 metadata. Metadata includes title, artist, album,
* and possibly the track number. Year, comment and genre are ignored.
*
* Format information:
* http://www.id3.org/ID3v1
* http://en.wikipedia.org/wiki/ID3
*/
var ID3v1Metadata = (function() {
/**
* Parse a file and return a Promise with the metadata.
*
* @param {BlobView} blobview The audio file to parse.
* @return {Promise} A Promise returning the parsed metadata object.
*/
function parse(blobview) {
return new Promise(function(resolve, reject) {
var blob = blobview.blob;
BlobView.get(blob, blob.size - 128, 128, function(footer, error) {
if (error) {
reject(error);
return;
}
try {
var magic = footer.getBinaryText(0, 3);
if (magic === 'TAG') {
// It's an MP3 file with an ID3v1 tag.
resolve(parseID3v1Metadata(footer));
} else {
// It's an MP3 file with no metadata. Just resolve to an empty
// metatada object.
resolve({});
}
} catch (e) {
reject(e);
}
});
});
}
/**
* Parse ID3v1 metadata from the 128 bytes footer at the end of a file.
*
* @param {BlobView} footer The last 128 bytes of the file.
* @return {Metadata} The parsed metadata object.
*/
function parseID3v1Metadata(footer) {
footer.seek(3); // Skip the "TAG" prefix.
var title = footer.readNullTerminatedLatin1Text(30, true);
var artist = footer.readNullTerminatedLatin1Text(30, true);
var album = footer.readNullTerminatedLatin1Text(30, true);
footer.advance(32); // Skip year and comment.
var zerobyte = footer.readUnsignedByte();
var track = footer.readUnsignedByte();
var metadata = {
tag_format: 'id3v1',
title: title || undefined,
artist: artist || undefined,
album: album || undefined
};
if (zerobyte === 0 && track !== 0) {
metadata.tracknum = track;
}
return metadata;
}
return {
parse: parse
};
})();

View file

@ -0,0 +1,452 @@
/* global BlobView, ID3v1Metadata, LazyLoader */
/* exported ID3v2Metadata */
'use strict';
/**
* Parse files with ID3v2 metadata.
*
* Format information:
* http://id3.org/Developer%20Information
*/
var ID3v2Metadata = (function() {
// Map id3v2 frame ids to metadata property names. Each line has two mappings:
// one for id3v2.3+ and one for id3v2.2.
var ID3V2FRAMES = {
TPE1: 'artist', TP1: 'artist',
TALB: 'album', TAL: 'album',
TIT2: 'title', TT2: 'title',
TRCK: 'tracknum', TRK: 'tracknum',
TPOS: 'discnum', TPA: 'discnum',
APIC: 'picture', PIC: 'picture'
};
var ID3V2SECONDARYFRAMES = {
TRCK: 'trackcount', TRK: 'trackcount',
TPOS: 'disccount', TPA: 'disccount'
};
/**
* Parse a file and return a Promise with the metadata.
*
* @param {BlobView} blobview The audio file to parse.
* @return {Promise} A Promise returning the parsed metadata object.
*/
function parse(blobview) {
return new Promise((resolve, reject) => {
var header = parseHeader(blobview);
if (header.version > 4) {
console.warn('mp3 file with unknown metadata version');
reject();
return;
}
blobview.getMore(blobview.index, header.length, (moreview, err) => {
if (err) {
reject(err);
return;
}
try {
resolve(parseFrames(header, moreview));
} catch(e) {
console.warn('Invalid ID3v2 data for', blobview.blob.name, ':', e);
reject(e);
}
});
}).catch((e) => {
return LazyLoader.load('js/metadata/id3v1.js').then(() => {
return ID3v1Metadata.parse(blobview);
});
});
}
/**
* Parse the header of an ID3 tag.
*
* @param {BlobView} blobview The audio file to parse.
* @return {Object} An object describing the header's values.
*/
function parseHeader(blobview) {
// First three bytes are "ID3" or we wouldn't be here
blobview.seek(3);
var header = {
get versionString() {
return 'id3v2.' + this.version + '.' + this.revision;
},
get tag_unsynchronized() {
return (this.flags & 0x80) !== 0;
},
get has_extended_header() {
return (this.flags & 0x40) !== 0;
}
};
header.version = blobview.readUnsignedByte();
header.revision = blobview.readUnsignedByte();
header.flags = blobview.readUnsignedByte();
header.length = blobview.readID3Uint28BE();
return header;
}
/**
* Parse all the ID3 frames in this tag.
*
* @param {Object} header The header object for this ID3 tag.
* @param {BlobView} blobview The audio file to parse.
* @return {Object} The metadata extracted from the ID3 tag.
*/
function parseFrames(header, blobview) {
var metadata = {};
metadata.tag_format = header.versionString;
// In id3v2.3, the "unsynchronized" flag in the tag header applies to
// the whole tag (excluding the tag header). In id3v2.4, the flag is just
// an indicator that we should expect to see the "unsynchronized" flag
// set on all the frames.
if (header.tag_unsynchronized && header.version === 3) {
blobview = deunsync(blobview, header.length);
}
// Skip the extended header, if there is one.
if (header.has_extended_header) {
var extended_header_size;
if (header.version === 4) {
// In id3v2.4, the size includes itself, i.e. the rest of the header
// is |extended_header_size - 4|.
extended_header_size = blobview.readID3Uint28BE() - 4;
} else { // id3version === 3
// In id3v2.3, the size *excludes* itself, i.e. the rest of the header
// is |extended_header_size|.
extended_header_size = blobview.readUnsignedInt();
}
blobview.advance(extended_header_size);
}
while (blobview.index < blobview.byteLength) {
// If there is a null byte here, then we've found padding and we're done.
if (blobview.getUint8(blobview.index) === 0) {
break;
}
parseFrame(header, blobview, metadata);
}
return metadata;
}
/**
* Parse an individual ID3 frame.
*
* @param {Object} header The header object for this ID3 tag.
* @param {BlobView} blobview The audio file being parsed.
* @param {Metadata} metadata The (partially filled-in) metadata object.
*/
function parseFrame(header, blobview, metadata) {
var frameid, framesize, frame_format_flags, frame_unsynchronized = false,
data_len_indicator = false, unsupported_flags = false;
switch (header.version) {
case 2:
frameid = blobview.readBinaryText(3);
framesize = blobview.readUint24();
break;
case 3:
frameid = blobview.readBinaryText(4);
framesize = blobview.readUnsignedInt();
// Ignore the frame status flags, since they only apply when modifying the
// file/tag.
blobview.readUnsignedByte();
frame_format_flags = blobview.readUnsignedByte();
unsupported_flags = (frame_format_flags !== 0);
break;
case 4:
frameid = blobview.readBinaryText(4);
framesize = blobview.readID3Uint28BE();
blobview.readUnsignedByte(); // As above, ignore the frame status flags.
frame_format_flags = blobview.readUnsignedByte();
data_len_indicator = ((frame_format_flags & 0b00000001) !== 0);
frame_unsynchronized = ((frame_format_flags & 0b00000010) !== 0);
unsupported_flags = ((frame_format_flags & 0b11111100) !== 0);
break;
}
var nextframe = blobview.index + framesize;
var propname = ID3V2FRAMES[frameid];
// Skip frames we don't care about.
if (!propname) {
blobview.seek(nextframe);
return;
}
// Skip frames with flags we don't understand.
if (unsupported_flags) {
console.warn('Skipping', frameid, 'frame with unsupported format flags',
'0b' + frame_format_flags.toString(2));
blobview.seek(nextframe);
return;
}
try {
var frameview, framevalue, data_len;
if (data_len_indicator) {
data_len = blobview.readID3Uint28BE();
framesize -= 4;
}
if (frame_unsynchronized) {
frameview = deunsync(blobview, framesize);
framesize = frameview.sliceLength;
if (data_len !== undefined && framesize != data_len) {
console.warn('de-unsynced frame size (' + framesize + ') doesn\'t' +
'match data length indicator (' + data_len + ')');
}
} else {
frameview = blobview;
}
switch (frameid) {
case 'TPE1': case 'TP1': // artist
case 'TALB': case 'TAL': // album
case 'TIT2': case 'TT2': // title
framevalue = readTextFrame(header, frameview, framesize);
break;
case 'TRCK': case 'TRK': // track
case 'TPOS': case 'TPA': // disc
framevalue = readNumericPairFrame(header, frameview, framesize);
if (framevalue[1] !== null) {
metadata[ID3V2SECONDARYFRAMES[frameid]] = framevalue[1];
}
framevalue = framevalue[0];
break;
case 'APIC': case 'PIC': // picture
framevalue = readPicFrame(header, frameview, framesize);
break;
default:
console.error('Should not have gotten here');
}
if (framevalue !== null) {
metadata[propname] = framevalue;
}
} catch (e) {
console.warn('Error parsing mp3 metadata frame', frameid, ':', e);
}
// Make sure we're at the start of the next frame before continuing
blobview.seek(nextframe);
}
/**
* Reverse the ID3 unsynchronization so that we get the unescaped data. This
* will advance the view to the end of the unsynchronized block so that you
* can continue to use the original view once you're finished with the
* deunsynced view.
*
* @param {BlobView} view The original BlobView for the ID3 tag.
* @param {Number} framesize The size of the unsynchronized frame.
* @return {BlobView} A new BlobView with the deunsynced data.
*/
function deunsync(view, framesize) {
// To de-unsychronize a frame, we need to convert all instances of
// |0xff 00| to |0xff|.
var data = new Uint8Array(framesize), was0xff = false, dataIndex = 0;
for (var i = 0; i < framesize; i++) {
var b = view.readUnsignedByte();
if (was0xff && b === 0x00) {
continue;
}
was0xff = (b === 0xff);
data[dataIndex++] = b;
}
// Create a new BlobView with the de-unsynchronized data.
var deunsynced_view = new BlobView.getFromArrayBuffer(
data.buffer, 0, dataIndex, view.littleEndian
);
deunsynced_view.deunsynced = true;
return deunsynced_view;
}
/**
* Read the value from a textual ID3 frame (one whose name starts with "T",
* and isn't "TXXX").
*
* @param {Object} header The header object for this ID3 tag.
* @param {BlobView} view The audio file being parsed.
* @param {Number} size The size in bytes of this frame's value.
* @param {Number} encoding The encoding for this string (0: latin-1,
* 1: utf16, 2: utf16-be, 3: utf-8). If null, determine the encoding from
* the first byte of the value.
* @param {String} The value of this frame.
*/
function readTextFrame(header, view, size, encoding) {
if (encoding === undefined) {
encoding = view.readUnsignedByte();
size = size - 1;
}
if (header.version === 4) {
// In id3v2.4, all text frames can have multiple values, separated by
// the null character. For now, we join them together to make one big
// string.
return readEncodedTextArray(view, size, encoding);
} else {
// In id3v2.3, some text frames can have multiple values, separated by
// '/', so we don't need to do anything special here. In fact, even if
// we start treating multi-value text frames as an array, we probably
// shouldn't do anything, since '/' is a bad delimiter.
return readEncodedText(view, size, encoding);
}
}
/**
* Read the value from a numeric pair frame (track number or disc number).
*
* @param {Object} header The header object for this ID3 tag.
* @param {BlobView} view The audio file being parsed.
* @param {Number} size The size in bytes of this frame's value.
* @param {Number} encoding The encoding for this string (0: latin-1,
* 1: utf16, 2: utf16-be, 3: utf-8). If null, determine the encoding from
* the first byte of the value.
* @param {Array} The value of this frame, as two Numbers.
*/
function readNumericPairFrame(header, view, size, encoding) {
var text = readTextFrame(header, view, size, encoding);
var pair = text.split('/', 2).map(function(val) {
var i = parseInt(val, 10);
return isNaN(i) || !isFinite(i) ? null : i;
});
if (pair.length === 1) {
pair.push(null);
}
return pair;
}
/**
* Read the value from a picture frame.
*
* @param {Object} header The header object for this ID3 tag.
* @param {BlobView} view The audio file being parsed.
* @param {Number} size The size in bytes of this frame's value.
* @param {Picture} The value of this frame.
*/
function readPicFrame(header, view, size) {
var start = view.index;
var encoding = view.readUnsignedByte();
var mimetype;
// mimetype is different for old PIC frames and new APIC frames
if (header.version === 2) {
mimetype = view.readLatin1Text(3);
if (mimetype === 'JPG') {
mimetype = 'image/jpeg';
} else if (mimetype === 'PNG') {
mimetype = 'image/png';
}
} else {
mimetype = view.readNullTerminatedLatin1Text(size - 1);
if (mimetype === '-->') {
// XXX: We don't support URLs (the spec recommends against them anyway).
console.error('URL for cover art is not supported.');
return null;
}
}
// We ignore these next two fields.
view.readUnsignedByte(); // kind
readEncodedText(view, size - (view.index - start), encoding); // desc
var picstart = view.sliceOffset + view.viewOffset + view.index;
var picsize = size - (view.index - start);
var picend = picstart + picsize;
if (view.deunsynced) {
return {
flavor: 'unsynced',
blob: new Blob(
[view.buffer.slice(picstart, picend)],
{type: mimetype}
)
};
} else {
// Now return an object that specifies where to pull the image from
// The properties of this object can be passed to blob.slice()
return {
flavor: 'embedded',
start: picstart,
end: picend,
type: mimetype
};
}
}
/**
* Read an array of strings from a frame.
*
* @param {BlobView} view The audio file being parsed.
* @param {Number} size The size in bytes of this frame's value.
* @param {Number} encoding The encoding for this string (0: latin-1,
* 1: utf16, 2: utf16-be, 3: utf-8). If null, determine the encoding from
* the first byte of the value.
* @param {String} The strings, joined by " / ".
*/
function readEncodedTextArray(view, size, encoding) {
var text;
switch (encoding) {
case 0:
text = view.readLatin1Text(size);
break;
case 1:
text = view.readUTF16Text(size, undefined);
break;
case 2:
text = view.readUTF16Text(size, false);
break;
case 3:
text = view.readUTF8Text(size);
break;
default:
throw Error('unknown text encoding');
}
// Remove any trailing nulls and replace nulls in the middle with ' / '.
// XXX: When the database supports arrays of values for each field, we
// should split this into a proper array!
return text.replace(/\0+$/, '').replace('\0', ' / ');
}
/**
* Read a single string from a frame.
*
* @param {BlobView} view The audio file being parsed.
* @param {Number} size The size in bytes of this frame's value.
* @param {Number} encoding The encoding for this string (0: latin-1,
* 1: utf16, 2: utf16-be, 3: utf-8). If null, determine the encoding from
* the first byte of the value.
* @param {String} The string.
*/
function readEncodedText(view, size, encoding) {
switch (encoding) {
case 0:
return view.readNullTerminatedLatin1Text(size);
case 1:
return view.readNullTerminatedUTF16Text(size, undefined);
case 2:
return view.readNullTerminatedUTF16Text(size, false);
case 3:
return view.readNullTerminatedUTF8Text(size);
default:
throw Error('unknown text encoding');
}
}
return {
parse: parse
};
})();

View file

@ -0,0 +1,421 @@
/* exported MP4Metadata */
'use strict';
/**
* Parse files with MP4 metadata.
*
* Format information:
* https://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/
* QTFFChap1/qtff1.html
* http://en.wikipedia.org/wiki/MPEG-4_Part_14
* http://atomicparsley.sourceforge.net/mpeg-4files.html
*/
var MP4Metadata = (function() {
// Map MP4 atom names to metadata property names
var MP4ATOMS = {
'\xa9alb' : 'album',
'\xa9art' : 'artist',
'\xa9ART' : 'artist',
'aART' : 'artist',
'\xa9nam' : 'title',
'trkn' : 'tracknum',
'disk' : 'discnum',
'covr' : 'picture'
};
// These MP4 atoms are stored as pairs of integers, so they get mapped to
// two metadata fields
var MP4INTPAIRATOMS = {
'trkn': 'trackcount',
'disk': 'disccount'
};
// These are 'ftyp' values that we recognize
// See http://www.mp4ra.org/filetype.html
// Also see gecko code in /toolkit/components/mediasniffer/nsMediaSniffer.cpp
// Gaia will accept the supported compatible brands in gecko as well
var MP4Types = {
'M4A ' : true, // iTunes audio. Note space in property name.
'M4B ' : true, // iTunes audio book. Note space.
'mp41' : true, // MP4 version 1
'mp42' : true, // MP4 version 2
'isom' : true, // ISO base media file format, version 1
'iso2' : true // ISO base media file format, version 2
};
// MP4 and 3GP containers both use ISO base media file format.
// Also see what audio codecs/formats are supported in 3GPP specification.
// Format information:
// https://en.wikipedia.org/wiki/ISO_base_media_file_format
// http://tools.ietf.org/html/rfc6381
// http://www.3gpp.org/ftp/Specs/html-info/26244.htm
//
var MP4Codecs = {
'mp4a' : true, // MPEG-4 audio
'samr' : true, // AMR narrow-band speech
'sawb' : true, // AMR wide-band speech
'sawp' : true // Extended AMR wide-band audio
};
/**
* Parse a file and return a Promise with the metadata.
*
* @param {BlobView} blobview The audio file to parse.
* @return {Promise} A Promise returning the parsed metadata object.
*/
function parse(blobview) {
// The MP4 file might be a video or it might be some kind of audio that we
// don't support.
if (!checkMP4Type(blobview, MP4Types)) {
return Promise.reject(new Error('Unknown MP4 file type'));
}
return findMoovAtom(blobview).then((result) => {
var metadata = {tag_format: 'mp4'};
if (!result) {
return metadata;
}
return parseMoovAtom(result.atom, result.size, metadata);
});
}
/**
* Check the type of MP4 file to ensure we should play it. (MP4 files use
* 'ftyp' to identify the type of encoding. For more information, see:
* <http://www.ftyps.com/what.html>.)
*
* @param {BlobView} blobview The audio file to parse.
* @param {Object} types A list of types we support.
* @return {Boolean} True if the file should be parsed, false otherwise.
*/
function checkMP4Type(blobview, types) {
// The major brand is the four bytes right after 'ftyp'.
var majorbrand = blobview.getBinaryText(8, 4);
if (majorbrand in types) {
return true;
} else {
// Check the rest for the compatible brands. They are every four bytes
// after the version of major brand. Usually there are two optional
// compatible brands, but an arbitrary number of other compatible brands
// are also acceptable, so we will check all the compatible brands until
// the header ends.
var index = 16;
var size = blobview.getUint32(0);
while (index < size) {
var compatiblebrand = blobview.getBinaryText(index, 4);
index += 4;
if (compatiblebrand in types) {
return true;
}
}
return false;
}
}
/**
* Find the "moov" atom in the MP4 container.
*
* @param {BlobView} atom The file we're parsing.
* @return {Promise} A promise that resolves when we've found the move atom.
*/
function findMoovAtom(atom) {
// XXX: I think I could probably restructure this somehow. The atoms or
// "boxes" we're reading and parsing here for a tree that I need to
// traverse. Maybe nextBox() and firstChildBox() functions would be
// helpful. Or even make these methods of BlobView? Not sure if it is worth
// the time to refactor, though... See also the approach in
// shared/js/get_video_rotation.js
return new Promise(function(resolve, reject) {
var offset = atom.sliceOffset + atom.viewOffset; // position in blob
var size = atom.readUnsignedInt();
var type = atom.readBinaryText(4);
if (size === 0) {
// A size of 0 means the rest of the file
size = atom.blob.size - offset;
} else if (size === 1) {
// A size of 1 means the size is in bytes 8-15
size = atom.readUnsignedInt() * 4294967296 + atom.readUnsignedInt();
}
if (type === 'moov') {
// Get the full contents of this atom
atom.getMore(offset, size, function(moov) {
resolve({atom: moov, size: size});
});
} else {
// Otherwise, get the start of the next atom and recurse
// to continue the search for the moov atom.
// If we're reached the end of the blob without finding
// anything, just call the metadata callback with no metadata
if (offset + size + 16 <= atom.blob.size) {
atom.getMore(offset + size, 16, function(moov) {
try {
findMoovAtom(moov).then(function(result) {
resolve(result);
});
} catch (e) {
reject(e);
}
});
} else {
resolve(null);
}
}
});
}
/**
* Parse the moov atom. This function, and the ones that follow are all
* synchronous. We've read the entire moov atom, so we've got all the bytes
* we need and don't have to do an async read again.
*
* @param {BlobView} data The data for the moov atom.
* @param {Number} end The offset at which the moov atom ends.
* @param {Metadata} metadata The (partially filled-in) metadata object.
* @return {Metadata} The completed metadata object.
*/
function parseMoovAtom(data, end, metadata) {
data.advance(8); // skip the size and type of this atom
// Find the udta and trak atoms within the moov atom
// There will only be one udta atom, but there may be multiple trak
// atoms. In that case, this is probably a movie file and we'll reject
// it when we find a track that is not an mp4 audio codec.
while (data.index < end) {
var size = data.readUnsignedInt();
var type = data.readBinaryText(4);
var nextindex = data.index + size - 8;
if (type === 'udta') { // Metadata is inside here
parseUdtaAtom(data, end, metadata);
} else if (type === 'trak') { // We find the audio format inside here
data.advance(-8); // skip back to beginning
if (seekChildAtoms(data, ['mdia', 'minf'])) {
if (searchChildAtom(data, 'vmhd')) {
throw Error('Found video track in MP4 container');
}
if (searchChildAtom(data, 'smhd')) {
if (seekChildAtoms(data, ['stbl', 'stsd'])) {
data.advance(20);
var codec = data.readBinaryText(4);
if (!(codec in MP4Codecs)) {
throw Error('Unsupported format in MP4 container: ' + codec);
}
}
}
} else {
// There is not enough information for us to identify the MP4
throw Error('Not enough metadata in MP4 container!');
}
}
data.seek(nextindex);
}
return metadata;
}
/**
* Find the specified hierarchy of atoms and stop at the last one's file
* offset.
*
* @param {BlobView} data The data for the moov atom.
* @param {Array} atoms The names of the atoms to find.
* @return {Boolean} True if we found the atoms, false otherwise.
*/
function seekChildAtoms(data, atoms) {
return atoms.every(function(atom) {
return seekChildAtom(data, atom);
});
}
/**
* Find a child atom and stop at its file offset.
*
* @param {BlobView} data The data for the moov atom.
* @param {String} atom The name of the atom to find.
* @return {Boolean} True if we found the atom, false otherwise.
*/
function seekChildAtom(data, atom) {
var start = data.index;
var length = data.readUnsignedInt();
data.advance(4);
while (data.index < start + length) {
var size = data.readUnsignedInt();
var type = data.readBinaryText(4);
if (type === atom) {
data.advance(-8);
return true;
}
else {
data.advance(size - 8);
}
}
return false;
}
/**
* Find a child atom, but reset the file offset to the start after completion.
*
* @param {BlobView} data The data for the moov atom.
* @param {String} atom The name of the atom to find.
* @return {Boolean} True if we found the atom, false otherwise.
*/
function searchChildAtom(data, atom) {
var start = data.index;
var result = seekChildAtom(data, atom);
data.seek(start);
return result;
}
/**
* Parse the udta atom.
*
* @param {BlobView} data The data for the moov atom.
* @param {Number} end The offset at which the moov atom ends.
* @param {Metadata} metadata The (partially filled-in) metadata object.
*/
function parseUdtaAtom(data, end, metadata) {
// Find the meta atom within the udta atom
while (data.index < end) {
var size = data.readUnsignedInt();
var type = data.readBinaryText(4);
if (type === 'meta') {
parseMetaAtom(data, data.index + size - 8, metadata);
data.seek(end);
return;
} else {
data.advance(size - 8);
}
}
}
/**
* Parse the meta atom.
*
* @param {BlobView} data The data for the moov atom.
* @param {Number} end The offset at which the moov atom ends.
* @param {Metadata} metadata The (partially filled-in) metadata object.
*/
function parseMetaAtom(data, end, metadata) {
// The meta atom apparently has a slightly different structure.
// Have to skip flag bytes before reading children atoms
data.advance(4);
// Find the ilst atom within the meta atom
while (data.index < end) {
var size = data.readUnsignedInt();
var type = data.readBinaryText(4);
if (type === 'ilst') {
parseIlstAtom(data, data.index + size - 8, metadata);
data.seek(end);
return;
}
else {
data.advance(size - 8);
}
}
}
/**
* Parse the ilst atom, which (finally) contains all our metadata atom.
*
* @param {BlobView} data The data for the moov atom.
* @param {Number} end The offset at which the moov atom ends.
* @param {Metadata} metadata The (partially filled-in) metadata object.
*/
function parseIlstAtom(data, end, metadata) {
// Now read all child atoms of ilst, looking for metadata
// we care about
while (data.index < end) {
var size = data.readUnsignedInt();
var type = data.readBinaryText(4);
var next = data.index + size - 8;
var propname = MP4ATOMS[type];
if (propname) {
try {
var value = getMetadataValue(data, next, type);
// Track number and disc number are of the form "x/y".
if (type in MP4INTPAIRATOMS) {
metadata[propname] = value.number;
if (value.count) {
metadata[MP4INTPAIRATOMS[type]] = value.count;
}
} else {
metadata[propname] = value;
}
} catch (e) {
console.warn('skipping', type, ':', e);
}
}
data.seek(next);
}
}
/**
* Get the value for a single metadata atom.
*
* @param {BlobView} data The data for the moov atom.
* @param {Number} end The offset at which the moov atom ends.
* @param {String} atomtype The name of this atom.
* @return {Object} The parsed value.
*/
function getMetadataValue(data, end, atomtype) {
// Loop until we find a data atom
while (data.index < end) {
var size = data.readUnsignedInt();
var type = data.readBinaryText(4);
if (type !== 'data') {
data.advance(size - 8);
continue;
}
// We've found the data atom.
// Return its (first) value or throw an error.
var datatype = data.readUnsignedInt() & 0xFFFFFF;
data.advance(4); // Ignore locale
var datasize = size - 16; // the rest of the atom is the value
// Special case for track number and disk number
// They have two values: number and count.
if (atomtype in MP4INTPAIRATOMS) {
data.advance(2);
var number = data.readUnsignedShort();
var count = data.readUnsignedShort();
return { number: number, count: count };
}
switch (datatype) {
case 1: // utf8 text
return data.readUTF8Text(datasize);
case 13: // jpeg
return {
flavor: 'embedded',
start: data.sliceOffset + data.viewOffset + data.index,
end: data.sliceOffset + data.viewOffset + data.index + datasize,
type: 'image/jpeg'
};
case 14: // png
return {
flavor: 'embedded',
start: data.sliceOffset + data.viewOffset + data.index,
end: data.sliceOffset + data.viewOffset + data.index + datasize,
type: 'image/png'
};
default:
throw Error('unexpected type in data atom');
}
}
throw Error('no data atom found');
}
return {
parse: parse
};
})();

View file

@ -0,0 +1,205 @@
/* global LazyLoader, VorbisPictureComment */
/* exported OggMetadata */
'use strict';
/**
* Parse files with Ogg metadata (e.g. Vorbis comments or Opus tags).
*
* Format information:
* http://wiki.xiph.org/VorbisComment
*/
var OggMetadata = (function() {
// Fields that should be stored as integers, not strings
var INTFIELDS = [
'tracknum', 'trackcount', 'discnum', 'disccount'
];
// Map ogg field names to metadata property names
var OGGFIELDS = {
title: 'title',
artist: 'artist',
album: 'album',
tracknumber: 'tracknum',
tracktotal: 'trackcount',
discnumber: 'discnum',
disctotal: 'disccount',
metadata_block_picture: 'picture'
};
/**
* A type thrown if we walk off the end of an Ogg page.
*/
function EndOfPageError() {}
/**
* Parse a file and return a Promise with the metadata.
*
* @param {BlobView} blobview The audio file to parse.
* @param {Metadata} metadata The (partially filled-in) metadata object.
* @return {Promise} A Promise returning the parsed metadata object.
*/
function parse(blobview) {
readIdentificationHeader(blobview);
return readCommentHeader(blobview);
}
/**
* Read the identification header of an Ogg container. It's always the first
* page.
*
* @param {BlobView} page The audio file being parsed.
*/
function readIdentificationHeader(page) {
var header = readPageHeader(page);
if (header.segment_table.length !== 1) {
throw new Error(
'ogg identification header expected as only packet of first page'
);
}
// Skip over the identification header.
page.advance(header.segment_table[0]);
}
/**
* Read the comment header of an Ogg container.
*
* @param {BlobView} page The audio file being parsed.
* @return {Promise} A Promise that resolves with the completed metadata.
*/
function readCommentHeader(page) {
var metadata = {};
var header = readPageHeader(page);
var sum = function(a, b) { return a + b; };
var comment_length = Array.reduce(header.segment_table, sum, 0);
return new Promise((resolve, reject) => {
page.getMore(page.index, comment_length, (fullpage, err) => {
if (err) {
reject(err);
return;
}
try {
// Look for a comment header from a supported codec
var first_byte = fullpage.readByte();
var valid = false;
switch (first_byte) {
case 3:
valid = fullpage.readBinaryText(6) === 'vorbis';
metadata.tag_format = 'vorbis';
break;
case 79:
valid = fullpage.readBinaryText(7) === 'pusTags';
metadata.tag_format = 'opus';
break;
}
if (!valid) {
reject('malformed ogg comment packet');
return;
}
readAllComments(fullpage, metadata);
LazyLoader.load('js/metadata/vorbis_picture.js').then(() => {
return VorbisPictureComment.parsePictureComment(metadata);
}).then(resolve);
} catch(e) {
reject(e);
}
});
});
}
/**
* Read the header for an Ogg page.
*
* @param {BlobView} page The audio file being parsed.
* @return {Object} An object containing the page's segment table.
*/
function readPageHeader(page) {
var capture_pattern = page.readBinaryText(4);
if (capture_pattern !== 'OggS') {
throw new Error('malformed ogg page header');
}
// Skip over some header fields until we reach the page segments.
page.advance(22);
var page_segments = page.readUnsignedByte();
var segment_table = page.readUnsignedByteArray(page_segments);
return {
segment_table: segment_table
};
}
/**
* Read all the comments in an Ogg container.
*
* @param {BlobView} page The audio file being parsed.
* @param {Metadata} metadata The (partially filled-in) metadata object.
*/
function readAllComments(page, metadata) {
var vendor_string_length = page.readUnsignedInt(true);
page.advance(vendor_string_length); // skip libvorbis vendor string
var num_comments = page.readUnsignedInt(true);
for (var i = 0; i < num_comments; i++) {
try {
var comment = readComment(page);
if (comment) {
if (!(comment.field in metadata)) {
metadata[comment.field] = comment.value;
} else if (comment.field !== 'picture') {
// We already have a value, so append this new one.
metadata[comment.field] += ' / ' + comment.value;
}
}
} catch (e) {
if (e instanceof EndOfPageError) {
return;
}
console.warn('Error parsing vorbis comment', e);
}
}
}
/**
* Read a single comment field.
*
* @param {BlobView} page The audio file being parsed.
*/
function readComment(page) {
if (page.remaining() < 4) { // 4 bytes for comment-length variable
// TODO: handle metadata that uses multiple pages
throw new EndOfPageError();
}
var comment_length = page.readUnsignedInt(true);
if (comment_length > page.remaining()) {
// TODO: handle metadata that uses multiple pages
throw new EndOfPageError();
}
var comment = page.readUTF8Text(comment_length);
var equal = comment.indexOf('=');
if (equal === -1) {
throw new Error('missing delimiter in comment');
}
var fieldname = comment.substring(0, equal).toLowerCase().replace(' ', '');
var propname = OGGFIELDS[fieldname];
if (propname) { // Do we care about this field?
var value = comment.substring(equal + 1);
if (INTFIELDS.indexOf(propname) !== -1) {
value = parseInt(value, 10);
}
return {field: propname, value: value};
}
}
return {
parse: parse
};
})();

View file

@ -0,0 +1,131 @@
/* global BlobView */
/* exported VorbisPictureComment */
'use strict';
var VorbisPictureComment = (function() {
/**
* Read the picture frame from the block blob
*/
function readPicFrame(view) {
// Source of the structure:
// https://xiph.org/flac/format.html#metadata_block_picture
// http://flac.sourceforge.net/format.html#metadata_block_picture
//
var kind = view.readUnsignedInt();
if (kind != 3) {
return null;
}
var mime_len = view.readUnsignedInt();
var mimetype = view.readLatin1Text(mime_len);
if (mimetype === '-->') {
// XXX: We don't support URLs (the spec recommends against them anyway).
console.error('URL for cover art is not supported.');
return null;
}
// Skip desc, w, h, bpp and indexed colours.
var desc_len = view.readUnsignedInt();
view.advance(desc_len + 16);
var pic_len = view.readUnsignedInt();
var pic_start = view.sliceOffset + view.viewOffset + view.index;
// Now return an object that specifies where to pull the image from
// The properties of this object can be passed to blob.slice()
return {
flavor: 'embedded',
start: pic_start,
end: pic_start + pic_len,
type: mimetype
};
}
// BEGIN slow base64
// https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
// This is needed as atob doesn't yield the right result.
function base64DecToArr(sBase64, nBlocksSize) {
function b64ToUint6(nChr) {
return nChr > 64 && nChr < 91 ?
nChr - 65
: nChr > 96 && nChr < 123 ?
nChr - 71
: nChr > 47 && nChr < 58 ?
nChr + 4
: nChr === 43 ?
62
: nChr === 47 ?
63
: 0;
}
var sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, '');
var nInLen = sB64Enc.length;
var nOutLen = nBlocksSize ?
Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize :
nInLen * 3 + 1 >> 2;
var taBytes = new Uint8Array(nOutLen);
for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0;
nInIdx < nInLen; nInIdx++) {
nMod4 = nInIdx & 3;
nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
if (nMod4 === 3 || nInLen - nInIdx === 1) {
for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
}
nUint24 = 0;
}
}
return taBytes;
}
// END
//
// Will parse the vorbis comment for picture from metadata.picture.
// If it doesn't exists, it is a no-op.
function parsePictureComment(metadata) {
return new Promise(function(resolve, reject) {
if (!metadata.picture) {
resolve(metadata);
return;
}
var value = metadata.picture;
try {
// Album art in ogg
// http://wiki.xiph.org/VorbisComment
// http://flac.sourceforge.net/format.html#metadata_block_picture
// Image block is in base64.
var binary = base64DecToArr(value);
var aBlob = new Blob([binary]);
BlobView.get(aBlob, 0, aBlob.size, function(block, err) {
var prop = readPicFrame(block);
if (prop) {
// we need to duplicate the blob because we need
// to set the MIME type now.
metadata.picture = {
flavor: 'unsynced',
blob: aBlob.slice(prop.start, prop.end, prop.type)
};
}
resolve(metadata);
}, BlobView.bigEndian);
}
catch(e) {
console.warn('Error parsing picture comment', e.message);
resolve(metadata);
}
});
}
return {
readPicFrame: readPicFrame,
parsePictureComment: parsePictureComment
};
})();

View file

@ -0,0 +1,42 @@
;'use strict';var BlobView=(function(){function fail(msg){throw Error(msg);}
var decoderCache={};function getDecoder(encoding){if(encoding in decoderCache){return decoderCache[encoding];}
var decoder=decoderCache[encoding]=new TextDecoder(encoding);return decoder;}
function BlobView(blob,sliceOffset,sliceLength,slice,viewOffset,viewLength,littleEndian)
{this.blob=blob;this.sliceOffset=sliceOffset;this.sliceLength=sliceLength;this.slice=slice;this.viewOffset=viewOffset;this.viewLength=viewLength;this.littleEndian=littleEndian;this.view=new DataView(slice,viewOffset,viewLength);this.buffer=slice;this.byteLength=viewLength;this.byteOffset=viewOffset;this.index=0;}
BlobView.get=function(blob,offset,length,callback,littleEndian){if(offset<0){fail('negative offset');}
if(length<0){fail('negative length');}
if(offset>blob.size){fail('offset larger than blob size');}
if(offset+length>blob.size){length=blob.size-offset;}
var slice=blob.slice(offset,offset+length);var reader=new FileReader();reader.readAsArrayBuffer(slice);reader.onloadend=function(){var result=null;if(reader.result){result=new BlobView(blob,offset,length,reader.result,0,length,littleEndian||false);}
callback(result,reader.error);};};BlobView.getFromArrayBuffer=function(buffer,offset,length,littleEndian){return new BlobView(null,offset,length,buffer,offset,length,littleEndian);};BlobView.prototype={constructor:BlobView,getMore:function(offset,length,callback){if(!this.blob){fail('no blob backing this BlobView');}
if(offset>=this.sliceOffset&&offset+length<=this.sliceOffset+this.sliceLength){callback(new BlobView(this.blob,this.sliceOffset,this.sliceLength,this.slice,offset-this.sliceOffset,length,this.littleEndian));}
else{BlobView.get(this.blob,offset,length,callback,this.littleEndian);}},littleEndian:function(){this.littleEndian=true;},bigEndian:function(){this.littleEndian=false;},getUint8:function(offset){return this.view.getUint8(offset);},getInt8:function(offset){return this.view.getInt8(offset);},getUint16:function(offset,le){return this.view.getUint16(offset,le!==undefined?le:this.littleEndian);},getInt16:function(offset,le){return this.view.getInt16(offset,le!==undefined?le:this.littleEndian);},getUint32:function(offset,le){return this.view.getUint32(offset,le!==undefined?le:this.littleEndian);},getInt32:function(offset,le){return this.view.getInt32(offset,le!==undefined?le:this.littleEndian);},getFloat32:function(offset,le){return this.view.getFloat32(offset,le!==undefined?le:this.littleEndian);},getFloat64:function(offset,le){return this.view.getFloat64(offset,le!==undefined?le:this.littleEndian);},readByte:function(){return this.view.getInt8(this.index++);},readUnsignedByte:function(){return this.view.getUint8(this.index++);},readShort:function(le){var val=this.view.getInt16(this.index,le!==undefined?le:this.littleEndian);this.index+=2;return val;},readUnsignedShort:function(le){var val=this.view.getUint16(this.index,le!==undefined?le:this.littleEndian);this.index+=2;return val;},readInt:function(le){var val=this.view.getInt32(this.index,le!==undefined?le:this.littleEndian);this.index+=4;return val;},readUnsignedInt:function(le){var val=this.view.getUint32(this.index,le!==undefined?le:this.littleEndian);this.index+=4;return val;},readFloat:function(le){var val=this.view.getFloat32(this.index,le!==undefined?le:this.littleEndian);this.index+=4;return val;},readDouble:function(le){var val=this.view.getFloat64(this.index,le!==undefined?le:this.littleEndian);this.index+=8;return val;},tell:function(){return this.index;},remaining:function(){return this.byteLength-this.index;},seek:function(index){if(index<0){fail('negative index');}
if(index>this.byteLength){fail('index greater than buffer size');}
this.index=index;},advance:function(n){var index=this.index+n;if(index<0){fail('advance past beginning of buffer');}
if(index>this.byteLength){fail('advance past end of buffer');}
this.index=index;},getUnsignedByteArray:function(offset,n){return new Uint8Array(this.buffer,offset+this.viewOffset,n);},readUnsignedByteArray:function(n){var val=new Uint8Array(this.buffer,this.index+this.viewOffset,n);this.index+=n;return val;},getBit:function(offset,bit){var byte=this.view.getUint8(offset);return(byte&(1<<bit))!==0;},getUint24:function(offset,le){var b1,b2,b3;if(le!==undefined?le:this.littleEndian){b1=this.view.getUint8(offset);b2=this.view.getUint8(offset+1);b3=this.view.getUint8(offset+2);}
else{b3=this.view.getUint8(offset);b2=this.view.getUint8(offset+1);b1=this.view.getUint8(offset+2);}
return(b3<<16)+(b2<<8)+b1;},readUint24:function(le){var value=this.getUint24(this.index,le);this.index+=3;return value;},getBinaryText:function(offset,len){var bytes=new Uint8Array(this.buffer,offset+this.viewOffset,len);return String.fromCharCode.apply(String,bytes);},readBinaryText:function(len){var s=this.getBinaryText(this.index,len);this.index+=len;return s;},getLatin1Text:function(offset,len){var bytes=new Uint8Array(this.buffer,offset+this.viewOffset,len);return getDecoder('latin1').decode(bytes);},readLatin1Text:function(len){var s=this.getLatin1Text(this.index,len);this.index+=len;return s;},getUTF8Text:function(offset,len){var bytes=new Uint8Array(this.buffer,offset+this.viewOffset,len);return getDecoder('utf-8').decode(bytes);},readUTF8Text:function(len){var s=this.getUTF8Text(this.index,len);this.index+=len;return s;},getUTF16Text:function(offset,len,le){if(len%2){fail('len must be a multiple of two');}
var bytes=new Uint8Array(this.buffer,offset+this.viewOffset,len);if(le===null||le===undefined){var BOM=(bytes[0]<<8)+bytes[1];if(BOM===0xFEFF){bytes=bytes.subarray(2);le=false;}else if(BOM===0xFFFE){bytes=bytes.subarray(2);le=true;}else{le=true;}}
var encoding=le?'utf-16le':'utf-16be';return getDecoder(encoding).decode(bytes);},readUTF16Text:function(len,le){var s=this.getUTF16Text(this.index,len,le);this.index+=len;return s;},getID3Uint28BE:function(offset){var b1=this.view.getUint8(offset)&0x7f;var b2=this.view.getUint8(offset+1)&0x7f;var b3=this.view.getUint8(offset+2)&0x7f;var b4=this.view.getUint8(offset+3)&0x7f;return(b1<<21)|(b2<<14)|(b3<<7)|b4;},readID3Uint28BE:function(){var value=this.getID3Uint28BE(this.index);this.index+=4;return value;},readNullTerminatedLatin1Text:function(size,advance_by_size=false){var bytes=new Uint8Array(this.buffer,this.viewOffset+this.index,size);var nil=bytes.indexOf(0);if(nil!==-1){bytes=bytes.subarray(0,nil);}
var s=getDecoder('latin1').decode(bytes);if(nil===-1||advance_by_size){this.index+=size;}else{this.index+=nil+1;}
return s;},readNullTerminatedUTF8Text:function(size,advance_by_size=false){var bytes=new Uint8Array(this.buffer,this.viewOffset+this.index,size);var nil=bytes.indexOf(0);if(nil!==-1){bytes=bytes.subarray(0,nil);}
var s=getDecoder('utf-8').decode(bytes);if(nil===-1||advance_by_size){this.index+=size;}else{this.index+=nil+1;}
return s;},readNullTerminatedUTF16Text:function(size,le,advance_by_size=false){if(size%2){fail('size must be a multiple of two');}
for(var len=0;len<size;len+=2){if(this.getUint16(this.index+len,le)===0){break;}}
var s=this.getUTF16Text(this.index,len,le);if(len===size||advance_by_size){this.index+=size;}else{this.index+=len+2;}
return s;}};return{get:BlobView.get,getFromArrayBuffer:BlobView.getFromArrayBuffer};}());'use strict';var MetadataFormats=(function(){var formats=[{file:'js/metadata/forward_lock.js',get module(){return ForwardLockMetadata;},match:function(header){return header.getBinaryText(0,9)==='LOCKED 1 ';}},{file:'js/metadata/id3v2.js',get module(){return ID3v2Metadata;},match:function(header){return header.getBinaryText(0,3)==='ID3';}},{file:'js/metadata/ogg.js',get module(){return OggMetadata;},match:function(header){return header.getBinaryText(0,4)==='OggS';}},{file:'js/metadata/flac.js',get module(){return FLACMetadata;},match:function(header){return header.getBinaryText(0,4)==='fLaC';}},{file:'js/metadata/mp4.js',get module(){return MP4Metadata;},match:function(header){return header.getBinaryText(4,4)==='ftyp';}},{file:'js/metadata/id3v1.js',get module(){return ID3v1Metadata;},match:function(header){return(header.getUint16(0,false)&0xFFFE)===0xFFFA;}}];function MetadataParser(formatInfo){this._formatInfo=formatInfo;}
MetadataParser.prototype={parse:function(header){var info=this._formatInfo;return LazyLoader.load(info.file).then(()=>{return info.module.parse(header);});}};function findParser(header){for(var i=0;i<formats.length;i++){if(formats[i].match(header)){return new MetadataParser(formats[i]);}}
return null;}
return{findParser:findParser};})();'use strict';var AudioMetadata=(function(){function parse(blob){var filename=blob.name;if(filename){if(filename.slice(0,5)==='DCIM/'&&filename.slice(-4).toLowerCase()==='.3gp'){return Promise.reject('skipping 3gp video file');}}
if(blob.size<128){return Promise.reject('file is empty or too small');}
return new Promise(function(resolve,reject){var headersize=Math.min(64*1024,blob.size);BlobView.get(blob,0,headersize,function(header,error){if(error){reject(error);return;}
try{var parser=MetadataFormats.findParser(header);var promise;if(parser){promise=parser.parse(header);}else{promise=checkPlayability(blob);}
resolve(promise.then(function(metadata){return addDefaultMetadata(metadata||{},filename);}));}catch(e){console.error('AudioMetadata.parse:',e,e.stack);reject(e);}});});}
function addDefaultMetadata(metadata,filename){if(!metadata.artist){metadata.artist='';}
if(!metadata.album){metadata.album='';}
if(!metadata.title){if(filename){var p1=filename.lastIndexOf('/');var p2=filename.lastIndexOf('.');if(p2<=p1){p2=filename.length;}
metadata.title=filename.substring(p1+1,p2);}else{metadata.title='';}}
metadata.rated=metadata.played=0;return metadata;}
function checkPlayability(blob){var player=new Audio();player.mozAudioChannelType='content';var canplay=blob.type&&player.canPlayType(blob.type);if(canplay==='probably'){return Promise.resolve();}else{return new Promise(function(resolve,reject){var url=URL.createObjectURL(blob);player.src=url;const CANPLAY_TIMEOUT=3000;var timeoutId=setTimeout(()=>{console.error('No oncanplay or error events seen yet.','Assuming file is corrupt:',blob.name);player.onerror();},CANPLAY_TIMEOUT);player.onerror=function(){clearTimeout(timeoutId);URL.revokeObjectURL(url);player.removeAttribute('src');player.load();reject('Unplayable music file');};player.oncanplay=function(){clearTimeout(timeoutId);URL.revokeObjectURL(url);player.removeAttribute('src');player.load();resolve();};});}}
return{parse:parse};})();

View file

@ -0,0 +1,25 @@
;'use strict';var App=(function(){var app;var chromeInteractive=false;init();function init(){navigator.mozL10n.once(function onLocalizationInit(){window.performance.mark('navigationLoaded');Database.init();TitleBar.init();TabBar.init();setStartMode();navigator.mozL10n.ready(function(){ModeManager.updateTitle();if(!chromeInteractive){chromeInteractive=true;window.performance.mark('navigationInteractive');}});});}
function setStartMode(){if(document.URL.indexOf('#pick')!==-1){navigator.mozSetMessageHandler('activity',function activityHandler(a){var activityName=a.source.name;if(activityName==='pick'){document.body.classList.add('picker-mode');app.pendingPick=a;document.getElementById('overlay-cancel-button').addEventListener('click',function(){if(App.pendingPick){App.pendingPick.postError('pick cancelled');}});}
TabBar.option='title';ModeManager.start(MODE_PICKER);});}else{TitleBar.doneButton.parentNode.removeChild(TitleBar.doneButton);TabBar.option='mix';ModeManager.start(MODE_TILES);}}
function showOverlay(id){document.activeElement.blur();app.currentOverlay=id;function setVisibility(visible){Array.forEach(document.body.children,function(elt){if(elt.id==='overlay'){elt.classList.toggle('hidden',!visible);}else{elt.setAttribute('aria-hidden',visible);}});}
if(id===null){setVisibility(false);return;}
var menu=document.getElementById('overlay-menu');if(app.pendingPick){menu.classList.remove('hidden');}else{menu.classList.add('hidden');}
var l10nIds={'title':id+'-title','text':id+'-text'};if(id==='nocard'){l10nIds.title='nocard2-title';l10nIds.text='nocard3-text';}
var titleElement=document.getElementById('overlay-title');var textElement=document.getElementById('overlay-text');titleElement.dataset.l10nId=l10nIds.title;textElement.dataset.l10nId=l10nIds.text;setVisibility(true);}
function showCorrectOverlay(){if(app.knownSongs.length>0){if(app.currentOverlay==='empty'||app.currentOverlay==='upgrade'){app.showOverlay(null);}}else{app.showOverlay('empty');}}
function dbEnumerable(callback){if(app.currentOverlay==='upgrade'){app.showOverlay(null);}
refreshViews(function(){window.performance.mark('visuallyLoaded');window.performance.mark('contentInteractive');TitleBar.view.removeAttribute('no-font-fit');document.getElementById('spinner').classList.add('hidden');setTimeout(function(){document.getElementById('spinner-overlay').classList.add('hidden');},100);if(document.URL.indexOf('#pick')===-1){setupCommunications();}
if(callback){callback();}});}
function setupCommunications(){var files=['shared/js/bluetooth_helper.js','shared/js/media/remote_controls.js','js/communications.js',];LazyLoader.load(files).then(()=>{MusicComms.init();});}
function dbReady(refresh,callback){if(app.currentOverlay==='nocard'||app.currentOverlay==='pluggedin'){app.showOverlay(null);}
if(refresh){refreshViews(callback);}else if(callback){callback();}}
function dbUnavailable(why){if(typeof PlayerView!=='undefined'){PlayerView.stop();}
if(!app.pendingPick){TabBar.option='mix';ModeManager.start(MODE_TILES,function(){TilesView.hideSearch();});}
if(why==='nocard'){app.showOverlay('nocard');}else if(why==='unmounted'){app.showOverlay('pluggedin');}}
var hidSearchBox=false;function refreshViews(callback){function showListView(){var option=TabBar.option;var info={key:'metadata.'+option,range:null,direction:(option==='title')?'next':'nextunique',option:option};ModeManager.waitForView(MODE_PICKER,()=>{ListView.activate(info);});}
if(app.pendingPick){showListView();if(callback){callback();}
return;}
if(ModeManager.currentMode===MODE_LIST&&TabBar.option!=='playlist'){showListView();}
ModeManager.waitForView(MODE_TILES,()=>{TilesView.activate(function(songs){TabBar.setDisabled(!songs.length);app.knownSongs=songs;app.showCorrectOverlay();if(app.currentOverlay===null&&!hidSearchBox){hidSearchBox=true;window.setTimeout(function(){TilesView.hideSearch();},1000);}
if(callback){callback();}});});}
app={pendingPick:null,currentOverlay:null,knownSongs:[],showOverlay:showOverlay,showCorrectOverlay:showCorrectOverlay,dbEnumerable:dbEnumerable,dbReady:dbReady,dbUnavailable:dbUnavailable,refreshViews:refreshViews};return app;})();

View file

@ -0,0 +1,6 @@
;'use strict';navigator.mozL10n.once(function onLocalizationInit(){navigator.mozSetMessageHandler('activity',handleOpenActivity);});function handleOpenActivity(request){var data=request.source.data;var blob=request.source.data.blob;var header=document.getElementById('header');var saveButton=document.getElementById('title-save');var banner=document.getElementById('banner');var message=document.getElementById('message');var storage;var saved=false;if(data.allowSave&&data.filename&&checkFilename()){saveButton.hidden=false;saveButton.disabled=true;header.runFontFit();getStorageIfAvailable('music',blob.size,function(ds){storage=ds;saveButton.disabled=false;});}
playBlob(blob);function playBlob(blob){PlayerView.init(TYPE_SINGLE);PlayerView.stop();PlaybackQueue.loadSettings().then(()=>{return AudioMetadata.parse(blob);}).then((metadata)=>{var fileinfo={metadata:metadata,name:blob.name,blob:blob};PlayerView.activate(new PlaybackQueue.StaticQueue([fileinfo]));PlayerView.start();}).catch((e)=>{console.error(e);alert(navigator.mozL10n.get('audioinvalid'));done();});}
header.addEventListener('action',done);saveButton.addEventListener('click',save);window.addEventListener('visibilitychange',function onVisibilityChanged(){if(document.hidden){done();}});function done(){PlayerView.stop();request.postResult({saved:saved});}
function save(){saveButton.hidden=true;document.getElementById('title-text').textContent=document.getElementById('title-text').textContent;getUnusedFilename(storage,data.filename,function(filename){var savereq=storage.addNamed(blob,filename);savereq.onsuccess=function(){saved=filename;showBanner(navigator.mozL10n.get('saved',{title:document.getElementById('title-text').textContent}));};savereq.onerror=function(e){console.error('Error saving',filename,e);};});}
function checkFilename(){var dotIdx=data.filename.lastIndexOf('.'),ext;if(dotIdx>-1){ext=data.filename.substr(dotIdx+1);if(ext==='ogg'){return true;}else{return MimeMapper.guessTypeFromExtension(ext)===blob.type;}}else{return false;}}
function showBanner(msg){message.textContent=msg;banner.hidden=false;setTimeout(function(){banner.hidden=true;},3000);}}

View file

@ -0,0 +1,146 @@
/* exported Playlist */
/* m3u parsing. */
/*
* http://tools.ietf.org/html/draft-pantos-http-live-streaming-14
* http://en.wikipedia.org/wiki/M3U
* http://forums.winamp.com/showthread.php?threadid=65772
* http://schworak.com/blog/e39/m3u-play-list-specification/
*/
'use strict';
/*
* API defined:
* Playlist a class that encapsulate a playlist as well as its serialisation
*
* Constructor Playlist(path)
*
* Playlist.parse(path): contruct and parse a playlist from file.
* Return a promise for it.
*/
function Playlist(path) {
this._songs = [];
this._directory = null;
if (path) {
this._directory = path;
var idx = this._directory.lastIndexOf('/');
if (idx !== -1) {
this._directory = this._directory.slice(0, idx + 1);
}
}
}
Playlist.parse = function(path) {
var promise = new Promise(
function(resolve, reject) {
var storage = navigator.getDeviceStorage('music');
var request = storage.get(path);
request.onsuccess = function() {
var reader = new FileReader();
var file = request.result;
reader.readAsText(file);
reader.onerror = function() {
reject(new Error('Error reading: ' + path + ': ' + this.error));
};
reader.onload = function() {
var pl = new Playlist(path);
pl.fromString(reader.result);
resolve(pl);
};
};
request.onerror = function() {
reject(new Error('Couldn\'t get path: ' + path + ': ' + this.error));
};
});
return promise;
};
Playlist.isUrl = function(path) {
var re = /^(https?|ftp|file|mms|rtmp):\//;
return re.test(path);
};
Playlist.prototype = {
get songs() {
return this._songs;
},
get directory() {
return this._directory;
},
// m3u state that path is either absolute or relative to the playlist
_makeAbsolutePath: function(path) {
if (!this._directory || Playlist.isUrl(path)) {
return path;
}
if (path[0] === '/') {
return path;
}
return this._directory + path;
},
/*
* song is a path string.
* index is the index to insert the song at. If -1 or undefined
* song is added at the end if the array.
*/
addSong: function(song, index) {
if (!song) {
throw new Error('invalid');
}
var absPath = this._makeAbsolutePath(song);
if (index === undefined || index === -1 || index >= this._songs.length) {
this._songs.push(absPath);
} else {
this._songs.splice(index, 0, absPath);
}
},
removeSong: function(path) {
var absPath = this._makeAbsolutePath(path);
var idx = this._songs.indexOf(absPath);
if (idx != -1) {
this._songs.splice(idx, 1);
}
},
removeSongAt: function(index) {
this._songs.splice(index, 1);
},
toString: function() {
var content = '';
content += '#EXTM3U\n';
var entry;
for (entry of this._songs) {
content += entry + '\n';
}
return content;
},
fromString: function(content) {
var lines = content.toString().split('\n');
for (var i = 0; i < lines.length; i++){
var line = lines[i].trim();
if (line === '' || line.startsWith('#')) {
continue;
}
this._songs.push(this._makeAbsolutePath(line));
}
}
};

View file

@ -0,0 +1,19 @@
;'use strict';var PlaybackQueue=(function(){var SETTINGS_OPTION_KEY='settings_option_key';var Repeat={OFF:0,LIST:1,SONG:2,next:function(val){return(val+1)%3;}};function posmod(a,b){var r=a%b;return r<0?r+b:r;}
function fillIndices(length){var indices=new Array(length);for(var i=0;i<length;i++){indices[i]=i;}
return indices;}
function shuffle(list){for(var i=list.length-1;i>=1;i--){var j=Math.floor(Math.random()*(i+1));if(j<i){var tmp=list[j];list[j]=list[i];list[i]=tmp;}}}
function BaseQueue(){this._index=null;}
BaseQueue.prototype={_init:function(index){if(this.length===0){throw Error('cannot have an empty queue');}
this._index=index||0;this._shuffle(playbackSettings.shuffle,index!==undefined);},_shuffle:function(enabled,keepIndex=true){this._shuffleTime=Date.now();if(!enabled){if(keepIndex){this._index=this.index;}
delete this._shuffledList;return;}
this._shuffledList=fillIndices(this.length);var oldIndex=null;if(keepIndex){oldIndex=this._shuffledList.splice(this._index,1)[0];this._index=0;}
shuffle(this._shuffledList);if(keepIndex){this._shuffledList.unshift(oldIndex);}},next:function(automatic=false){return this.advance(1,automatic);},previous:function(){this.advance(-1);},advance:function(offset,automatic=false){var next;var justShuffled=false;if(this._shuffleTime<shuffleTime){this._shuffle(playbackSettings.shuffle);justShuffled=true;}
switch(PlaybackQueue.repeat){case Repeat.OFF:next=Math.max(this._index+offset,0);break;case Repeat.LIST:next=posmod(this._index+offset,this.length);var cycled=next!==this._index+offset;if(playbackSettings.shuffle&&cycled&&!justShuffled){this._shuffle(true);}
break;case Repeat.SONG:next=automatic?this._index:Math.max(this._index+offset,0);break;default:throw new Error('unexpected repeat status: '+this.repeat);}
if(next>=this.length){this._index=null;return false;}
this._index=next;return true;},get index(){return this._shuffledList?this._shuffledList[this._index]:this._index;},get rawIndex(){return this._index;}};function StaticQueue(fileinfos,index){this._fileinfos=fileinfos;this._init(index);}
StaticQueue.prototype=new BaseQueue();Object.defineProperty(StaticQueue.prototype,'length',{get:function(){return this._fileinfos.length;}});StaticQueue.prototype.current=function(){return Promise.resolve(this._fileinfos[this.index]);};function DynamicQueue(query,index){this._query=query;this._init(index);}
DynamicQueue.prototype=new BaseQueue();Object.defineProperty(DynamicQueue.prototype,'length',{get:function(){return this._query.count;}});DynamicQueue.prototype.current=function(){var query=this._query;return new Promise((resolve,reject)=>{var handle=Database.advancedEnumerate(query.key,query.range,query.direction,this.index,(record)=>{Database.cancelEnumeration(handle);resolve(record);});});};var playbackSettings=null;var shuffleTime=0;function loadSettings(){return new Promise((resolve,reject)=>{asyncStorage.getItem(SETTINGS_OPTION_KEY,(settings)=>{if(settings){playbackSettings=settings;}else{playbackSettings={repeat:Repeat.OFF,shuffle:false};}
resolve();});});}
function saveSettings(){return new Promise((resolve,reject)=>{asyncStorage.setItem(SETTINGS_OPTION_KEY,playbackSettings,()=>{resolve();});});}
return{StaticQueue:StaticQueue,DynamicQueue:DynamicQueue,Repeat:Repeat,loadSettings:loadSettings,get repeat(){return playbackSettings.repeat;},set repeat(val){playbackSettings.repeat=val;saveSettings();return val;},get shuffle(){return playbackSettings.shuffle;},set shuffle(val){playbackSettings.shuffle=val;shuffleTime=Date.now();saveSettings();return val;},};})();

View file

@ -0,0 +1,5 @@
;'use strict';var TabBar={playlistArray:[{metadata:{l10nId:'playlists-shuffle-all'},option:'shuffleAll'},{metadata:{l10nId:'playlists-highest-rated'},option:'rated'},{metadata:{l10nId:'playlists-recently-added'},option:'date'},{metadata:{l10nId:'playlists-most-played'},option:'played'},{metadata:{l10nId:'playlists-least-played'},option:'played'},null],get view(){return document.getElementById('tabs');},get tabs(){return this.view.querySelectorAll('[role="tab"]');},set option(choice){var map={'mix':'tabs-mix','playlist':'tabs-playlists','artist':'tabs-artists','album':'tabs-albums','title':'tabs-songs'};var tab=document.getElementById(map[choice]);AccessibilityHelper.setAriaSelected(tab,this.tabs);this._option=choice;},get option(){return this._option;},init:function tab_init(){this.option='mix';this.view.addEventListener('touchend',this);},setDisabled:function tab_setDisabled(option){this.disabled=option;},handleEvent:function tab_handleEvent(evt){if(this.disabled){return;}
switch(evt.type){case'touchend':var target=evt.target;if(!target){return;}
if(this.option===target.dataset.option){return;}else{this.option=target.dataset.option;}
switch(target.id){case'tabs-mix':ListView.cancelEnumeration();ModeManager.start(MODE_TILES);TilesView.hideSearch();break;case'tabs-playlists':ModeManager.start(MODE_LIST,function(){ListView.activate();this.playlistArray.forEach(function(playlist){ListView.update(this.option,playlist);}.bind(this));}.bind(this));break;case'tabs-artists':case'tabs-albums':case'tabs-songs':var info={key:'metadata.'+this.option,range:null,direction:(this.option==='title')?'next':'nextunique',option:this.option};ModeManager.start(MODE_LIST,function(){ListView.activate(info);});break;}
break;default:return;}}};

View file

@ -0,0 +1,8 @@
;'use strict';var TitleBar={get view(){return document.getElementById('title');},get titleText(){return document.querySelector('#title-text bdi');},get playerIcon(){return document.getElementById('title-player');},get doneButton(){return document.getElementById('title-done');},get scanProgress(){return document.getElementById('scan-progress');},get scanSpinner(){return document.getElementById('scan-spinner');},get scanCount(){return document.getElementById('scan-count');},get scanArtist(){return document.getElementById('scan-artist');},get scanTitle(){return document.getElementById('scan-title');},init:function tb_init(){this.view.addEventListener('click',this);this.view.addEventListener('action',this.onActionBack);},changeTitleText:function tb_changeTitleText(content){this.titleText.textContent=content;},showBackArrow:function(show){if(show){this.view.setAttribute('action','back');}
else{this.view.removeAttribute('action');}},onActionBack:function(){if(App.pendingPick){if(ModeManager.currentMode===MODE_PICKER){App.pendingPick.postError('pick cancelled');return;}
PlayerView.stop();}
ModeManager.pop();},showScanProgress:function(info){this.scanProgress.classList.remove('hidden');this.scanSpinner.classList.remove('hidden');this.scanCount.textContent=info.count;this.scanArtist.textContent=info.artist||'';this.scanTitle.textContent=info.title||'';},hideScanProgress:function(){this.scanSpinner.classList.add('hidden');setTimeout(function(){this.scanProgress.classList.add('hidden');}.bind(this),100);},handleEvent:function tb_handleEvent(evt){var target=evt.target;function cleanupPick(){PlayerView.stop();}
switch(evt.type){case'click':if(!target){return;}
switch(target.id){case'title-player':if(PlayerView.isQueued){ModeManager.push(MODE_PLAYER);}
break;case'title-done':var currentFileInfo=PlayerView.currentFileInfo;LazyLoader.load('js/metadata/album_art_cache.js').then(()=>{return AlbumArtCache.getThumbnailBlob(currentFileInfo);}).then((picture)=>{var currentMetadata=currentFileInfo.metadata;var playingBlob=PlayerView.playingBlob;App.pendingPick.postResult({type:playingBlob.type,blob:playingBlob,name:currentMetadata.title||'',metadata:{title:currentMetadata.title,artist:currentMetadata.artist,album:currentMetadata.album,picture:picture}});cleanupPick();});break;}
break;default:return;}}};

View file

@ -0,0 +1,430 @@
/* exported ListView */
/* global App, createListElement, Database, IDBKeyRange, ModeManager,
MODE_PLAYER, MODE_SUBLIST, MODE_SEARCH_FROM_LIST, PlaybackQueue,
PlayerView, SearchView, SubListView, TabBar */
'use strict';
// Assuming the ListView will prepare 5 pages for batch loading.
// Each page contains 7 list elements.
var LIST_BATCH_SIZE = 7 * 5;
// View of List
var ListView = {
get view() {
return document.getElementById('views-list');
},
get anchor() {
return document.getElementById('views-list-anchor');
},
get searchBox() {
return document.getElementById('views-list-search');
},
get searchInput() {
return document.getElementById('views-list-search-input');
},
get dataSource() {
return this._dataSource;
},
set dataSource(source) {
this._dataSource = source;
},
init: function lv_init() {
this.clean();
this.view.addEventListener('click', this);
this.view.addEventListener('touchmove', this);
this.view.addEventListener('scroll', this);
this.searchInput.addEventListener('focus', this);
},
clean: function lv_clean() {
this.cancelEnumeration();
this.info = null;
this.handle = null;
this.dataSource = [];
this.index = 0;
this.lastDataIndex = 0;
this.firstLetters = [];
this.lastFirstLetter = null;
this.anchor.innerHTML = '';
this.anchor.style.height = 0;
this.view.scrollTop = 0;
this.hideSearch();
this.moveTimer = null;
this.scrollTimer = null;
},
cancelEnumeration: function lv_cancelEnumeration() {
// Cancel a pending enumeration before start a new one
if (this.handle) {
Database.cancelEnumeration(this.handle);
}
},
hideSearch: function lv_hideSearch() {
this.searchInput.value = '';
// XXX: we probably want to animate this...
if (this.view.scrollTop < this.searchBox.offsetHeight) {
this.view.scrollTop = this.searchBox.offsetHeight;
}
},
// This function basically create the section header of the list elements.
// When we hit a different first letter, this function will use it to
// create a new header then keep it, until to hit another different one,
// it will create the next header with the new first letter.
createHeader: function lv_createHeader(option, result) {
var firstLetter = result.metadata[option].charAt(0);
var headerLi;
if (this.lastFirstLetter !== firstLetter) {
this.lastFirstLetter = firstLetter;
headerLi = document.createElement('li');
headerLi.className = 'list-header';
headerLi.textContent = this.lastFirstLetter || '?';
headerLi.setAttribute('role', 'heading');
headerLi.setAttribute('aria-level', '2');
}
return headerLi;
},
activate: function lv_activate(info) {
// If info is not provided, then we should be displaying playlists,
// so it does not need to enumerate from MediaDB.
if (!info) {
this.clean();
return;
}
// Choose one of the indexes to get the count and it should be the
// correct count because failed records don't contain metadata, so
// here we just pick the album, artist or title as indexes.
Database.count('metadata.' + info.option, null, function(count) {
this.clean();
this.info = info;
// Keep the count with the info for later use in PlayerView.
this.info.count = count;
this.handle = Database.enumerate(info.key, info.range, info.direction,
function(record) {
if (record) {
// Check if music is in picker mode because we don't to allow the
// user to pick locked music.
if (!App.pendingPick || !record.metadata.locked) {
this.dataSource.push(record);
}
// Save the current length of the dataSource to lastDataIndex
// because we might expand the length to the total count of
// the records, since we cannot retrieve all of them in a short
// time and the enumeration might be cancelled.
// It will also be used to judge the enumeration is end of not.
this.lastDataIndex = this.dataSource.length;
}
// When we got the first batch size of the records,
// or the total count is less than the batch size,
// display it so that users are able to see the first paint
// very quickly.
if (this.dataSource.length === LIST_BATCH_SIZE || !record) {
this.batchUpdate(info.option, LIST_BATCH_SIZE);
// If record is null then the enumeration is finished,
// so ListView has all the records and is able to adjust
// the height.
count = record ? count : null;
this.adjustHeight(info.option, count);
// In picker mode we have to use the ListView's dataSource to
// display the correct overlay.
if (App.pendingPick) {
App.knownSongs = this.dataSource;
App.showCorrectOverlay();
}
}
}.bind(this));
}.bind(this));
},
update: function lv_update(option, result) {
if (result === null) {
App.showCorrectOverlay();
return;
}
this.dataSource.push(result);
if (option !== 'playlist') {
var header = this.createHeader(option, result);
if (header) {
this.anchor.appendChild(header);
}
}
this.anchor.appendChild(createListElement(option, result, this.index));
this.index++;
},
// This function is used for judging if the ListView should update and the
// range it should update, it sees where the bottom element is and calculates
// its position to know how many to update.
judgeAndUpdate: function lv_judgeAndUpdate() {
// If there is no lastChild then the first paint is not drawn yet.
// Also if the info is not provide, we don't have to judge for updating.
if (!this.anchor.lastChild || !this.info) {
return;
}
var itemHeight = this.anchor.lastChild.offsetHeight;
var scrolledHeight = this.view.scrollTop + this.view.offsetHeight;
var position = Math.round(scrolledHeight / itemHeight);
var last = this.anchor.children.length;
var range = position + this.firstLetters.length - last;
if (range > 0) {
this.batchUpdate(TabBar.option, range + LIST_BATCH_SIZE);
// If list handle is cancelled and the lastDataIndex is not -1,
// it means the enumeration was cancelled and the dataSource is incomplete
// so that we have to resume it from the last data index we have.
if (this.handle.state === 'cancelled' && this.lastDataIndex > -1) {
var info = this.info;
var index = this.lastDataIndex + 1;
this.handle = Database.advancedEnumerate(
info.key, info.range, info.direction, index, function(record) {
if (record) {
this.dataSource[index] = record;
this.lastDataIndex = index;
index++;
} else {
this.lastDataIndex = -1;
}
}.bind(this)
);
}
}
},
// See where is the last index we have for the existing children, and start
// to create the rest elements from it, note that here we use fragment to
// update all the new elements at once, this is for reducing the amount of
// appending child to the DOM tree.
batchUpdate: function lv_batchUpdate(option, range) {
var start = this.index;
var end = start + range;
var fragment = document.createDocumentFragment();
if (end > this.dataSource.length) {
end = this.dataSource.length;
}
for (var i = start; i < end; i++) {
var data = this.dataSource[i];
if (data) {
var header = this.createHeader(option, data);
if (header) {
fragment.appendChild(header);
}
fragment.appendChild(createListElement(option, data, this.index));
this.index++;
}
}
this.anchor.appendChild(fragment);
},
// Because the correct height of ListView depends on how many records and
// how many section headers it got, also we don't want to cause too many
// repaints by appending children to the DOM tree and changes the height,
// when we got the first count from the MediaDB or the enumeration is end,
// we can fake the the height by the first adjustment(count), then fix the
// height to correct by the second adjustment(record is null).
adjustHeight: function lv_adjustHeight(option, count) {
// If it's the first launch, then dataSource will be empty and we don't
// need to adjust the height.
if (this.dataSource.length === 0) {
return;
}
if (!count) {
count = this.dataSource.length;
this.firstLetters.length = 0;
var previousFirstLetter;
for (var i = 0; i < this.dataSource.length; i++) {
var metadata = this.dataSource[i].metadata;
var firstLetter = metadata[option].charAt(0);
if (previousFirstLetter !== firstLetter) {
this.firstLetters.push(firstLetter);
previousFirstLetter = firstLetter;
}
}
} else {
// Assuming we have all the letters from A to Z.
this.firstLetters.length = 26;
}
var headerHeight = this.anchor.firstChild.offsetHeight;
var itemHeight = this.anchor.lastChild.offsetHeight;
var bottomHeight = parseInt(getComputedStyle(this.anchor.lastChild, null).
getPropertyValue('margin-bottom'), 10);
this.anchor.style.height = (
headerHeight * this.firstLetters.length +
itemHeight * count +
bottomHeight
) + 'px';
},
playWithShuffleAll: function lv_playWithShuffleAll() {
ModeManager.push(MODE_PLAYER, () => {
PlayerView.clean();
Database.count('metadata.title', null, (count) => {
var info = {
key: 'metadata.title',
range: null,
direction: 'next',
option: 'title',
count: count
};
PlaybackQueue.shuffle = true;
PlayerView.activate(new PlaybackQueue.DynamicQueue(info));
PlayerView.start();
});
});
},
playWithIndex: function lv_playWithIndex(index) {
ModeManager.push(MODE_PLAYER, () => {
// Because the ListView might still retrieving the records, and
// we are assigning the dataSource to the PlayerView, since
// setDBInfo will expand the dataSource length to the total
// count we will be retrieved, we must cancel the enumeration
// or the length will be expanded to a wrong number.
this.cancelEnumeration();
PlayerView.clean();
PlayerView.activate(new PlaybackQueue.DynamicQueue(this.info, index));
PlayerView.start();
});
},
activateSubListView: function lv_activateSubListView(target) {
var option = target.dataset.option;
var index = target.dataset.index;
var data = this.dataSource[index];
var keyRange = (target.dataset.keyRange != 'all') ?
IDBKeyRange.only(target.dataset.keyRange) : null;
var l10nId = data.metadata.l10nId;
var direction =
(l10nId === 'playlists-most-played' ||
l10nId === 'playlists-recently-added' ||
l10nId === 'playlists-highest-rated') ?
'prev' : 'next';
// SubListView needs to prepare the songs data before entering it,
// So here we initialize the SubListView before push the view.
ModeManager.waitForView(MODE_SUBLIST, () => {
SubListView.activate(option, data, index, keyRange, direction, () => {
ModeManager.push(MODE_SUBLIST);
});
});
},
handleEvent: function lv_handleEvent(evt) {
var target = evt.target;
if (!target) {
return;
}
switch (evt.type) {
case 'click':
if (target.id === 'views-list-search-close') {
if (ModeManager.currentMode === MODE_SEARCH_FROM_LIST) {
ModeManager.pop();
}
this.hideSearch();
evt.preventDefault();
} else {
var option = target.dataset.option;
// When an user select "Shuffle all"
// We just play all songs with shuffle order
// or change mode to subList view and list songs
if (option === 'shuffleAll') {
this.playWithShuffleAll();
} else if (option === 'title') {
this.playWithIndex(parseInt(target.dataset.index, 10));
} else if (option) {
this.activateSubListView(target);
}
}
break;
case 'focus':
if (target.id === 'views-list-search-input') {
if (ModeManager.currentMode !== MODE_SEARCH_FROM_LIST) {
ModeManager.start(MODE_SEARCH_FROM_LIST, function() {
// Let the search view gets the focus.
SearchView.searchInput.focus();
});
}
}
break;
case 'touchmove':
// Start the rest batch updating after the first paint
if (this.anchor.children.length === 0) {
return;
}
if (this.moveTimer) {
clearTimeout(this.moveTimer);
}
// If the move timer is not cancelled, it should be a suitable time
// to update the ui because we don't want to render elements while
// the list is scrolling.
this.moveTimer = setTimeout(function() {
this.judgeAndUpdate();
this.moveTimer = null;
}.bind(this), 50);
break;
case 'scroll':
// Start the rest batch updating after the first paint
if (this.anchor.children.length === 0) {
return;
}
if (this.scrollTimer) {
clearTimeout(this.scrollTimer);
}
// If the user try to scroll as possible as it can, after the scrolling
// stops, we can see where the position is and try to render the rest
// elements that should be displayed on the screen.
this.scrollTimer = setTimeout(function() {
this.judgeAndUpdate();
this.scrollTimer = null;
}.bind(this), 500);
break;
default:
return;
}
}
};

View file

@ -0,0 +1,12 @@
;'use strict';var MODE_TILES=1;var MODE_LIST=2;var MODE_SUBLIST=3;var MODE_PLAYER=4;var MODE_SEARCH_FROM_TILES=5;var MODE_SEARCH_FROM_LIST=6;var MODE_PICKER=7;var ModeManager={views:{1:{id:'views-tiles',paths:['js/ui/views/tiles_view.js']},2:{id:'views-list',paths:['js/ui/views/list_view.js']},3:{id:'views-sublist',paths:['js/ui/views/subList_view.js']},4:{id:'views-player',paths:['js/ui/views/player_view.js','js/queue.js']},5:{id:'views-search',paths:['js/ui/views/search_view.js','shared/js/text_normalizer.js']},6:{id:'views-search',paths:['js/ui/views/search_view.js','shared/js/text_normalizer.js']},7:{id:'views-list',paths:['js/ui/views/list_view.js']}},_modeStack:[],playerTitle:null,get currentMode(){return this._modeStack[this._modeStack.length-1];},get previousMode(){return this._modeStack[this._modeStack.length-2];},start:function(mode,callback){this._modeStack=[];this._resetViews();this._pushMode(mode,false,function(){this._modeStack=[mode];this._updateMode(callback);}.bind(this));},push:function(mode,callback){this._pushMode(mode,true,function(){this._modeStack.push(mode);this._updateMode(callback);}.bind(this));},pop:function(){if(this._modeStack.length<=1){return;}
this._popMode();this._modeStack.pop();this._updateMode();},_resetViews:function(){for(var mode in this.views){var sheet=document.getElementById(this.views[mode].id);sheet.classList.remove('animated');sheet.classList.remove('current');sheet.classList.add('next');}},waitForView:function(mode,callback){var view=this.views[mode];if(view.isLoaded){if(callback){callback(view);return;}}
LazyLoader.load(view.paths).then(()=>{if(view.isLoaded){return;}
var sheet=document.getElementById(view.id);sheet.classList.remove('hidden');switch(view.id){case'views-tiles':TilesView.init();break;case'views-list':ListView.init();break;case'views-sublist':SubListView.init();break;case'views-player':if(App.pendingPick){PlayerView.init(TYPE_SINGLE,false);}else{PlayerView.init(TYPE_LIST);}
break;case'views-search':SearchView.init();break;}
if(view.id==='views-player'){return PlaybackQueue.loadSettings();}}).then(()=>{view.isLoaded=true;if(callback){callback(view);}});},_pushMode:function(mode,animated,callback){this.waitForView(mode,(view)=>{var nextId=view.id;var currentId=this.currentMode?this.views[this.currentMode].id:null;var nextSheet=document.getElementById(nextId);var currentSheet=document.getElementById(currentId);if(nextSheet){nextSheet.classList.toggle('animated',animated);nextSheet.classList.remove('previous');nextSheet.classList.remove('next');nextSheet.classList.add('current');}
if(currentSheet){currentSheet.classList.toggle('animated',animated);currentSheet.classList.remove('current');currentSheet.classList.add('previous');}
if(callback){callback();}});},_popMode:function(callback){var currentId=this.views[this.currentMode].id;var previousId=this.views[this.previousMode].id;var currentSheet=document.getElementById(currentId);var previousSheet=document.getElementById(previousId);currentSheet.classList.remove('current');currentSheet.classList.add('next');previousSheet.classList.remove('previous');previousSheet.classList.add('current');if(callback){callback();}},_updateBackArrow:function(){var noBackArrow=[MODE_TILES,MODE_LIST,MODE_SEARCH_FROM_TILES,MODE_SEARCH_FROM_LIST];var hide=noBackArrow.indexOf(this.currentMode)>-1;TitleBar.showBackArrow(!hide);},updateTitle:function(){var title;switch(this.currentMode){case MODE_TILES:title=this.playerTitle||navigator.mozL10n.get('music');break;case MODE_LIST:case MODE_SUBLIST:switch(TabBar.option){case'playlist':title=navigator.mozL10n.get('playlists');break;case'artist':title=navigator.mozL10n.get('artists');break;case'album':title=navigator.mozL10n.get('albums');break;case'title':title=navigator.mozL10n.get('songs');break;}
break;case MODE_PLAYER:title=this.playerTitle||navigator.mozL10n.get('unknownTitle');break;case MODE_PICKER:title=navigator.mozL10n.get('picker-title');break;}
if(title){TitleBar.changeTitleText(title);}
TitleBar.view.hidden=this.currentMode===MODE_SEARCH_FROM_TILES||this.currentMode===MODE_SEARCH_FROM_LIST;},updatePlayerIcon:function(){var isPlayerMode=(this.currentMode===MODE_PLAYER);var isPlayerQueued=(this.views[MODE_PLAYER].isLoaded&&PlayerView.isQueued);TitleBar.playerIcon.hidden=isPlayerMode||!isPlayerQueued;if(App.pendingPick){TitleBar.doneButton.hidden=!isPlayerMode;}},_updateTabs:function(){var hideTabs=this.currentMode===MODE_PLAYER||this.currentMode===MODE_SEARCH_FROM_TILES||this.currentMode===MODE_SEARCH_FROM_LIST;TabBar.view.classList.toggle('away',hideTabs);},_updateMode:function(callback){this._updateBackArrow();this.updateTitle();this.updatePlayerIcon();this._updateTabs();this._enableNFCSharing((this.currentMode===MODE_PLAYER));if(callback){callback();}},_enableNFCSharing:function(enabled){if(!navigator.mozNfc){return;}
if(enabled&&!App.pendingPick){navigator.mozNfc.onpeerready=function(event){var peer=event.peer;if(peer){peer.sendFile(PlayerView.playingBlob);}};}else{navigator.mozNfc.onpeerready=null;}}};

View file

@ -0,0 +1,34 @@
;'use strict';var TYPE_LIST='list';var TYPE_SINGLE='single';var PLAYSTATUS_STOPPED='STOPPED';var PLAYSTATUS_PLAYING='PLAYING';var PLAYSTATUS_PAUSED='PAUSED';var PLAYSTATUS_FWD_SEEK='FWD_SEEK';var PLAYSTATUS_REV_SEEK='REV_SEEK';var INTERRUPT_BEGIN='mozinterruptbegin';var PlayerView={_repeatModes:['off','list','song'],get view(){return document.getElementById('views-player');},get audio(){return document.getElementById('player-audio');},get foreCoverImage(){return document.querySelector('.cover-image.visible');},get backCoverImage(){return document.querySelector('.cover-image:not(.visible)');},get playStatus(){return this._playStatus;},set playStatus(val){this._playStatus=val;},get isQueued(){return Boolean(this.queue&&this.queue.length);},init:function pv_init(type=TYPE_LIST,autoplay=true){this.artist=document.getElementById('player-cover-artist');this.album=document.getElementById('player-cover-album');this.artistText=document.querySelector('#player-cover-artist bdi');this.albumText=document.querySelector('#player-cover-album bdi');this.timeoutID;this.cover=document.getElementById('player-cover');this.coverImageURL=null;this.shareButton=document.getElementById('player-cover-share');this.repeatButton=document.getElementById('player-album-repeat');this.shuffleButton=document.getElementById('player-album-shuffle');this.ratings=document.getElementById('player-album-rating').children;this.seekSlider=document.getElementById('player-seek');this.seekRegion=document.getElementById('player-seek-bar');this.seekBar=document.getElementById('player-seek-bar-progress');this.seekIndicator=document.getElementById('player-seek-bar-indicator');this.seekElapsed=document.getElementById('player-seek-elapsed');this.seekRemaining=document.getElementById('player-seek-remaining');this.playControl=document.getElementById('player-controls-play');this.previousControl=document.getElementById('player-controls-previous');this.nextControl=document.getElementById('player-controls-next');this.banner=document.getElementById('info-banner');this.isTouching=false;this.isFastSeeking=false;this.playStatus=PLAYSTATUS_STOPPED;this.pausedPosition=null;this.handle=null;this.currentFileInfo=null;this.playingBlob=null;this.setSeekBar(0,0);this.intervalID=null;this.view.addEventListener('click',this);this.view.addEventListener('contextmenu',this);this.seekRegion.addEventListener('touchstart',this);this.seekRegion.addEventListener('touchmove',this);this.seekRegion.addEventListener('touchend',this);this.seekSlider.addEventListener('keypress',this);this.previousControl.addEventListener('touchend',this);this.nextControl.addEventListener('touchend',this);this.audio.addEventListener('play',this);this.audio.addEventListener('pause',this);this.audio.addEventListener('playing',this);this.audio.addEventListener('durationchange',this);this.audio.addEventListener('timeupdate',this);this.audio.addEventListener('ended',this);this.audio.addEventListener('mozinterruptbegin',this);this.audio.addEventListener('mozinterruptend',this);window.addEventListener('visibilitychange',this);window.addEventListener('storage',this._handleInterpageMessage.bind(this));navigator.mozL10n.ready(this.updateL10n.bind(this));this.type=type;this.autoplay=autoplay;if(this.type===TYPE_SINGLE){this.shuffleButton.disabled=true;this.repeatButton.disabled=true;this.previousControl.disabled=true;this.nextControl.disabled=true;}},checkSCOStatus:function pv_checkSCOStatus(){if(typeof MusicComms!=='undefined'&&MusicComms.enabled){var SCOStatus=MusicComms.isSCOEnabled;this.playControl.disabled=this.previousControl.disabled=this.nextControl.disabled=SCOStatus;this.seekRegion.parentNode.classList.toggle('disabled',SCOStatus);this.banner.classList.toggle('visible',SCOStatus);}},clean:function pv_clean(){if(this.handle){Database.cancelEnumeration(this.handle);}
this.queue=null;this.playingBlob=null;this.coverImageURL=null;this.foreCoverImage.style.backgroundImage='';},activate:function pv_activate(queue){this.queue=queue;this.shuffleButton.disabled=(this.queue.length<2);this.setRepeat(PlaybackQueue.repeat);this.setShuffle(PlaybackQueue.shuffle);},showInfo:function pv_showInfo(){this.cover.classList.add('slideOut');if(this.timeoutID){window.clearTimeout(this.timeoutID);}
this.timeoutID=window.setTimeout(function pv_hideInfo(){this.cover.classList.remove('slideOut');}.bind(this),5000);},setInfo:function pv_setInfo(fileinfo){this.currentFileInfo=fileinfo;var metadata=fileinfo.metadata;if(typeof ModeManager!=='undefined'){ModeManager.playerTitle=metadata.title;ModeManager.updateTitle();if(metadata.locked||this.type===TYPE_SINGLE){this.shareButton.classList.add('hidden');this.artist.classList.add('hidden-cover-share');this.album.classList.add('hidden-cover-share');}else{this.shareButton.classList.remove('hidden');this.artist.classList.remove('hidden-cover-share');this.album.classList.remove('hidden-cover-share');}}else{var titleBar=document.querySelector('#title-text bdi');titleBar.textContent=metadata.title||navigator.mozL10n.get('unknownTitle');titleBar.dataset.l10nId=metadata.title?'':'unknownTitle';}
this.artistText.textContent=metadata.artist||navigator.mozL10n.get('unknownArtist');this.artistText.dataset.l10nId=metadata.artist?'':'unknownArtist';this.albumText.textContent=metadata.album||navigator.mozL10n.get('unknownAlbum');this.albumText.dataset.l10nId=metadata.album?'':'unknownAlbum';this.setCoverImage(fileinfo);},setCoverImage:function pv_setCoverImage(fileinfo){LazyLoader.load('js/metadata/album_art_cache.js').then(()=>{return AlbumArtCache.getFullSizeURL(fileinfo);}).then((url)=>{if(this.coverImageURL!==url){this.coverImageURL=url;var back=this.backCoverImage,fore=this.foreCoverImage;back.style.backgroundImage='url('+url+')';back.classList.add('visible');fore.classList.remove('visible');}});},getRepeat:function pv_getRepeat(){return this._repeatModes.indexOf(this.repeatButton.value);},setRepeat:function pv_setRepeat(value){this.repeatButton.value=this._repeatModes[value];this.repeatButton.setAttribute('data-l10n-id','repeat-'+this._repeatModes[value]);},setShuffle:function pv_setShuffle(value){this.shuffleButton.classList.toggle('shuffle-on',value);this.shuffleButton.setAttribute('aria-pressed',value);},setRatings:function pv_setRatings(rated){for(var i=0;i<5;i++){var rating=this.ratings[i];if(i===rated-1){rating.setAttribute('aria-checked',true);}else{rating.setAttribute('aria-checked',false);}
if(i<rated){rating.classList.add('star-on');}else{rating.classList.remove('star-on');}}},setAudioSrc:function pv_setAudioSrc(file){var url=URL.createObjectURL(file);this.playingBlob=file;this.audio.removeAttribute('src');this.audio.load();this.audio.mozAudioChannelType='content';this.audio.src=url;this.audio.load();this.audio.play();this.audio.onloadeddata=function(evt){URL.revokeObjectURL(url);};this.audio.onerror=(function(evt){if(this.onerror){this.onerror(evt);}}).bind(this);this.setSeekBar(0,0);},updateRemoteMetadata:function pv_updateRemoteMetadata(){if(typeof MusicComms==='undefined'||this.queue.length===0){return;}
var metadata=this.currentFileInfo.metadata;var notifyMetadata={title:metadata.title||navigator.mozL10n.get('unknownTitle'),artist:metadata.artist||navigator.mozL10n.get('unknownArtist'),album:metadata.album||navigator.mozL10n.get('unknownAlbum'),duration:this.audio.duration*1000,mediaNumber:this.rawIndex+1,totalMediaCount:this.queue.length};if(this.audio.currentTime===0){LazyLoader.load('js/metadata/album_art_cache.js').then(()=>{return AlbumArtCache.getThumbnailBlob(this.currentFileInfo);}).then((blob)=>{notifyMetadata.picture=blob;MusicComms.notifyMetadataChanged(notifyMetadata);});}else{MusicComms.notifyMetadataChanged(notifyMetadata);}},updateRemotePlayStatus:function pv_updateRemotePlayStatus(){if(typeof MusicComms==='undefined'){return;}
var position=this.pausedPosition?this.pausedPosition:this.audio.currentTime;var info={playStatus:this.playStatus,duration:this.audio.duration*1000,position:position*1000};this.pausedPosition=(this.playStatus===PLAYSTATUS_PLAYING)?null:this.audio.currentTime;MusicComms.notifyStatusChanged(info);},PLAYER_IS_OCCUPIED_BY:'music-player-is-occupied-by',_handleInterpageMessage:function(evt){if(evt.key===this.PLAYER_IS_OCCUPIED_BY){if(evt.newValue&&evt.newValue!==location.href){this.pause();}}},_sendInterpageMessage:function(){window.localStorage.setItem(this.PLAYER_IS_OCCUPIED_BY,location.href);},_clearInterpageMessage:function(){var whoIsPlaying=window.localStorage.getItem(this.PLAYER_IS_OCCUPIED_BY);if(whoIsPlaying&&whoIsPlaying===window.location.href){window.localStorage.removeItem(this.PLAYER_IS_OCCUPIED_BY);}},start:function pv_start(autoplay=true){this.checkSCOStatus();this._sendInterpageMessage();this.showInfo();this.queue.current().then((songData)=>{this.setInfo(songData);if(songData.blob){return songData.blob;}
this.setRatings(songData.metadata.rated);Database.incrementPlayCount(songData);return Database.getFile(songData,true);}).then((file)=>{this.setAudioSrc(file);if(!autoplay||!this.autoplay||MusicComms.isSCOEnabled){this.pause();}}).catch(function(msg){console.error(msg);});},play:function pv_play(targetIndex){this.checkSCOStatus();this._sendInterpageMessage();this.showInfo();if(this.audio.duration>20&&this.audio.duration-this.audio.currentTime<1){this.next(true);}else{this.audio.play();}},pause:function pv_pause(){this.checkSCOStatus();this._clearInterpageMessage();this.audio.pause();},stop:function pv_stop(){this.pause();this.audio.removeAttribute('src');this.audio.load();this.clean();if(typeof ModeManager!=='undefined'){ModeManager.playerTitle=null;if(ModeManager.currentMode===MODE_PLAYER){ModeManager.pop();}else{ModeManager.updateTitle();ModeManager.updatePlayerIcon();}}
this.playStatus=PLAYSTATUS_STOPPED;this.updateRemotePlayStatus();},next:function pv_next(isAutomatic){if(this.type===TYPE_SINGLE){this.start(false);}else if(this.queue.next(isAutomatic)){this.start();}else{this.stop();}},previous:function pv_previous(){if(this.audio.currentTime<=3){this.queue.previous();}
this.start();},startFastSeeking:function pv_startFastSeeking(direction){this.isTouching=this.isFastSeeking=true;var offset=direction*2;this.prevPlayStatus=this.playStatus;this.playStatus=direction?PLAYSTATUS_FWD_SEEK:PLAYSTATUS_REV_SEEK;this.updateRemotePlayStatus();this.intervalID=window.setInterval(function(){this.seekAudio(this.audio.currentTime+offset);}.bind(this),15);},stopFastSeeking:function pv_stopFastSeeking(){this.isTouching=this.isFastSeeking=false;if(this.intervalID){window.clearInterval(this.intervalID);}
this.playStatus=this.prevPlayStatus;this.prevPlayStatus=null;this.updateRemotePlayStatus();},updateSeekBar:function pv_updateSeekBar(){if(this.isTouching){return;}
if(typeof ModeManager==='undefined'||ModeManager.currentMode===MODE_PLAYER){this.seekAudio();}},seekAudio:function pv_seekAudio(seekTime){if(seekTime!==undefined){this.audio.currentTime=Math.floor(seekTime);}
this.setSeekBar(this.audio.duration,this.audio.currentTime);},setSeekBar:function pv_setSeekBar(endTime,currentTime){if(this.seekBar.max!=endTime){navigator.mozL10n.setAttributes(this.seekSlider,'playbackSeekBar',{'duration':formatTime(endTime)});}
this.seekBar.max=isFinite(endTime)?endTime:0;this.seekBar.value=currentTime;var formattedCurrentTime=formatTime(currentTime);this.seekSlider.setAttribute('aria-valuetext',formattedCurrentTime);this.seekSlider.setAttribute('aria-valuemax',this.seekBar.max);this.seekSlider.setAttribute('aria-valuenow',currentTime);var ratio=(isFinite(endTime)&&endTime!==0)?(currentTime/endTime):0;var x=(ratio*this.seekBar.offsetWidth-
this.seekIndicator.offsetWidth/2);if(this.isLTR){x=x+'px';}else{if(x<0){x=Math.abs(x)+'px';}else{x='-'+x+'px';}}
this.seekIndicator.style.transform='translateX('+x+')';this.seekElapsed.textContent=formattedCurrentTime;var remainingTime=endTime-currentTime;this.seekRemaining.textContent=(remainingTime>0)?'-'+formatTime(remainingTime):'---:--';},share:function pv_shareFile(){var songData=this.currentFileInfo;if(songData.metadata.locked){return;}
LazyLoader.load('js/metadata/album_art_cache.js').then(()=>{return Promise.all([Database.getFile(songData),AlbumArtCache.getThumbnailBlob(songData)]);}).then(function([file,pictureBlob]){var filename=songData.name,name=filename.substring(filename.lastIndexOf('/')+1);var activityData={type:'audio/*',number:1,blobs:[file],filenames:[name],filepaths:[filename],metadata:[{title:songData.metadata.title,artist:songData.metadata.artist,album:songData.metadata.album,picture:pictureBlob}]};if(PlayerView.playStatus!==PLAYSTATUS_PLAYING){var a=new MozActivity({name:'share',data:activityData});a.onerror=function(e){console.warn('share activity error:',a.error.name);};}
else{(function(){var hack_activity_property='_hack_hack_shut_up';var hack_setting_property='music._hack.pause_please';navigator.mozSettings.addObserver(hack_setting_property,observer);activityData[hack_activity_property]=hack_setting_property;var a=new MozActivity({name:'share',data:activityData});a.onerror=a.onsuccess=cleanup;function observer(e){PlayerView.pause();}
function cleanup(){navigator.mozSettings.removeObserver(hack_setting_property,observer);if(PlayerView.playStatus===PLAYSTATUS_PAUSED){PlayerView.play();}}}());}});},handleEvent:function pv_handleEvent(evt){var target=evt.target;if(!target){return;}
switch(evt.type){case'click':switch(target.id){case'player-cover':case'player-cover-image-1':case'player-cover-image-2':this.showInfo();break;case'player-controls-play':if(this.playControl.classList.contains('is-pause')){this.play();}else{this.pause();}
break;case'player-album-repeat':this.showInfo();var repeat=PlaybackQueue.Repeat.next(this.getRepeat());PlaybackQueue.repeat=repeat;this.setRepeat(repeat);break;case'player-album-shuffle':this.showInfo();var shuffle=!target.classList.contains('shuffle-on');PlaybackQueue.shuffle=shuffle;this.setShuffle(shuffle);break;case'player-cover-share':this.share();break;}
if(target.dataset.rating){this.showInfo();var songData=this.currentFileInfo;var targetRating=parseInt(target.dataset.rating,10);var newRating=(targetRating===songData.metadata.rated)?targetRating-1:targetRating;Database.setSongRating(songData,newRating);this.setRatings(newRating);}
break;case'play':this.playControl.classList.remove('is-pause');this.playStatus=PLAYSTATUS_PLAYING;this.playControl.setAttribute('data-l10n-id','playbackPause');this.updateRemotePlayStatus();break;case'pause':this.playControl.classList.add('is-pause');this.playStatus=PLAYSTATUS_PAUSED;this.playControl.setAttribute('data-l10n-id','playbackPlay');this.updateRemotePlayStatus();break;case'touchstart':case'touchmove':if(evt.type==='touchstart'){this.isTouching=true;this.seekIndicator.classList.add('highlight');}
if(this.isTouching&&this.audio.duration>0){var touch=evt.touches[0];var x=(touch.clientX-target.offsetLeft)/target.offsetWidth;if(x<0){x=0;}
if(x>1){x=1;}
if(this.isLTR){this.seekTime=x*this.seekBar.max;}else{this.seekTime=this.audio.duration-x*this.seekBar.max;}
this.setSeekBar(this.audio.duration,this.seekTime);}
break;case'touchend':if(this.isFastSeeking){this.stopFastSeeking();}else if(target.id==='player-seek-bar'){this.seekIndicator.classList.remove('highlight');if(this.audio.duration>0&&this.isTouching){this.seekAudio(this.seekTime);this.seekTime=0;}
this.isTouching=false;}else if(target.id==='player-controls-previous'){this.previous();}else if(target.id==='player-controls-next'){this.next();}
break;case'keypress':var step=Math.max(this.audio.duration/20,2);if(evt.keyCode==evt.DOM_VK_DOWN){this.seekAudio(this.audio.currentTime-step);}else if(evt.keyCode==evt.DOM_VK_UP){this.seekAudio(this.audio.currentTime+step);}
break;case'contextmenu':if(target.id==='player-controls-next'){this.startFastSeeking(1);}else if(target.id==='player-controls-previous'){this.startFastSeeking(-1);}
break;case'durationchange':case'timeupdate':this.updateSeekBar();if(evt.type==='durationchange'||this.audio.currentTime===0){this.updateRemoteMetadata();}
break;case'ended':this.next(true);break;case'visibilitychange':if(document.hidden){this.audio.removeEventListener('timeupdate',this);}else{this.audio.addEventListener('timeupdate',this);this.updateSeekBar();}
break;case'mozinterruptbegin':this.playStatus=INTERRUPT_BEGIN;this.updateRemotePlayStatus();break;case'mozinterruptend':this.playStatus=PLAYSTATUS_PLAYING;this.updateRemotePlayStatus();break;default:return;}},updateL10n:function pv_updateL10n(){this.isLTR=navigator.mozL10n.language.direction==='ltr'?true:false;}};

View file

@ -0,0 +1,235 @@
/* exported SearchView */
/* global App, createListElement, Database, ListView, ModeManager, MODE_LIST,
MODE_PICKER, MODE_PLAYER, MODE_SEARCH_FROM_TILES, MODE_SUBLIST,
MODE_TILES, PlaybackQueue, PlayerView, SubListView, TabBar,
TilesView */
'use strict';
var SearchView = {
context: {
ALL: 'ALL',
ARTISTS: 'ARTISTS',
ALBUMS: 'ALBUMS',
SONGS: 'SONGS',
},
searchContext: 'ALL',
get view() {
return document.getElementById('views-search');
},
get searchInput() {
return document.getElementById('views-search-input');
},
get searchArtistsView() {
return document.getElementById('views-search-artists');
},
get searchAlbumsView() {
return document.getElementById('views-search-albums');
},
get searchTitlesView() {
return document.getElementById('views-search-titles');
},
showNoResult: function sv_showNoResult(show) {
var view = document.getElementById('views-search-no-result');
view.classList.toggle('hidden', !show);
},
init: function sv_init() {
this.dataSource = [];
this.searchHandles = { artist: null, album: null, title: null };
this.view.addEventListener('click', this);
this.view.addEventListener('touchend', this);
this.searchInput.addEventListener('focus', this);
this.searchInput.addEventListener('input', this);
this.searchInput.addEventListener('keypress', this);
},
switchContext: function sv_switchContext() {
switch (TabBar.option) {
case 'mix':
case 'playlist':
this.searchContext = SearchView.context.ALL;
break;
case 'artist':
this.searchContext = SearchView.context.ARTISTS;
break;
case 'album':
this.searchContext = SearchView.context.ALBUMS;
break;
case 'title':
this.searchContext = SearchView.context.SONGS;
break;
}
},
search: function sv_search(query) {
this.clear();
if (!query) {
return;
}
var lists = { artist: this.searchArtistsView,
album: this.searchAlbumsView,
title: this.searchTitlesView };
var numResults = { artist: 0, album: 0, title: 0 };
function sv_showResult(option, result) {
/* jshint validthis:true */
if (result === null) {
this.searchHandles[option] = null;
var totalFound = numResults.artist + numResults.album +
numResults.title;
this.showNoResult(totalFound === 0);
return;
}
this.dataSource.push(result);
numResults[option]++;
lists[option].classList.remove('hidden');
lists[option].getElementsByClassName('search-result-count')[0]
.textContent = numResults[option];
lists[option].getElementsByClassName('search-results')[0].appendChild(
createListElement(option, result, this.dataSource.length - 1, query)
);
this.showNoResult(false);
}
// Only shows the search results of tracks when it's in picker mode
if (!App.pendingPick) {
if (this.searchContext === this.context.ALL ||
this.searchContext === this.context.ARTISTS) {
this.searchHandles.artist = Database.search(
'artist', query, sv_showResult.bind(this, 'artist')
);
}
if (this.searchContext === this.context.ALL ||
this.searchContext === this.context.ALBUMS) {
this.searchHandles.album = Database.search(
'album', query, sv_showResult.bind(this, 'album')
);
}
}
if (this.searchContext === this.context.ALL ||
this.searchContext === this.context.SONGS) {
this.searchHandles.title = Database.search(
'title', query, sv_showResult.bind(this, 'title')
);
}
},
clear: function sv_clear() {
for (var option in this.searchHandles) {
var handle = this.searchHandles[option];
if (handle) {
Database.cancelEnumeration(handle);
}
}
var views = [this.searchArtistsView, this.searchAlbumsView,
this.searchTitlesView];
views.forEach(function(view) {
view.getElementsByClassName('search-results')[0].innerHTML = '';
view.classList.add('hidden');
});
this.showNoResult(false);
this.dataSource = [];
},
hide: function sv_hide() {
this.searchInput.value = '';
this.clear();
if (ModeManager.currentMode === MODE_SEARCH_FROM_TILES) {
ModeManager.start(MODE_TILES, () => {
TilesView.hideSearch();
});
} else {
ModeManager.start(App.pendingPick ? MODE_PICKER : MODE_LIST, () => {
ListView.hideSearch();
});
}
},
openResult: function sv_openResult(target) {
var index = target.dataset.index;
var option = target.dataset.option;
var keyRange = target.dataset.keyRange;
var data = this.dataSource[index];
if (option === 'title') {
ModeManager.push(MODE_PLAYER, () => {
PlayerView.activate(new PlaybackQueue.StaticQueue([data]));
PlayerView.start();
});
} else {
// SubListView needs to prepare the songs data before entering it,
// So here we initialize the SubListView before push the view.
ModeManager.waitForView(MODE_SUBLIST, () => {
SubListView.activate(option, data, index, keyRange, 'next', () => {
ModeManager.push(MODE_SUBLIST);
});
});
}
},
handleEvent: function sv_handleEvent(evt) {
var target = evt.target;
switch (evt.type) {
case 'touchend':
if (target.id === 'views-search-clear') {
evt.preventDefault();
this.searchInput.value = '';
this.clear();
}
break;
case 'click':
if (!target) {
return;
}
if (target.id === 'views-search-close') {
evt.preventDefault();
this.hide();
}
if (target.dataset.index) {
this.openResult(target);
}
break;
case 'focus':
this.switchContext();
break;
case 'input':
if (target.id === 'views-search-input') {
this.search(target.value);
}
break;
case 'keypress':
if (target.id === 'views-search-input') {
if (evt.keyCode === evt.DOM_VK_RETURN) {
evt.preventDefault();
}
}
break;
default:
return;
}
}
};

View file

@ -0,0 +1,186 @@
/* exported SubListView */
/* global AlbumArtCache, createListElement, Database, LazyLoader, ModeManager,
MODE_PLAYER, PlaybackQueue, PlayerView, showImage, TabBar */
'use strict';
var SubListView = {
unknownNameL10nIds: {
'artist': 'unknownArtist',
'album': 'unknownAlbum',
'title': 'unknownTitle'
},
get view() {
return document.getElementById('views-sublist');
},
get dataSource() {
return this._dataSource;
},
get anchor() {
return document.getElementById('views-sublist-anchor');
},
get headerImage() {
return document.getElementById('views-sublist-header-image');
},
get headerName() {
return document.getElementById('views-sublist-header-name');
},
get playAllButton() {
return document.getElementById('views-sublist-controls-play');
},
get shuffleButton() {
return document.getElementById('views-sublist-controls-shuffle');
},
set dataSource(source) {
this._dataSource = source;
// At the same time we also check how many songs in an album
// Shuffle button is not necessary when an album only contains one song
this.shuffleButton.disabled = (this._dataSource.length < 2);
},
init: function slv_init() {
this.handle = null;
this.dataSource = [];
this.index = 0;
this.view.addEventListener('click', this);
},
clean: function slv_clean() {
// Cancel a pending enumeration before start a new one
if (this.handle) {
Database.cancelEnumeration(this.handle);
}
this.dataSource = [];
this.index = 0;
this.anchor.innerHTML = '';
this.view.scrollTop = 0;
},
setHeaderImage: function slv_setHeaderImage(fileinfo) {
// See if we are viewing the predefined playlists, if so, then replace the
// fileinfo with the first record in the dataSource to display the first
// album art for every predefined playlist.
if (TabBar.playlistArray.indexOf(fileinfo) !== -1) {
fileinfo = this.dataSource[0];
}
LazyLoader.load('js/metadata/album_art_cache.js').then(() => {
return AlbumArtCache.getThumbnailURL(fileinfo);
}).then((url) => {
showImage(this.albumImage, url);
});
},
setHeaderName: function slv_setHeaderName(name, l10nId) {
this.headerName.textContent = name;
this.headerName.dataset.l10nId = l10nId;
},
activate: function(option, data, index, keyRange, direction, callback) {
var targetOption = (option === 'date') ? option : 'metadata.' + option;
this.clean();
this.handle = Database.enumerateAll(targetOption, keyRange, direction,
(dataArray) => {
var headerName;
var headerNameL10nId = '';
var maxDiscNum = 1;
if (option === 'album') {
dataArray.sort(function(e1, e2) {
return (e1.metadata.discnum - e2.metadata.discnum) ||
(e1.metadata.tracknum - e2.metadata.tracknum);
});
maxDiscNum = Math.max(
dataArray[dataArray.length - 1].metadata.disccount,
dataArray[dataArray.length - 1].metadata.discnum
);
}
var inPlaylist = (option !== 'artist' &&
option !== 'album' &&
option !== 'title');
headerName = data.metadata[inPlaylist ? 'title' : option];
if (!headerName) {
headerNameL10nId = this.unknownNameL10nIds[option];
headerName = navigator.mozL10n.get(headerNameL10nId);
}
// Overrides l10nId.
if (data.metadata.l10nId) {
headerNameL10nId = data.metadata.l10nId;
}
this.dataSource = dataArray;
this.setHeaderName(headerName, headerNameL10nId);
this.setHeaderImage(data);
dataArray.forEach((songData) => {
songData.multidisc = (maxDiscNum > 1);
this.update(songData, inPlaylist);
});
if (callback) {
callback();
}
});
},
// Set inPlaylist to true if you want the index instead of the track #
// By default it is the track #
update: function slv_update(result, useIndexNumber) {
if (result === null) {
return;
}
var option = useIndexNumber ? 'song-index' : 'song';
this.anchor.appendChild(createListElement(option, result, this.index));
this.index++;
},
handleEvent: function slv_handleEvent(evt) {
var target = evt.target;
if (!target) {
return;
}
switch (evt.type) {
case 'click':
if (target === this.shuffleButton || target === this.playAllButton) {
ModeManager.push(MODE_PLAYER, () => {
PlayerView.clean();
PlaybackQueue.shuffle = (target === this.shuffleButton);
PlayerView.activate(new PlaybackQueue.StaticQueue(this.dataSource));
PlayerView.start();
});
} else if (target.dataset.index) {
ModeManager.push(MODE_PLAYER, () => {
PlayerView.clean();
var targetIndex = parseInt(target.dataset.index, 10);
PlayerView.activate(new PlaybackQueue.StaticQueue(
this.dataSource, targetIndex
));
PlayerView.start();
});
}
break;
default:
return;
}
}
};

View file

@ -0,0 +1,220 @@
/* exported TilesView */
/* global AlbumArtCache, Database, IDBKeyRange, LazyLoader, ModeManager,
MODE_PLAYER, MODE_SEARCH_FROM_TILES, PlaybackQueue, PlayerView,
SearchView, showImage */
'use strict';
var TilesView = {
get view() {
return document.getElementById('views-tiles');
},
get anchor() {
return document.getElementById('views-tiles-anchor');
},
get searchBox() {
return document.getElementById('views-tiles-search');
},
get searchInput() {
return document.getElementById('views-tiles-search-input');
},
get dataSource() {
return this._dataSource;
},
set dataSource(source) {
this._dataSource = source;
},
init: function tv_init() {
this.handle = null;
this.dataSource = [];
this.index = 0;
this.view.addEventListener('click', this);
this.searchInput.addEventListener('focus', this);
},
clean: function tv_clean() {
this.dataSource = [];
this.index = 0;
this.anchor.innerHTML = '';
},
hideSearch: function tv_hideSearch() {
this.searchInput.value = '';
// XXX: we probably want to animate this...
if (this.view.scrollTop < this.searchBox.offsetHeight) {
this.view.scrollTop = this.searchBox.offsetHeight;
}
},
activate: function tv_activate(callback) {
// Enumerate existing song entries in the database. List them all, and
// sort them in ascending order by album. Use enumerateAll() here so that
// we get all the results we want and then pass them synchronously to the
// _addItem() function. If we did it asynchronously, then we'd get one
// redraw for every song.
// Cancel a pending enumeration before starting a new one.
if (this.handle) {
Database.cancelEnumeration(this.handle);
}
this.handle = Database.enumerateAll('metadata.album', null, 'nextunique',
function(songs) {
TilesView.clean();
songs.forEach(function(song) {
TilesView._addItem(song);
});
// Display the TilesView once the UI has been populated.
document.getElementById('views-tiles').classList.remove('hidden');
if (callback) {
callback(songs);
}
});
},
_addItem: function tv_addItem(result) {
this.dataSource.push(result);
var tile = document.createElement('div');
tile.className = 'tile';
var container = document.createElement('div');
container.className = 'tile-container';
container.setAttribute('role', 'button');
var albumArt = document.createElement('img');
albumArt.className = 'tile-album-art';
container.appendChild(albumArt);
var titleBar = document.createElement('div');
titleBar.className = 'tile-title-bar';
var artistName = document.createElement('div');
artistName.className = 'tile-title-artist';
var artistNameText = document.createElement('bdi');
artistName.appendChild(artistNameText);
var albumName = document.createElement('div');
albumName.className = 'tile-title-album';
var albumNameText = document.createElement('bdi');
albumName.appendChild(albumNameText);
artistNameText.textContent =
result.metadata.artist || navigator.mozL10n.get('unknownArtist');
artistNameText.dataset.l10nId =
result.metadata.artist ? '' : 'unknownArtist';
albumNameText.textContent =
result.metadata.album || navigator.mozL10n.get('unknownAlbum');
albumNameText.dataset.l10nId = result.metadata.album ? '' : 'unknownAlbum';
titleBar.appendChild(artistName);
// There are 6 tiles in one group
// and the first tile is the main-tile
// so we mod 6 to find out who is the main-tile
if (this.index % 6 === 0) {
tile.classList.add('main-tile');
artistName.classList.add('main-tile-title');
titleBar.appendChild(albumName);
} else {
tile.classList.add('sub-tile');
artistName.classList.add('sub-tile-title');
}
var index = this.index;
LazyLoader.load('js/metadata/album_art_cache.js').then(() => {
var NUM_INITIALLY_VISIBLE_TILES = 8;
var INITIALLY_HIDDEN_TILE_WAIT_TIME_MS = 1000;
var setTileBackgroundClosure = function(url) {
showImage(albumArt, url);
};
if (index <= NUM_INITIALLY_VISIBLE_TILES) {
// Load this tile's background now, because it's visible.
AlbumArtCache.getThumbnailURL(result).then(setTileBackgroundClosure);
} else {
// Defer loading hidden tiles until the visible ones are done.
setTimeout(function() {
AlbumArtCache.getThumbnailURL(result).then(setTileBackgroundClosure);
}, INITIALLY_HIDDEN_TILE_WAIT_TIME_MS);
}
});
container.dataset.index = this.index;
// The tile info(album/artist) shows only when the cover does not exist
if (!result.metadata.picture) {
container.appendChild(titleBar);
} else {
container.setAttribute('aria-label', artistName.textContent + ' ' +
albumName.textContent);
}
tile.appendChild(container);
this.anchor.appendChild(tile);
this.index++;
},
handleEvent: function tv_handleEvent(evt) {
var target = evt.target;
if (!target) {
return;
}
switch (evt.type) {
case 'click':
if (target.id === 'views-tiles-search-close') {
if (ModeManager.currentMode === MODE_SEARCH_FROM_TILES) {
ModeManager.pop();
}
this.hideSearch();
evt.preventDefault();
} else if (target.dataset.index) {
tv_playAlbum(this.dataSource[target.dataset.index],
target.dataset.index);
}
break;
case 'focus':
if (target.id === 'views-tiles-search-input') {
if (ModeManager.currentMode !== MODE_SEARCH_FROM_TILES) {
ModeManager.start(MODE_SEARCH_FROM_TILES, function() {
// Let the search view gets the focus.
SearchView.searchInput.focus();
});
}
}
break;
default:
return;
}
function tv_playAlbum(data, index) {
var key = 'metadata.album';
var range = IDBKeyRange.only(data.metadata.album);
var direction = 'next';
ModeManager.push(MODE_PLAYER, function() {
PlayerView.clean();
// When an user tap an album on the tilesView
// we have to get all the song data first
// because the shuffle option might be ON
// and we have create shuffled list and play in shuffle order
Database.enumerateAll(key, range, direction, (dataArray) => {
PlayerView.activate(new PlaybackQueue.StaticQueue(dataArray));
PlayerView.start();
});
});
}
}
};

View file

@ -0,0 +1,26 @@
;;'use strict';function formatTime(secs){if(isNaN(secs)){return;}
secs=Math.floor(secs);var formatedTime;var seconds=secs%60;var minutes=Math.floor(secs/60)%60;var hours=Math.floor(secs/3600);if(hours===0){formatedTime=(minutes<10?'0'+minutes:minutes)+':'+
(seconds<10?'0'+seconds:seconds);}else{formatedTime=(hours<10?'0'+hours:hours)+':'+
(minutes<10?'0'+minutes:minutes)+':'+
(seconds<10?'0'+seconds:seconds);}
return formatedTime;}
function createListElement(option,data,index,highlight){var li=document.createElement('li');li.className='list-item';li.setAttribute('role','presentation');var a=document.createElement('a');a.dataset.index=index;a.dataset.option=option;a.setAttribute('role','option');var titleBdi;li.appendChild(a);function highlightText(result,text){var textContent=result.textContent;var textLowerCased=textContent.toLocaleLowerCase();var index=Normalizer.toAscii(textLowerCased).indexOf(text);if(index>=0){var innerHTML=Sanitizer.createSafeHTML`
${textContent.substring(0, index)}
<span class="search-highlight">
${textContent.substring(index, index + text.length)}
</span>
${textContent.substring(index + text.length)}`;result.innerHTML=Sanitizer.unwrapSafeHTML(innerHTML);}}
switch(option){case'playlist':titleBdi=document.createElement('bdi');titleBdi.className='list-playlist-title';if(data.metadata.l10nId){titleBdi.textContent=navigator.mozL10n.get(data.metadata.l10nId);titleBdi.dataset.l10nId=data.metadata.l10nId;}else{titleBdi.textContent=data.metadata.title||navigator.mozL10n.get('unknownTitle');titleBdi.dataset.l10nId=data.metadata.title?'':'unknownTitle';}
a.dataset.keyRange='all';a.dataset.option=data.option;a.appendChild(titleBdi);if(index===0){var shuffleIcon=document.createElement('div');shuffleIcon.className='list-playlist-icon';shuffleIcon.dataset.icon='shuffle';shuffleIcon.setAttribute('data-l10n-id','shuffle-toggle');a.appendChild(shuffleIcon);}
break;case'artist':case'album':case'title':var artistBdi;var albumImg;albumImg=document.createElement('img');albumImg.className='list-album-art';li.appendChild(albumImg);LazyLoader.load('js/metadata/album_art_cache.js').then(()=>{return AlbumArtCache.getThumbnailURL(data);}).then((url)=>{showImage(albumImg,url);});if(option==='artist'){artistBdi=document.createElement('bdi');artistBdi.className='list-single-title';artistBdi.textContent=data.metadata.artist||navigator.mozL10n.get('unknownArtist');artistBdi.dataset.l10nId=data.metadata.artist?'':'unknownArtist';if(highlight){highlightText(artistBdi,highlight);}
a.appendChild(artistBdi);}else{var albumOrTitleBdi=document.createElement('bdi');artistBdi=document.createElement('bdi');albumOrTitleBdi.className='list-main-title';artistBdi.className='list-sub-title';if(option==='album'){albumOrTitleBdi.textContent=data.metadata.album||navigator.mozL10n.get('unknownAlbum');albumOrTitleBdi.dataset.l10nId=data.metadata.album?'':'unknownAlbum';}else{albumOrTitleBdi.textContent=data.metadata.title||navigator.mozL10n.get('unknownTitle');albumOrTitleBdi.dataset.l10nId=data.metadata.title?'':'unknownTitle';}
artistBdi.textContent=data.metadata.artist||navigator.mozL10n.get('unknownArtist');artistBdi.dataset.l10nId=data.metadata.artist?'':'unknownArtist';if(highlight){highlightText(albumOrTitleBdi,highlight);}
a.appendChild(albumOrTitleBdi);a.appendChild(artistBdi);}
a.dataset.keyRange=data.metadata[option];a.dataset.option=option;break;case'song':case'song-index':var songTitle=data.metadata.title||navigator.mozL10n.get('unknownTitle');var indexBdi=document.createElement('bdi');indexBdi.className='list-song-index';if(option==='song-index'){indexBdi.textContent=index+1;}else{var trackNum=data.metadata.tracknum;if(data.metadata.discnum&&data.multidisc){trackNum=data.metadata.discnum+'.'+
(trackNum<10?'0'+trackNum:trackNum);}
indexBdi.textContent=trackNum;}
titleBdi=document.createElement('bdi');titleBdi.className='list-song-title';titleBdi.textContent=songTitle;titleBdi.dataset.l10nId=data.metadata.title?'':'unknownTitle';var lengthBdi=document.createElement('bdi');lengthBdi.className='list-song-length';a.appendChild(indexBdi);a.appendChild(titleBdi);a.appendChild(lengthBdi);break;}
return li;}
function showImage(image,url,option){image.classList.remove(option);image.src='';if(option==='fadeIn'){image.style.opacity=0;}
image.addEventListener('load',handler);function handler(evt){evt.target.removeEventListener('load',handler);image.classList.add(option);}
image.src=url;}

View file

@ -0,0 +1,18 @@
{
"name": "music",
"tags": {
"dictionaries": ["jsdoc"]
},
"source": {
"include": ["apps/music/js"]
},
"plugins": [
"plugins/markdown",
"plugins/summarize"
],
"opts": {
"private": true,
"recurse": true,
"destination": "docs/music"
}
}

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," صورة، {timestamp}}"]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["صورة ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," فيديو، ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["ڤديو ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"طوليّة"},{"$i":"orientationLandscape","$v":"عرضيّة"},{"$i":"playbackPlay","ariaLabel":"شغّل"},{"$i":"playbackPause","ariaLabel":"ألبث"},{"$i":"playbackNext","ariaLabel":"التالي"},{"$i":"playbackPrevious","ariaLabel":"السابق"},{"$i":"playbackFullscreen","ariaLabel":"ملء الشاشة"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["شريط البحث، والمدة ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," изображение"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," видео"]}},{"$i":"orientationPortrait","$v":"портретно"},{"$i":"orientationLandscape","$v":"пейзажно"},{"$i":"playbackPlay","ariaLabel":"Пускане"},{"$i":"playbackPause","ariaLabel":"Пауза"},{"$i":"playbackNext","ariaLabel":"Следващ"},{"$i":"playbackPrevious","ariaLabel":"Предишен"},{"$i":"playbackFullscreen","ariaLabel":"На цял екран"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Лента за превъртане, времетраене ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," ছবি, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," ছবি"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," ভিডিও, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," ভিডিও"]}},{"$i":"orientationPortrait","$v":"লম্বালম্বি"},{"$i":"orientationLandscape","$v":"আড়াআড়ি"},{"$i":"playbackPlay","ariaLabel":"চলবে"},{"$i":"playbackPause","ariaLabel":"বিরতি"},{"$i":"playbackNext","ariaLabel":"পরবর্তী"},{"$i":"playbackPrevious","ariaLabel":"পূর্ববর্তী"},{"$i":"playbackFullscreen","ariaLabel":"পর্দাজুড়ে"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["সীক বার, সময়কাল ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Imatge ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Imatge ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Vídeo ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Vídeo ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"vertical"},{"$i":"orientationLandscape","$v":"horitzontal"},{"$i":"playbackPlay","ariaLabel":"Reprodueix"},{"$i":"playbackPause","ariaLabel":"Pausa"},{"$i":"playbackNext","ariaLabel":"Següent"},{"$i":"playbackPrevious","ariaLabel":"Anterior"},{"$i":"playbackFullscreen","ariaLabel":"Pantalla completa"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Barra de cerca, duració ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Orientace: ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Orientace: ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Orientace: ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Orientace: ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"portrét"},{"$i":"orientationLandscape","$v":"krajina"},{"$i":"playbackPlay","ariaLabel":"Přehrát"},{"$i":"playbackPause","ariaLabel":"Pozastavit"},{"$i":"playbackNext","ariaLabel":"Další"},{"$i":"playbackPrevious","ariaLabel":"Předchozí"},{"$i":"playbackFullscreen","ariaLabel":"Celá obrazovka"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Posuvník, délka ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," billede, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," billede"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portræt"},{"$i":"orientationLandscape","$v":"landskab"},{"$i":"playbackPlay","ariaLabel":"Afspil"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Næste"},{"$i":"playbackPrevious","ariaLabel":"Forrige"},{"$i":"playbackFullscreen","ariaLabel":"Fuldskærm"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Søgelinje, varighed ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"},"-Grafik, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Grafik in ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"},"-Video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Video in ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"Hochformat"},{"$i":"orientationLandscape","$v":"Querformat"},{"$i":"playbackPlay","ariaLabel":"Abspielen"},{"$i":"playbackPause","ariaLabel":"Anhalten"},{"$i":"playbackNext","ariaLabel":"Nächstes"},{"$i":"playbackPrevious","ariaLabel":"Vorheriges"},{"$i":"playbackFullscreen","ariaLabel":"Vollbild"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Wiedergabeleiste, Dauer ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"κατακόρυφος προσανατολισμός"},{"$i":"orientationLandscape","$v":"oριζόντιος προσαντατολισμός"},{"$i":"playbackPlay","ariaLabel":"Αναπαραγωγή"},{"$i":"playbackPause","ariaLabel":"Παύση"},{"$i":"playbackNext","ariaLabel":"Επόμενο"},{"$i":"playbackPrevious","ariaLabel":"Προηγούμενο"},{"$i":"playbackFullscreen","ariaLabel":"Πλήρης οθόνη"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, διάρκεια ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Imagen ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["imagen ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Vídeo ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Vídeo ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"vertical"},{"$i":"orientationLandscape","$v":"horizontal"},{"$i":"playbackPlay","ariaLabel":"Reproducir"},{"$i":"playbackPause","ariaLabel":"Pausar"},{"$i":"playbackNext","ariaLabel":"Siguiente"},{"$i":"playbackPrevious","ariaLabel":"Anterior"},{"$i":"playbackFullscreen","ariaLabel":"Pantalla completa"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Barra de búsqueda, duración ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Irudi ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["irudi ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Bideo ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["bideo ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"bertikala"},{"$i":"orientationLandscape","$v":"horizontala"},{"$i":"playbackPlay","ariaLabel":"Erreproduzitu"},{"$i":"playbackPause","ariaLabel":"Pausatu"},{"$i":"playbackNext","ariaLabel":"Hurrengoa"},{"$i":"playbackPrevious","ariaLabel":"Aurrekoa"},{"$i":"playbackFullscreen","ariaLabel":"Pantaila osoa"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Bilaketa-barra, iraupena ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Image en mode ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Image en mode ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Vidéo en mode ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Vidéo en mode ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"paysage"},{"$i":"playbackPlay","ariaLabel":"Lecture"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Suivante"},{"$i":"playbackPrevious","ariaLabel":"Précédente"},{"$i":"playbackFullscreen","ariaLabel":"Plein écran"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Barre de recherche, durée ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"vertical"},{"$i":"orientationLandscape","$v":"horizontal"},{"$i":"playbackPlay","ariaLabel":"Reproducir"},{"$i":"playbackPause","ariaLabel":"Pausa"},{"$i":"playbackNext","ariaLabel":"Seguinte"},{"$i":"playbackPrevious","ariaLabel":"Anterior"},{"$i":"playbackFullscreen","ariaLabel":"Pantalla completa"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Barra de buscar, duración ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," kép, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," kép"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," videó, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," videó"]}},{"$i":"orientationPortrait","$v":"álló"},{"$i":"orientationLandscape","$v":"fekvő"},{"$i":"playbackPlay","ariaLabel":"Lejátszás"},{"$i":"playbackPause","ariaLabel":"Szünet"},{"$i":"playbackNext","ariaLabel":"Tovább"},{"$i":"playbackPrevious","ariaLabel":"Előző"},{"$i":"playbackFullscreen","ariaLabel":"Teljes képernyő"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Keresősáv, hossz: ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Immagine ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Immagine ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Video ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Video ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"ritratto"},{"$i":"orientationLandscape","$v":"paesaggio"},{"$i":"playbackPlay","ariaLabel":"Avvia riproduzione"},{"$i":"playbackPause","ariaLabel":"Metti in pausa"},{"$i":"playbackNext","ariaLabel":"Successivo"},{"$i":"playbackPrevious","ariaLabel":"Precedente"},{"$i":"playbackFullscreen","ariaLabel":"Schermo intero"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Barra di ricerca, durata ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"},"の画像、",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"},"の画像"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"},"の動画、",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"},"の動画"]}},{"$i":"orientationPortrait","$v":"縦長"},{"$i":"orientationLandscape","$v":"横長"},{"$i":"playbackPlay","ariaLabel":"再生"},{"$i":"playbackPause","ariaLabel":"一時停止"},{"$i":"playbackNext","ariaLabel":"次へ"},{"$i":"playbackPrevious","ariaLabel":"前へ"},{"$i":"playbackFullscreen","ariaLabel":"全画面表示"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["シークバー、再生位置 ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 사진, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 사진"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 동영상, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 동영상"]}},{"$i":"orientationPortrait","$v":"세로"},{"$i":"orientationLandscape","$v":"가로"},{"$i":"playbackPlay","ariaLabel":"재생"},{"$i":"playbackPause","ariaLabel":"멈춤"},{"$i":"playbackNext","ariaLabel":"다음"},{"$i":"playbackPrevious","ariaLabel":"이전"},{"$i":"playbackFullscreen","ariaLabel":"전체화면"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["탐색바, 재생시각 ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," afbeelding, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," afbeelding"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"staande"},{"$i":"orientationLandscape","$v":"liggende"},{"$i":"playbackPlay","ariaLabel":"Afspelen"},{"$i":"playbackPause","ariaLabel":"Pauzeren"},{"$i":"playbackNext","ariaLabel":"Volgende"},{"$i":"playbackPrevious","ariaLabel":"Vorige"},{"$i":"playbackFullscreen","ariaLabel":"Volledig scherm"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Zoekbalk, duur ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"pionowa"},{"$i":"orientationLandscape","$v":"pozioma"},{"$i":"playbackPlay","ariaLabel":"Odtwarzaj"},{"$i":"playbackPause","ariaLabel":"Wstrzymaj"},{"$i":"playbackNext","ariaLabel":"Następny utwór"},{"$i":"playbackPrevious","ariaLabel":"Poprzedni utwór"},{"$i":"playbackFullscreen","ariaLabel":"Pełny ekran"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Pasek postępu, czas ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Imagem em ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Imagem em ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Video em ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Video em ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"retrato"},{"$i":"orientationLandscape","$v":"paisagem"},{"$i":"playbackPlay","ariaLabel":"Reproduzir"},{"$i":"playbackPause","ariaLabel":"Pausar"},{"$i":"playbackNext","ariaLabel":"Próximo"},{"$i":"playbackPrevious","ariaLabel":"Anterior"},{"$i":"playbackFullscreen","ariaLabel":"Tela inteira"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Barra de busca, duração ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["imagine ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["videoclip ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"portret"},{"$i":"orientationLandscape","$v":"pe orizontală"},{"$i":"playbackPlay","ariaLabel":"Redă"},{"$i":"playbackPause","ariaLabel":"Pauză"},{"$i":"playbackNext","ariaLabel":"Următoarea"},{"$i":"playbackPrevious","ariaLabel":"Precedenta"},{"$i":"playbackFullscreen","ariaLabel":"Ecran complet"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Bară de căutare, durată ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," изображение, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," изображение"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," видео, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," видео"]}},{"$i":"orientationPortrait","$v":"книжное"},{"$i":"orientationLandscape","$v":"альбомное"},{"$i":"playbackPlay","ariaLabel":"Воспроизвести"},{"$i":"playbackPause","ariaLabel":"Приостановить"},{"$i":"playbackNext","ariaLabel":"Следующее"},{"$i":"playbackPrevious","ariaLabel":"Предыдущее"},{"$i":"playbackFullscreen","ariaLabel":"Полный экран"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Панель поиска, длительность ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Orientácia: ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Orientácia: ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Orientácia: ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Orientácia: ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"portrét"},{"$i":"orientationLandscape","$v":"krajina"},{"$i":"playbackPlay","ariaLabel":"Prehrať"},{"$i":"playbackPause","ariaLabel":"Pozastaviť"},{"$i":"playbackNext","ariaLabel":"Ďalšia"},{"$i":"playbackPrevious","ariaLabel":"Predchádzajúca"},{"$i":"playbackFullscreen","ariaLabel":"Na celú obrazovku"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Posuvník, dĺžka ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Figurë ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Figurë ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Video ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Video ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"portret"},{"$i":"orientationLandscape","$v":"së gjeri"},{"$i":"playbackPlay","ariaLabel":"Luaje"},{"$i":"playbackPause","ariaLabel":"Pushim"},{"$i":"playbackNext","ariaLabel":"Pasuesja"},{"$i":"playbackPrevious","ariaLabel":"E mëparshmja"},{"$i":"playbackFullscreen","ariaLabel":"Sa krejt ekrani"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Shtylla e rrjedhës, kohëzgjatje ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," слика, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," слика"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," видео, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," видео"]}},{"$i":"orientationPortrait","$v":"портрет "},{"$i":"orientationLandscape","$v":"пејзаж"},{"$i":"playbackPlay","ariaLabel":"Пусти"},{"$i":"playbackPause","ariaLabel":"Пауза"},{"$i":"playbackNext","ariaLabel":"Следећи"},{"$i":"playbackPrevious","ariaLabel":"Претходни"},{"$i":"playbackFullscreen","ariaLabel":"Режим целог екрана"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Трака за кретање, трајање ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," slika, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," slika"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portret "},{"$i":"orientationLandscape","$v":"pejzaž"},{"$i":"playbackPlay","ariaLabel":"Pusti"},{"$i":"playbackPause","ariaLabel":"Pauza"},{"$i":"playbackNext","ariaLabel":"Sledeći"},{"$i":"playbackPrevious","ariaLabel":"Prethodni"},{"$i":"playbackFullscreen","ariaLabel":"Režim celog ekrana"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Traka za kretanje, trajanje ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," bild, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," bild"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"porträtt"},{"$i":"orientationLandscape","$v":"landskap"},{"$i":"playbackPlay","ariaLabel":"Spela"},{"$i":"playbackPause","ariaLabel":"Pausa"},{"$i":"playbackNext","ariaLabel":"Nästa"},{"$i":"playbackPrevious","ariaLabel":"Tidigare"},{"$i":"playbackFullscreen","ariaLabel":"Helskärm"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Sökfält, längd ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," resim"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"dikey"},{"$i":"orientationLandscape","$v":"yatay"},{"$i":"playbackPlay","ariaLabel":"Oynat"},{"$i":"playbackPause","ariaLabel":"Duraklat"},{"$i":"playbackNext","ariaLabel":"İleri"},{"$i":"playbackPrevious","ariaLabel":"Geri"},{"$i":"playbackFullscreen","ariaLabel":"Tam ekran"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Sarma çubuğu, süre ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 图片, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 图像"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 视频, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 视频"]}},{"$i":"orientationPortrait","$v":"纵向"},{"$i":"orientationLandscape","$v":"横向"},{"$i":"playbackPlay","ariaLabel":"播放"},{"$i":"playbackPause","ariaLabel":"暂停"},{"$i":"playbackNext","ariaLabel":"下一个"},{"$i":"playbackPrevious","ariaLabel":"上一个"},{"$i":"playbackFullscreen","ariaLabel":"全屏"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["进度条,持续时间 ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 圖片,",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 圖片"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 影片,",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 視訊"]}},{"$i":"orientationPortrait","$v":"垂直"},{"$i":"orientationLandscape","$v":"水平"},{"$i":"playbackPlay","ariaLabel":"播放"},{"$i":"playbackPause","ariaLabel":"暫停"},{"$i":"playbackNext","ariaLabel":"下一首"},{"$i":"playbackPrevious","ariaLabel":"上一首"},{"$i":"playbackFullscreen","ariaLabel":"全螢幕"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["搜尋列,時間 ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," صورة، {timestamp}}"]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["صورة ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," فيديو، ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["ڤديو ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"طوليّة"},{"$i":"orientationLandscape","$v":"عرضيّة"},{"$i":"playbackPlay","ariaLabel":"شغّل"},{"$i":"playbackPause","ariaLabel":"ألبث"},{"$i":"playbackNext","ariaLabel":"التالي"},{"$i":"playbackPrevious","ariaLabel":"السابق"},{"$i":"playbackFullscreen","ariaLabel":"ملء الشاشة"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["شريط البحث، والمدة ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," изображение"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," видео"]}},{"$i":"orientationPortrait","$v":"портретно"},{"$i":"orientationLandscape","$v":"пейзажно"},{"$i":"playbackPlay","ariaLabel":"Пускане"},{"$i":"playbackPause","ariaLabel":"Пауза"},{"$i":"playbackNext","ariaLabel":"Следващ"},{"$i":"playbackPrevious","ariaLabel":"Предишен"},{"$i":"playbackFullscreen","ariaLabel":"На цял екран"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Лента за превъртане, времетраене ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," ছবি, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," ছবি"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," ভিডিও, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," ভিডিও"]}},{"$i":"orientationPortrait","$v":"লম্বালম্বি"},{"$i":"orientationLandscape","$v":"আড়াআড়ি"},{"$i":"playbackPlay","ariaLabel":"চলবে"},{"$i":"playbackPause","ariaLabel":"বিরতি"},{"$i":"playbackNext","ariaLabel":"পরবর্তী"},{"$i":"playbackPrevious","ariaLabel":"পূর্ববর্তী"},{"$i":"playbackFullscreen","ariaLabel":"পর্দাজুড়ে"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["সীক বার, সময়কাল ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Imatge ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Imatge ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Vídeo ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Vídeo ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"vertical"},{"$i":"orientationLandscape","$v":"horitzontal"},{"$i":"playbackPlay","ariaLabel":"Reprodueix"},{"$i":"playbackPause","ariaLabel":"Pausa"},{"$i":"playbackNext","ariaLabel":"Següent"},{"$i":"playbackPrevious","ariaLabel":"Anterior"},{"$i":"playbackFullscreen","ariaLabel":"Pantalla completa"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Barra de cerca, duració ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Orientace: ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Orientace: ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Orientace: ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Orientace: ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"portrét"},{"$i":"orientationLandscape","$v":"krajina"},{"$i":"playbackPlay","ariaLabel":"Přehrát"},{"$i":"playbackPause","ariaLabel":"Pozastavit"},{"$i":"playbackNext","ariaLabel":"Další"},{"$i":"playbackPrevious","ariaLabel":"Předchozí"},{"$i":"playbackFullscreen","ariaLabel":"Celá obrazovka"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Posuvník, délka ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," billede, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," billede"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portræt"},{"$i":"orientationLandscape","$v":"landskab"},{"$i":"playbackPlay","ariaLabel":"Afspil"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Næste"},{"$i":"playbackPrevious","ariaLabel":"Forrige"},{"$i":"playbackFullscreen","ariaLabel":"Fuldskærm"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Søgelinje, varighed ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"},"-Grafik, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Grafik in ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"},"-Video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Video in ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"Hochformat"},{"$i":"orientationLandscape","$v":"Querformat"},{"$i":"playbackPlay","ariaLabel":"Abspielen"},{"$i":"playbackPause","ariaLabel":"Anhalten"},{"$i":"playbackNext","ariaLabel":"Nächstes"},{"$i":"playbackPrevious","ariaLabel":"Vorheriges"},{"$i":"playbackFullscreen","ariaLabel":"Vollbild"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Wiedergabeleiste, Dauer ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"κατακόρυφος προσανατολισμός"},{"$i":"orientationLandscape","$v":"oριζόντιος προσαντατολισμός"},{"$i":"playbackPlay","ariaLabel":"Αναπαραγωγή"},{"$i":"playbackPause","ariaLabel":"Παύση"},{"$i":"playbackNext","ariaLabel":"Επόμενο"},{"$i":"playbackPrevious","ariaLabel":"Προηγούμενο"},{"$i":"playbackFullscreen","ariaLabel":"Πλήρης οθόνη"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, διάρκεια ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Imagen ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["imagen ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Vídeo ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Vídeo ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"vertical"},{"$i":"orientationLandscape","$v":"horizontal"},{"$i":"playbackPlay","ariaLabel":"Reproducir"},{"$i":"playbackPause","ariaLabel":"Pausar"},{"$i":"playbackNext","ariaLabel":"Siguiente"},{"$i":"playbackPrevious","ariaLabel":"Anterior"},{"$i":"playbackFullscreen","ariaLabel":"Pantalla completa"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Barra de búsqueda, duración ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Irudi ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["irudi ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Bideo ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["bideo ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"bertikala"},{"$i":"orientationLandscape","$v":"horizontala"},{"$i":"playbackPlay","ariaLabel":"Erreproduzitu"},{"$i":"playbackPause","ariaLabel":"Pausatu"},{"$i":"playbackNext","ariaLabel":"Hurrengoa"},{"$i":"playbackPrevious","ariaLabel":"Aurrekoa"},{"$i":"playbackFullscreen","ariaLabel":"Pantaila osoa"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Bilaketa-barra, iraupena ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Image en mode ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Image en mode ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Vidéo en mode ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Vidéo en mode ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"paysage"},{"$i":"playbackPlay","ariaLabel":"Lecture"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Suivante"},{"$i":"playbackPrevious","ariaLabel":"Précédente"},{"$i":"playbackFullscreen","ariaLabel":"Plein écran"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Barre de recherche, durée ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"vertical"},{"$i":"orientationLandscape","$v":"horizontal"},{"$i":"playbackPlay","ariaLabel":"Reproducir"},{"$i":"playbackPause","ariaLabel":"Pausa"},{"$i":"playbackNext","ariaLabel":"Seguinte"},{"$i":"playbackPrevious","ariaLabel":"Anterior"},{"$i":"playbackFullscreen","ariaLabel":"Pantalla completa"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Barra de buscar, duración ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," kép, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," kép"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," videó, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," videó"]}},{"$i":"orientationPortrait","$v":"álló"},{"$i":"orientationLandscape","$v":"fekvő"},{"$i":"playbackPlay","ariaLabel":"Lejátszás"},{"$i":"playbackPause","ariaLabel":"Szünet"},{"$i":"playbackNext","ariaLabel":"Tovább"},{"$i":"playbackPrevious","ariaLabel":"Előző"},{"$i":"playbackFullscreen","ariaLabel":"Teljes képernyő"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Keresősáv, hossz: ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Immagine ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Immagine ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Video ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Video ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"ritratto"},{"$i":"orientationLandscape","$v":"paesaggio"},{"$i":"playbackPlay","ariaLabel":"Avvia riproduzione"},{"$i":"playbackPause","ariaLabel":"Metti in pausa"},{"$i":"playbackNext","ariaLabel":"Successivo"},{"$i":"playbackPrevious","ariaLabel":"Precedente"},{"$i":"playbackFullscreen","ariaLabel":"Schermo intero"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Barra di ricerca, durata ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"},"の画像、",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"},"の画像"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"},"の動画、",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"},"の動画"]}},{"$i":"orientationPortrait","$v":"縦長"},{"$i":"orientationLandscape","$v":"横長"},{"$i":"playbackPlay","ariaLabel":"再生"},{"$i":"playbackPause","ariaLabel":"一時停止"},{"$i":"playbackNext","ariaLabel":"次へ"},{"$i":"playbackPrevious","ariaLabel":"前へ"},{"$i":"playbackFullscreen","ariaLabel":"全画面表示"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["シークバー、再生位置 ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 사진, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 사진"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 동영상, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," 동영상"]}},{"$i":"orientationPortrait","$v":"세로"},{"$i":"orientationLandscape","$v":"가로"},{"$i":"playbackPlay","ariaLabel":"재생"},{"$i":"playbackPause","ariaLabel":"멈춤"},{"$i":"playbackNext","ariaLabel":"다음"},{"$i":"playbackPrevious","ariaLabel":"이전"},{"$i":"playbackFullscreen","ariaLabel":"전체화면"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["탐색바, 재생시각 ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," afbeelding, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," afbeelding"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"staande"},{"$i":"orientationLandscape","$v":"liggende"},{"$i":"playbackPlay","ariaLabel":"Afspelen"},{"$i":"playbackPause","ariaLabel":"Pauzeren"},{"$i":"playbackNext","ariaLabel":"Volgende"},{"$i":"playbackPrevious","ariaLabel":"Vorige"},{"$i":"playbackFullscreen","ariaLabel":"Volledig scherm"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Zoekbalk, duur ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"portrait"},{"$i":"orientationLandscape","$v":"landscape"},{"$i":"playbackPlay","ariaLabel":"Play"},{"$i":"playbackPause","ariaLabel":"Pause"},{"$i":"playbackNext","ariaLabel":"Next"},{"$i":"playbackPrevious","ariaLabel":"Previous"},{"$i":"playbackFullscreen","ariaLabel":"Fullscreen"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Seek bar, duration ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video"]}},{"$i":"orientationPortrait","$v":"pionowa"},{"$i":"orientationLandscape","$v":"pozioma"},{"$i":"playbackPlay","ariaLabel":"Odtwarzaj"},{"$i":"playbackPause","ariaLabel":"Wstrzymaj"},{"$i":"playbackNext","ariaLabel":"Następny utwór"},{"$i":"playbackPrevious","ariaLabel":"Poprzedni utwór"},{"$i":"playbackFullscreen","ariaLabel":"Pełny ekran"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Pasek postępu, czas ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Imagem em ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Imagem em ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Video em ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Video em ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"retrato"},{"$i":"orientationLandscape","$v":"paisagem"},{"$i":"playbackPlay","ariaLabel":"Reproduzir"},{"$i":"playbackPause","ariaLabel":"Pausar"},{"$i":"playbackNext","ariaLabel":"Próximo"},{"$i":"playbackPrevious","ariaLabel":"Anterior"},{"$i":"playbackFullscreen","ariaLabel":"Tela inteira"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Barra de busca, duração ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," image, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["imagine ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," video, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["videoclip ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"portret"},{"$i":"orientationLandscape","$v":"pe orizontală"},{"$i":"playbackPlay","ariaLabel":"Redă"},{"$i":"playbackPause","ariaLabel":"Pauză"},{"$i":"playbackNext","ariaLabel":"Următoarea"},{"$i":"playbackPrevious","ariaLabel":"Precedenta"},{"$i":"playbackFullscreen","ariaLabel":"Ecran complet"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Bară de căutare, durată ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," изображение, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," изображение"]}},{"$i":"videoDescription","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," видео, ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":[{"t":"idOrVar","v":"orientation"}," видео"]}},{"$i":"orientationPortrait","$v":"книжное"},{"$i":"orientationLandscape","$v":"альбомное"},{"$i":"playbackPlay","ariaLabel":"Воспроизвести"},{"$i":"playbackPause","ariaLabel":"Приостановить"},{"$i":"playbackNext","ariaLabel":"Следующее"},{"$i":"playbackPrevious","ariaLabel":"Предыдущее"},{"$i":"playbackFullscreen","ariaLabel":"Полный экран"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Панель поиска, длительность ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Orientácia: ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Orientácia: ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Orientácia: ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Orientácia: ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"portrét"},{"$i":"orientationLandscape","$v":"krajina"},{"$i":"playbackPlay","ariaLabel":"Prehrať"},{"$i":"playbackPause","ariaLabel":"Pozastaviť"},{"$i":"playbackNext","ariaLabel":"Ďalšia"},{"$i":"playbackPrevious","ariaLabel":"Predchádzajúca"},{"$i":"playbackFullscreen","ariaLabel":"Na celú obrazovku"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Posuvník, dĺžka ",{"t":"idOrVar","v":"duration"}]}}]

View file

@ -0,0 +1 @@
[{"$i":"music","$v":"Music"},{"$i":"mix","$v":"Mix"},{"$i":"playlists","$v":"Playlist"},{"$i":"artists","$v":"Artists"},{"$i":"albums","$v":"Albums"},{"$i":"songs","$v":"Songs"},{"$i":"more","$v":"More"},{"$i":"songArtist","$v":"Song artist"},{"$i":"songAlbum","$v":"Song album"},{"$i":"unknownArtist","$v":"Unknown artist"},{"$i":"unknownAlbum","$v":"Unknown album"},{"$i":"unknownTitle","$v":"Unknown title"},{"$i":"empty-title","$v":"Add songs to get started"},{"$i":"empty-text","$v":"Load songs on to the memory card."},{"$i":"nocard2-title","$v":"No memory card found"},{"$i":"nocard3-text","$v":"Insert a memory card to listen to songs."},{"$i":"pluggedin-title","$v":"Music can not be used while phone is plugged in"},{"$i":"pluggedin-text","$v":"Unplug the phone to play music."},{"$i":"upgrade-title","$v":"Database Upgrade"},{"$i":"upgrade-text","$v":"Please wait while Music updates its database."},{"$i":"search-music","placeholder":"Search Music"},{"$i":"search-cancel","$v":"Cancel"},{"$i":"search-artists","$v":"Artists"},{"$i":"search-albums","$v":"Albums"},{"$i":"search-titles","$v":"Tracks"},{"$i":"search-close","$v":"close"},{"$i":"search-no-result","$v":"No music found"},{"$i":"playlists-shuffle-all","$v":"Shuffle all"},{"$i":"playlists-highest-rated","$v":"Highest rated"},{"$i":"playlists-recently-added","$v":"Recently added"},{"$i":"playlists-most-played","$v":"Most played"},{"$i":"playlists-least-played","$v":"Least played"},{"$i":"picker-title","$v":"Select a track"},{"$i":"save","$v":"Save"},{"$i":"saved","$v":["Saved ",{"t":"idOrVar","v":"title"}," to Music"]},{"$i":"audioinvalid","$v":"Audio cannot be played: format is unsupported or file is invalid."},{"$i":"overlay-cancel-button","$v":"Cancel"},{"$i":"music-paused-notification","$v":"Music paused during the call"},{"$i":"done","$v":"Done"},{"$i":"share-song","ariaLabel":"Share"},{"$i":"player-album-rating","ariaLabel":"Rating"},{"$i":"rating-star","ariaLabel":{"$v":{"zero":[{"t":"idOrVar","v":"n"}," stars"],"one":[{"t":"idOrVar","v":"n"}," star"],"two":[{"t":"idOrVar","v":"n"}," stars"],"few":[{"t":"idOrVar","v":"n"}," stars"],"many":[{"t":"idOrVar","v":"n"}," stars"],"other":[{"t":"idOrVar","v":"n"}," stars"]},"$x":[{"t":"idOrVar","v":"plural"},"n"]}},{"$i":"go-to-player-view","ariaLabel":"Go to player view"},{"$i":"repeat-off","ariaLabel":"Repeat off"},{"$i":"repeat-list","ariaLabel":"Repeat all"},{"$i":"repeat-song","ariaLabel":"Repeat track"},{"$i":"shuffle-toggle","ariaLabel":"Shuffle"},{"$i":"mix-tab","ariaLabel":"Mix"},{"$i":"playlists-tab","ariaLabel":"Playlists"},{"$i":"artists-tab","ariaLabel":"Artists"},{"$i":"albums-tab","ariaLabel":"Albums"},{"$i":"songs-tab","ariaLabel":"Songs"},{"$i":"imageDescription","ariaLabel":{"$v":["Figurë ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"imageDescriptionNoTimestamp","ariaLabel":{"$v":["Figurë ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"videoDescription","ariaLabel":{"$v":["Video ",{"t":"idOrVar","v":"orientation"},", ",{"t":"idOrVar","v":"timestamp"}]}},{"$i":"videoDescriptionNoTimestamp","ariaLabel":{"$v":["Video ",{"t":"idOrVar","v":"orientation"}]}},{"$i":"orientationPortrait","$v":"portret"},{"$i":"orientationLandscape","$v":"së gjeri"},{"$i":"playbackPlay","ariaLabel":"Luaje"},{"$i":"playbackPause","ariaLabel":"Pushim"},{"$i":"playbackNext","ariaLabel":"Pasuesja"},{"$i":"playbackPrevious","ariaLabel":"E mëparshmja"},{"$i":"playbackFullscreen","ariaLabel":"Sa krejt ekrani"},{"$i":"playbackSeekBar","ariaLabel":{"$v":["Shtylla e rrjedhës, kohëzgjatje ",{"t":"idOrVar","v":"duration"}]}}]

Some files were not shown because too many files have changed in this diff Show more