Skip to content

Instantly share code, notes, and snippets.

@chaidhat
Last active July 6, 2019 08:55
Show Gist options
  • Save chaidhat/47e72152c248570bb61da72c093a0234 to your computer and use it in GitHub Desktop.
Save chaidhat/47e72152c248570bb61da72c093a0234 to your computer and use it in GitHub Desktop.
const ArgumentType = require('../../extension-support/argument-type');
const BlockType = require('../../extension-support/block-type');
const Cast = require('../../util/cast');
const log = require('../../util/log');
const nets = require('nets');
const languageNames = require('scratch-translate-extension-languages');
const formatMessage = require('format-message');
/**
* Icon svg to be displayed in the blocks category menu, encoded as a data URI.
* @type {string}
*/
// eslint-disable-next-line max-len
const menuIconURI = 'data:image/png;base64,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';
/**
* Icon svg to be displayed at the left edge of each extension block, encoded as a data URI.
* @type {string}
*/
// eslint-disable-next-line max-len
//const blockIconURI = 'data:image/png;base64,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';
const blockIconURI = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHN0eWxlPi5zdDJ7ZmlsbDpyZWR9LnN0M3tmaWxsOiNlMGUwZTB9LnN0NHtmaWxsOm5vbmU7c3Ryb2tlOiM2NjY7c3Ryb2tlLXdpZHRoOi41O3N0cm9rZS1taXRlcmxpbWl0OjEwfTwvc3R5bGU+PHBhdGggZD0iTTM1IDI4SDVhMSAxIDAgMCAxLTEtMVYxMmMwLS42LjQtMSAxLTFoMzBjLjUgMCAxIC40IDEgMXYxNWMwIC41LS41IDEtMSAxeiIgZmlsbD0iI2ZmZiIgaWQ9IkxheWVyXzYiLz48ZyBpZD0iTGF5ZXJfNCI+PHBhdGggY2xhc3M9InN0MiIgZD0iTTQgMjVoMzJ2Mi43SDR6TTEzIDI0aC0yLjJhMSAxIDAgMCAxLTEtMXYtOS43YzAtLjYuNC0xIDEtMUgxM2MuNiAwIDEgLjQgMSAxVjIzYzAgLjYtLjUgMS0xIDF6Ii8+PHBhdGggY2xhc3M9InN0MiIgZD0iTTYuMSAxOS4zdi0yLjJjMC0uNS40LTEgMS0xaDkuN2MuNSAwIDEgLjUgMSAxdjIuMmMwIC41LS41IDEtMSAxSDcuMWExIDEgMCAwIDEtMS0xeiIvPjxjaXJjbGUgY2xhc3M9InN0MiIgY3g9IjIyLjgiIGN5PSIxOC4yIiByPSIzLjQiLz48Y2lyY2xlIGNsYXNzPSJzdDIiIGN4PSIzMC42IiBjeT0iMTguMiIgcj0iMy40Ii8+PHBhdGggY2xhc3M9InN0MiIgZD0iTTQuMiAyN2gzMS45di43SDQuMnoiLz48L2c+PGcgaWQ9IkxheWVyXzUiPjxjaXJjbGUgY2xhc3M9InN0MyIgY3g9IjIyLjgiIGN5PSIxOC4yIiByPSIyLjMiLz48Y2lyY2xlIGNsYXNzPSJzdDMiIGN4PSIzMC42IiBjeT0iMTguMiIgcj0iMi4zIi8+PHBhdGggY2xhc3M9InN0MyIgZD0iTTEyLjUgMjIuOWgtMS4yYy0uMyAwLS41LS4yLS41LS41VjE0YzAtLjMuMi0uNS41LS41aDEuMmMuMyAwIC41LjIuNS41djguNGMwIC4zLS4yLjUtLjUuNXoiLz48cGF0aCBjbGFzcz0ic3QzIiBkPSJNNy4yIDE4Ljd2LTEuMmMwLS4zLjItLjUuNS0uNWg4LjRjLjMgMCAuNS4yLjUuNXYxLjJjMCAuMy0uMi41LS41LjVINy43Yy0uMyAwLS41LS4yLS41LS41ek00IDI2aDMydjJINHoiLz48L2c+PGcgaWQ9IkxheWVyXzMiPjxwYXRoIGNsYXNzPSJzdDQiIGQ9Ik0zNS4yIDI3LjlINC44YTEgMSAwIDAgMS0xLTFWMTIuMWMwLS42LjUtMSAxLTFoMzAuNWMuNSAwIDEgLjQgMSAxVjI3YTEgMSAwIDAgMS0xLjEuOXoiLz48cGF0aCBjbGFzcz0ic3Q0IiBkPSJNMzUuMiAyNy45SDQuOGExIDEgMCAwIDEtMS0xVjEyLjFjMC0uNi41LTEgMS0xaDMwLjVjLjUgMCAxIC40IDEgMVYyN2ExIDEgMCAwIDEtMS4xLjl6Ii8+PC9nPjwvc3ZnPg==';
//const docsURI: 'https://translate-service.scratch.mit.edu/';
/**
* The url of the translate server.
* @type {string}
*/
const serverURL = 'https://translate-service.scratch.mit.edu/';
/**
* How long to wait in ms before timing out requests to translate server.
* @type {int}
*/
const serverTimeoutMs = 10000; // 10 seconds (chosen arbitrarily).
/**
* Class for the translate block in Scratch 3.0.
* @constructor
*/
class Scratch3SOOP {
constructor (runtime, util) {
this.runtime = runtime;
this.util = util;
this._a = 0;
this._funcs = {};
this._funcsparam = {};
this.debug = "all good";
this.debugerrorc = 0;
//[function_expecting, return value]
this._retFunctionExpecting = {};
this._retFunctionExpectingNum = 0;
this._retValue = "null";
this._structure = {};
this._giveDir = false;
this._altFunc = {};
this._testFunc = false;
this._scope = "";
this._tempscope = {};
this._tempscopenum = 0;
this._funcscope = "";
this._tempfuncscope = {};
this._tempfuncscopenum = 0;
}
/**
* The key to load & store a target's translate state.
* @return {string} The key.
*/
static get STATE_KEY () {
return 'Scratch.translate';
}
/**
* @returns {object} metadata for this extension and its blocks.
*/
getInfo () {
this._supportedLanguages = this._getSupportedLanguages(this.getViewerLanguageCode());
this._randomLanguageCode = this._supportedLanguages[
Math.floor(Math.random() * this._supportedLanguages.length)].value;
return {
id: 'translate',
name: formatMessage({
id: 'translate.categoryName',
default: 'OOP',
description: 'Name of extension that adds translate blocks'
}),
color1: '#8B4200',
color2: '#7B3200',
color3: '#CCCCCC',
docsURI: 'https://translate-service.scratch.mit.edu/',
//blockIconURI: blockIconURI,
//menuIconURI: menuIconURI,
blocks: [
{
opcode: 'clas',
text: formatMessage({
id: 'translate.clas',
default: 'class [CLASSNAME]',
description: 'the languge of the project viewer'
}),
blockType: BlockType.REPORTER,
arguments: {
CLASSNAME: {
type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.clas.name',
default: "Fruit",
description: 'hello: the default text to translate'
})
},
},
},
{
opcode: 'clasConstructor',
text: formatMessage({
id: 'translate.clasConstructor',
default: 'class [CLASSNAME]. [VALUE]',
description: 'the languge of the project viewer'
}),
blockType: BlockType.REPORTER,
arguments: {
CLASSNAME: {
type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.clasConstructor.name',
default: "Fruit",
description: 'hello: the default text to translate'
})
},
VALUE: {
//type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.clasConstructor.value',
default: 1,
description: 'hello: the default text to translate'
})
},
},
},
{
opcode: 'prop',
text: formatMessage({
id: 'translate.scopeableVar',
default: 'property [PROPNAME]',
description: 'the languge of the project viewer'
}),
blockType: BlockType.REPORTER,
arguments: {
PROPNAME: {
type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.prop.name',
default: "apple",
description: 'hello: the default text to translate'
})
},
},
},
'---',
{
opcode: 'set',
text: formatMessage({
id: 'translate.set',
default: 'set object [NAME] to [VALUE]',
description: 'the languge of the project viewer'
}),
blockType: BlockType.COMMAND,
arguments: {
NAME: {
//type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.set.name',
default: 1,
description: 'hello: the default text to translate'
})
},
VALUE: {
type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.set.value',
default: 1,
description: 'hello: the default text to translate'
})
},
},
},
'---',
{
opcode: 'funcref',
text: formatMessage({
id: 'translate.funcref',
default: 'function [FUNCNAME]',
description: 'the languge of the project viewer'
}),
blockType: BlockType.REPORTER,
arguments: {
FUNCNAME: {
type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.funcref.name',
default: "foo",
description: 'hello: the default text to translate'
})
},
},
},
{
opcode: 'callfunc',
text: formatMessage({
id: 'translate.callfunc',
default: 'call [NAME] <-- [PARAM]',
description: 'the languge of the project viewer'
}),
blockType: BlockType.REPORTER,
arguments: {
NAME: {
//type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.callfunc.name',
default: "foo",
description: 'hello: the default text to translate'
})
},
PARAM: {
//type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.callfunc.param',
default: 1,
description: 'hello: the default text to translate'
})
},
},
},
'---',
{
opcode: 'func',
text: formatMessage({
id: 'translate.func',
default: '[SCOPE] :: function [NAME] <-- [PARAM]',
description: 'the languge of the project viewer'
}),
blockType: BlockType.HAT,
arguments: {
SCOPE: {
//type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.func.scope',
default: 1,
description: 'hello: the default text to translate'
})
},
NAME: {
type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.func.name',
default: "foo",
description: 'hello: the default text to translate'
})
},
PARAM: {
//type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.func.param',
default: 1,
description: 'hello: the default text to translate'
})
},
},
},
{
opcode: 'thi',
text: formatMessage({
id: 'translate.thi',
default: 'this class . [PARAM]',
description: 'the languge of the project viewer'
}),
blockType: BlockType.REPORTER,
arguments: {
PARAM: {
//type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.thi.param',
default: 1,
description: 'hello: the default text to translate'
})
},
},
},
{
opcode: 'ret',
text: formatMessage({
id: 'translate.ret',
default: 'function return [VALUE]-->',
description: 'the languge of the project viewer'
}),
isTerminal: true,
blockType: BlockType.COMMAND,
arguments: {
VALUE: {
type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.ret.value',
default: "bar",
description: 'hello: the default text to translate'
})
},
},
},
'---',
{
opcode: 'tuple',
text: formatMessage({
id: 'translate.tuple',
default: '[VALUE1] , [VALUE2]',
description: 'the languge of the project viewer'
}),
blockType: BlockType.REPORTER,
arguments: {
VALUE1: {
type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.tuple.value1',
default: "",
description: 'hello: the default text to translate'
})
},
VALUE2: {
type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.tuple.value2',
default: "",
description: 'hello: the default text to translate'
})
},
},
},
{
opcode: 'gettuple',
text: formatMessage({
id: 'translate.gettuple',
default: 'get item [NUMBER] of tuple [TUPLE]',
description: 'the languge of the project viewer'
}),
blockType: BlockType.REPORTER,
arguments: {
NUMBER: {
type: ArgumentType.NUMBER,
defaultValue: formatMessage({
id: 'translate.gettuple.number',
default: 1,
description: 'hello: the default text to translate'
})
},
TUPLE: {
//type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.gettuple.tuple',
default: 1,
description: 'hello: the default text to translate'
})
},
},
},
'---',
{
opcode: 'scop',
text: formatMessage({
id: 'translate.scop',
default: 'using class [CLASSNAME]',
description: 'the languge of the project viewer'
}),
blockType: BlockType.CONDITIONAL,
arguments: {
CLASSNAME: {
defaultValue: formatMessage({
id: 'translate.scop.classname',
default: 1,
description: 'hello: the default text to translate'
})
},
},
},
'---',
{
opcode: 'c',
text: formatMessage({
id: 'translate.c',
default: 'debug.reset func [NAME]',
description: 'the languge of the project viewer'
}),
blockType: BlockType.COMMAND,
arguments: {
NAME: {
type: ArgumentType.STRING,
defaultValue: formatMessage({
id: 'translate.debug.name',
default: 1,
description: 'hello: the default text to translate'
})
},
},
},
{
opcode: 'dl',
text: formatMessage({
id: 'translate.dl',
default: 'debug.log',
description: 'the languge of the project viewer'
}),
blockType: BlockType.REPORTER,
arguments: {
},
},
{
opcode: 'de',
text: formatMessage({
id: 'translate.de',
default: 'debug.error?',
description: 'the languge of the project viewer'
}),
blockType: BlockType.BOOLEAN,
arguments: {
},
},
],
menus: {
languages: {
acceptReporters: true,
items: this._supportedLanguages
}
}
};
}
func({SCOPE,NAME,PARAM})
{
if (SCOPE)
NAME = SCOPE.substring(0,SCOPE.length - 1) + "," + NAME;
if (this._funcs[NAME] === "true")
{
this._tempscope[this._tempscopenum] = this._scope;
this._tempscopenum++;
this._tempfuncscope[this._tempfuncscopenum] = this._funcscope;
this._tempfuncscopenum++;
this._scope = "funcclass " + NAME + ",";
if (SCOPE)
this._funcscope = SCOPE.substring(0,SCOPE.length - 1) + ",";
this._funcs[NAME] = "standtrue";
if (this._testFunc)
{
return false;
}
return true;
}
else
{
if (this._funcs[NAME] === "standfalse")
{
this._funcs[NAME] = "false";
}
return false;
}
}
callfunc(args,util)
{
var a = args.NAME.substring(args.NAME.length - 1, args.NAME.length);
if (!(a === "]"))
{
this.debug = "ERROR NO" + this.debugerrorc +": in function " + args.NAME + ", " + "Code: 1. not a function! Proper usage: (call ( (function (FOO)) ) <-- ( )). Put only (function ( )) block into it!";
return this.debug;
}
else
{
args.NAME = args.NAME.substring(0, args.NAME.length - 1);
}
if (this._retFunctionExpectingNum < -10)
{
this.debug = "ERROR NO" + this.debugerrorc +": in function " + args.NAME + ", " + "Code: 2. this._retFunctionExpectingNum < 10, please reset errors.";
return this.debug;
}
if (util.stackTimerNeedsInit()) {
var j = 0;
for (var i = -10; i < this._retFunctionExpectingNum; i++)
{
if (this._retFunctionExpecting[i] === args.NAME)
{
j++;
}
}
if (j > 0)
{
this.debug = "ERROR NO" + this.debugerrorc + ": in function " + args.NAME + ", " + "Code: 3. no recursion allowed. I'm sorry.";
return this.debug;
}
if (this._funcs[args.NAME] != "true" && this._funcs[args.NAME] != "standfalse" && this._funcs[args.NAME] != "standtrue")
{
/*
/ Have we run before, starting threads?
if (!util.stackFrame.startedThreads) {
// No - start hats for this broadcast.
util.stackFrame.startedThreads = util.startHats(
'event_whenbroadcastreceived', {
BROADCAST_OPTION: broadcastOption
}
);
if (util.stackFrame.startedThreads.length === 0) {
// Nothing was started.
return;
}
}
// We've */
const efen = this._retFunctionExpectingNum;
this._funcs[args.NAME] = "true";
this._funcsparam[args.NAME] = args.PARAM;
this._retFunctionExpectingNum++;
this._retFunctionExpecting[efen] = args.NAME;
util.a = efen;
util.time = 0;
util.startStackTimer(100);
/*let efen = this._retFunctionExpectingNum;
this._retFunctionExpectingNum++;
for (var i = 0; i < 10; i++)
{
if (this._retFunctionExpectingNum === efen)
{
return this._retValue;
}
}*/
this.runtime.requestRedraw();
util.yield();
}
else
{
util.yield();
}
}
else
{
if (this._retFunctionExpectingNum === util.a) {
this._retFunctionExpecting[util.a] = "";
this._funcs[args.NAME] = "standfalse";
return this._retValue;
} else {
util.time++;
if (!(this._funcs[args.NAME] === "standtrue") && util.stackTimerFinished())
{
this._funcs[args.NAME] = "false";
this._retFunctionExpectingNum--;
this.debug = "ERROR NO" + this.debugerrorc + ": in function " + args.NAME + ", " + "Code: 4. Is there actually a function hat declaring this function?";
return this.debug;
}
util.yield();
}
}
}
ret({VALUE})
{
this._retValue = VALUE;
this._retFunctionExpectingNum--;
this._tempscopenum--;
this._scope = this._tempscope[this._tempscopenum];
return;
}
c(args,util)
{
for (var i = -10; i < this._retFunctionExpectingNum + 1; i++)
{
this._retFunctionExpecting[i] = "";
}
this._retFunctionExpectingNum = 0;
this._tempscopenum = 0;
this._funcs[args.NAME] = "false";
this._scope = "";
this.debug = "all good";
}
clas(args, util)
{
this._giveDir = ">" + args.CLASSNAME + "[";
//this.debug = (this._scope + this._giveDir);
return ">" + args.CLASSNAME + "[";
}
clasConstructor(args, util)
{
if (args.VALUE)
{
}
else
{
this._giveDir = ">" + args.CLASSNAME + "[";
//this.debug = (this._scope + this._giveDir);
return ">" + args.CLASSNAME + "[";
}
this._giveDir = ">" + args.CLASSNAME + "," + this._giveDir;
//this.debug = (this._scope + this._giveDir);
var a = (this._scope + this._giveDir).substring((this._scope + this._giveDir).length - 1, (this._scope + this._giveDir).length);
if (a === "[" || a === "]")
{
// class
return (this._scope + this._giveDir);
}
if (this._structure[(this._scope + this._giveDir)])
{
// property
if (this._structure[(this._scope + this._giveDir)].substring(0,1) === "*")
{
return this._structure[(this._scope + this._giveDir)].substring(1,this._structure[(this._scope + this._giveDir)].length);
}
else
{
return this._structure[(this._scope + this._giveDir)];
}
}
else
{
// nullptr
return "null";
}
}
prop(args, util)
{
this._giveDir = args.PROPNAME;
//this.debug = (this._scope + this._giveDir);
if (this._structure[(this._scope + this._giveDir)])
{
// property
if (this._structure[(this._scope + this._giveDir)].substring(0,1) === "*")
{
return this._structure[(this._scope + this._giveDir)].substring(1,this._structure[(this._scope + this._giveDir)].length);
}
else
{
return this._structure[(this._scope + this._giveDir)];
}
}
else
{
// nullptr
return "null";
}
}
thi(args)
{
if (args.VALUE)
{
}
else
{
this._giveDir = ">" + args.CLASSNAME + "[";
//this.debug = (this._scope + this._giveDir);
return ">" + args.CLASSNAME + "[";
}
this._giveDir = ">" + args.CLASSNAME + "," + this._giveDir;
//this.debug = (this._scope + this._giveDir);
var a = (this._scope + this._giveDir).substring((this._funcscope + this._giveDir).length - 1, (this._scope + this._giveDir).length);
if (a === "[" || a === "]")
{
// class
return (this._funcscope + this._giveDir);
}
if (this._structure[(this._funcscope + this._giveDir)])
{
// property
if (this._structure[(this._funcscope + this._giveDir)].substring(0,1) === "*")
{
return this._structure[(this._funcscope + this._giveDir)].substring(1,this._structure[(this._funcscope + this._giveDir)].length);
}
else
{
return this._structure[(this._funcscope + this._giveDir)];
}
}
else
{
// nullptr
return "null";
}
}
funcref(args, util)
{
this._giveDir = args.FUNCNAME + "]";
this.debug = (this._scope + this._giveDir);
return (this._scope + this._giveDir);
}
dl()
{
return this._funcscope;
}
de()
{
if (this.debug === "all good")
{
return false;
}
else
{
return true;
}
}
set(args, util)
{
//this.debug = "set " + (this._scope + this._giveDir) + ", ";
var de = ""
var a = getBranch((this._scope + this._giveDir), false);
var b = getBranch((this._scope + this._giveDir), true);
var c = a[b-1];
if (!this._structure[(this._scope + this._giveDir)])
{
//this.debug = "a";
for (var j = 1; j < b; j++)
{
var d = a[0];
for (var i = 1; i < j; i++)
{
d = d + "," + a[i];
}
var prefix = "";
// d is the indexer
if (j < b - 1)
{
//prefix = ">";
}
if (!this._structure[d])
{
this._structure[d] = prefix + a[j];
}
else
{
this._structure[d] = this._structure[d] + "," + prefix + a[j];
}
de = de + "::" + d + " to " + this._structure[d];
}
}
if ((this._scope + this._giveDir).substring((this._scope + this._giveDir).length - 1, (this._scope + this._giveDir).length) === "[")
{
// to make sure it exists, we add "*" to the beginning of it
//this._structure[(this._scope + this._giveDir)] = "*" + args.VALUE;
var name = args.NAME.substring(0,args.NAME.length - 1);
var val = args.VALUE.substring(0,args.VALUE.length - 1);
if (val)
{
// notice val and name are swapped in the CORRECT order
this.debug = val;
this._structure = dupeBranch(this._structure, val, name);
}
else
{
this.debug = "ERROR NO" + this.debugerrorc +": Code: 3. Value to be copied is missing.";
}
}
else if ((this._scope + this._giveDir).substring((this._scope + this._giveDir).length - 1, (this._scope + this._giveDir).length) === "]")
{
this._structure[(this._scope + this._giveDir)]
}
else
{
// to make sure it exists, we add "*" to the beginning of it
this._structure[(this._scope + this._giveDir)] = "*" + args.VALUE;
this.debug = de;
}
}
tuple(args)
{
return args.VALUE1 + "," + args.VALUE2;
}
gettuple(args)
{
var a = getBranch(args.TUPLE, false);
return a[args.NUMBER - 1];
}
scop(args, util)
{
if (typeof util.stackFrame.loopCounter === 'undefined') {
util.stackFrame.loopCounter = 1;
}
if (util.stackFrame.loopCounter > 0) {
if ((this._scope + this._giveDir).substring((this._scope + this._giveDir).length - 1, (this._scope + this._giveDir).length) === "[")
{
if (this._scope === "")
{
this._scope = args.CLASSNAME.substring(0,args.CLASSNAME.length - 1) + ",";
}
else
{
this._scope = this._scope + args.CLASSNAME.substring(0,args.CLASSNAME.length - 1) + ",";
}
util.stackFrame.loopCounter--;
util.startBranch(1, true);
}
else
{
this.debug = "ERROR NO" + this.debugerrorc +": Code: 4. Input must be a class.";
}
}
else
{
this._scope = this._scope.substring(0, this._scope.length - args.CLASSNAME.length)
;
}
}
/**
* Computes a list of language code and name pairs for the given language.
* @param {string} code The language code to get the list of language pairs
* @return {Array.<object.<string, string>>} An array of languge name and
* language code pairs.
* @private
*/
_getSupportedLanguages (code) {
return languageNames.menuMap[code].map(entry => {
const obj = {text: entry.name, value: entry.code};
return obj;
});
}
/**
* Get the human readable language value for the reporter block.
* @return {string} the language name of the project viewer.
*/
getViewerLanguage () {
this._viewerLanguageCode = this.getViewerLanguageCode();
const names = languageNames.menuMap[this._viewerLanguageCode];
let langNameObj = names.find(obj => obj.code === this._viewerLanguageCode);
// If we don't have a name entry yet, try looking it up via the Google langauge
// code instead of Scratch's (e.g. for es-419 we look up es to get espanol)
if (!langNameObj && languageNames.scratchToGoogleMap[this._viewerLanguageCode]) {
const lookupCode = languageNames.scratchToGoogleMap[this._viewerLanguageCode];
langNameObj = names.find(obj => obj.code === lookupCode);
}
let langName = this._viewerLanguageCode;
if (langNameObj) {
langName = langNameObj.name;
}
return langName;
}
/**
* Get the viewer's language code.
* @return {string} the language code.
*/
getViewerLanguageCode () {
const locale = formatMessage.setup().locale;
const viewerLanguages = [locale].concat(navigator.languages);
const languageKeys = Object.keys(languageNames.menuMap);
// Return the first entry in viewerLanguages that matches
// one of the available language keys.
const languageCode = viewerLanguages.reduce((acc, lang) => {
if (acc) {
return acc;
}
if (languageKeys.indexOf(lang.toLowerCase()) > -1) {
return lang;
}
return acc;
}, '') || 'en';
return languageCode.toLowerCase();
}
}
//structure = dupeBranch(structure);
function getBranch (dir, getB)
{
var c = dir;
var a = {};
var b = 0;
var m = 0;
for (var i = 0; i < c.length - 1; i++)
{
if (c.substring(i,i+1) === ",")
{
a[b] = c.substring(m, i);
b++;
m = i + 1;
}
}
a[b] = c.substring(m, i + 1);
b++;
if (getB)
{
return b;
}
return a;
}
function dupeBranch (structure, dupeDir, newDir)
{
var a = getBranch(structure[dupeDir], false);
var b = getBranch(structure[dupeDir], true);
for (var i = 0; i < b; i++){
if (a[i].substring(0, 1) === ">")
{
structure = dupeBranch (structure, dupeDir + "," + a[i], newDir + "," + a[i])
}
if (i < 1)
{
d = a[i];
}
else
{
d = d + "," + a[i];
}
structure[newDir + "," + a[i]] = structure[dupeDir + "," + a[i]];
}
structure[newDir] = d;
/* var s = structure;
var c = s[dupeDir] = "iads:yewuio:cxcv";
var a = {};
var b = 0;
var s = 0;
for (var i = 0; i < c.length - 1; i++)
{
if (c.substring(i,i+1) === ",")
{
a[b] = c.substring(s, i);
b++;
s = i + 1;
}
}
a[b] = c.substring(s, i + 1);
b++;
structure[newDir] = c;
for (var i = 0; i < b; b++)
{
structure[newDir + "," + a[b]] = s[dupeDir + "," + a[b]];
}*/
/*this._structure["Fruit/apple/ripeness"] = 0;
this._structure["Fruit/apple/count"] = 0;
this._structure["Fruit/apple"] = "ripeness:count";*/
return structure;
}
module.exports = Scratch3SOOP;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment