1*912701f9SAndroid Build Coastguard Worker// helper functions for keyboard 2*912701f9SAndroid Build Coastguard Worker 3*912701f9SAndroid Build Coastguard Worker/** 4*912701f9SAndroid Build Coastguard Worker * Unescape an escaped string 5*912701f9SAndroid Build Coastguard Worker * @param str input string such as '\u017c' 6*912701f9SAndroid Build Coastguard Worker * @returns 7*912701f9SAndroid Build Coastguard Worker */ 8*912701f9SAndroid Build Coastguard Workerfunction unescapeStr(str) { 9*912701f9SAndroid Build Coastguard Worker str = str.replace(/\\u{([0-9a-fA-F]+)}/g, (a, b) => 10*912701f9SAndroid Build Coastguard Worker String.fromCodePoint(Number.parseInt(b, 16)) 11*912701f9SAndroid Build Coastguard Worker ); 12*912701f9SAndroid Build Coastguard Worker return str; 13*912701f9SAndroid Build Coastguard Worker} 14*912701f9SAndroid Build Coastguard Worker 15*912701f9SAndroid Build Coastguard Workerfunction getKeyboardLayers(id) { 16*912701f9SAndroid Build Coastguard Worker let q = _KeyboardData.keyboards[id].keyboard3.layers; 17*912701f9SAndroid Build Coastguard Worker if (!Array.isArray(q)) { 18*912701f9SAndroid Build Coastguard Worker q = [q]; 19*912701f9SAndroid Build Coastguard Worker } 20*912701f9SAndroid Build Coastguard Worker mogrifyAttrs(q); 21*912701f9SAndroid Build Coastguard Worker const keybag = getKeyboardKeys(id); 22*912701f9SAndroid Build Coastguard Worker mogrifyLayerList(q, keybag); 23*912701f9SAndroid Build Coastguard Worker return q; 24*912701f9SAndroid Build Coastguard Worker} 25*912701f9SAndroid Build Coastguard Worker 26*912701f9SAndroid Build Coastguard Workerfunction mogrifyLayerList(layerList, keybag) { 27*912701f9SAndroid Build Coastguard Worker layerList.forEach(({ layer }) => { 28*912701f9SAndroid Build Coastguard Worker layer.forEach(({ row }) => { 29*912701f9SAndroid Build Coastguard Worker row.forEach((r) => { 30*912701f9SAndroid Build Coastguard Worker r.keys = r.keys.split(" ").map((id) => 31*912701f9SAndroid Build Coastguard Worker Object.assign( 32*912701f9SAndroid Build Coastguard Worker { 33*912701f9SAndroid Build Coastguard Worker id, 34*912701f9SAndroid Build Coastguard Worker }, 35*912701f9SAndroid Build Coastguard Worker keybag[id] 36*912701f9SAndroid Build Coastguard Worker ) 37*912701f9SAndroid Build Coastguard Worker ); 38*912701f9SAndroid Build Coastguard Worker }); 39*912701f9SAndroid Build Coastguard Worker }); 40*912701f9SAndroid Build Coastguard Worker }); 41*912701f9SAndroid Build Coastguard Worker} 42*912701f9SAndroid Build Coastguard Worker 43*912701f9SAndroid Build Coastguard Workerfunction getImportFile(id) { 44*912701f9SAndroid Build Coastguard Worker return _KeyboardData.imports[id["@_path"].split("/")[1]]; 45*912701f9SAndroid Build Coastguard Worker} 46*912701f9SAndroid Build Coastguard Worker 47*912701f9SAndroid Build Coastguard Workerfunction getImportKeys(id) { 48*912701f9SAndroid Build Coastguard Worker const imp = getImportFile(id); 49*912701f9SAndroid Build Coastguard Worker if (!imp) { 50*912701f9SAndroid Build Coastguard Worker throw Error(`Could not load import ${JSON.stringify(id)}`); 51*912701f9SAndroid Build Coastguard Worker } 52*912701f9SAndroid Build Coastguard Worker return imp.keys.key; 53*912701f9SAndroid Build Coastguard Worker} 54*912701f9SAndroid Build Coastguard Worker 55*912701f9SAndroid Build Coastguard Workerfunction mogrifyKeys(keys) { 56*912701f9SAndroid Build Coastguard Worker // drop @' 57*912701f9SAndroid Build Coastguard Worker if (!keys) { 58*912701f9SAndroid Build Coastguard Worker return []; 59*912701f9SAndroid Build Coastguard Worker } 60*912701f9SAndroid Build Coastguard Worker return keys.reduce((p, v) => { 61*912701f9SAndroid Build Coastguard Worker // TODO: any other swapping 62*912701f9SAndroid Build Coastguard Worker mogrifyAttrs(v); 63*912701f9SAndroid Build Coastguard Worker const { id, output } = v; 64*912701f9SAndroid Build Coastguard Worker if (output) { 65*912701f9SAndroid Build Coastguard Worker v.output = unescapeStr(output); 66*912701f9SAndroid Build Coastguard Worker } 67*912701f9SAndroid Build Coastguard Worker p[id] = v; 68*912701f9SAndroid Build Coastguard Worker return p; 69*912701f9SAndroid Build Coastguard Worker }, {}); 70*912701f9SAndroid Build Coastguard Worker} 71*912701f9SAndroid Build Coastguard Worker 72*912701f9SAndroid Build Coastguard Workerfunction mogrifyAttrs(o) { 73*912701f9SAndroid Build Coastguard Worker for (const k of Object.keys(o)) { 74*912701f9SAndroid Build Coastguard Worker const ok = o[k]; 75*912701f9SAndroid Build Coastguard Worker if (/^@_/.test(k)) { 76*912701f9SAndroid Build Coastguard Worker const attr = k.substring(2); 77*912701f9SAndroid Build Coastguard Worker o[attr] = ok; 78*912701f9SAndroid Build Coastguard Worker delete o[k]; 79*912701f9SAndroid Build Coastguard Worker } else if (Array.isArray(ok)) { 80*912701f9SAndroid Build Coastguard Worker ok.forEach((e) => mogrifyAttrs(e)); 81*912701f9SAndroid Build Coastguard Worker } else if (typeof ok === "object") { 82*912701f9SAndroid Build Coastguard Worker mogrifyAttrs(ok); 83*912701f9SAndroid Build Coastguard Worker } 84*912701f9SAndroid Build Coastguard Worker } 85*912701f9SAndroid Build Coastguard Worker return o; 86*912701f9SAndroid Build Coastguard Worker} 87*912701f9SAndroid Build Coastguard Worker 88*912701f9SAndroid Build Coastguard Workerfunction getKeyboardKeys(id) { 89*912701f9SAndroid Build Coastguard Worker const keys = _KeyboardData.keyboards[id].keyboard3.keys.key || []; 90*912701f9SAndroid Build Coastguard Worker if (!keys) { 91*912701f9SAndroid Build Coastguard Worker throw Error(`No keys for ${id}`); 92*912701f9SAndroid Build Coastguard Worker } 93*912701f9SAndroid Build Coastguard Worker let imports = [ 94*912701f9SAndroid Build Coastguard Worker { 95*912701f9SAndroid Build Coastguard Worker // add implied import 96*912701f9SAndroid Build Coastguard Worker "@_base": "cldr", 97*912701f9SAndroid Build Coastguard Worker "@_path": "45/keys-Latn-implied.xml", 98*912701f9SAndroid Build Coastguard Worker }, 99*912701f9SAndroid Build Coastguard Worker ...(_KeyboardData.keyboards[id].keyboard3.keys.import || []), 100*912701f9SAndroid Build Coastguard Worker ]; 101*912701f9SAndroid Build Coastguard Worker 102*912701f9SAndroid Build Coastguard Worker const importedKeys = []; 103*912701f9SAndroid Build Coastguard Worker for (const fn of imports) { 104*912701f9SAndroid Build Coastguard Worker for (const k of getImportKeys(fn)) { 105*912701f9SAndroid Build Coastguard Worker importedKeys.push(k); 106*912701f9SAndroid Build Coastguard Worker } 107*912701f9SAndroid Build Coastguard Worker } 108*912701f9SAndroid Build Coastguard Worker 109*912701f9SAndroid Build Coastguard Worker return mogrifyKeys([...importedKeys, ...keys]); 110*912701f9SAndroid Build Coastguard Worker} 111*912701f9SAndroid Build Coastguard Worker 112*912701f9SAndroid Build Coastguard Workerfunction getIds() { 113*912701f9SAndroid Build Coastguard Worker return Object.keys(_KeyboardData.keyboards); 114*912701f9SAndroid Build Coastguard Worker} 115