<commit_before>var CHROME_INNER_URL_PATTERN = /^chrome(-.+)?\:\/\/.+/;
var NEWTAB = { url: 'chrome://newtab/', selected : false };
var NOT_PINED_TABS = { pinned: false };
var KEY_YOUR_LAST_TABS = 'KEY_YOUR_LAST_TABS';
var GET_POSITION_INJECTION = { code: '({ top: document.body.scrollTop, left: document.body.scrollLeft })' };
var OPTIONS_URL = chrome.extension.getURL('page/options.html');
var EMPTY_STR = '';

function is_newtab(tab) {
    return tab.url == NEWTAB.url;
}

function has_last_tabs(items) {
    return items != null && items.KEY_YOUR_LAST_TABS != null && items.KEY_YOUR_LAST_TABS.length > 0;
}

function is_url_ok(url) {
    return url != null && url != EMPTY_STR && !CHROME_INNER_URL_PATTERN.test(url);
}

function is_position_valid(pos) {
    var typeNum = typeof(0);
    return pos != null && typeof(pos.top) == typeNum && typeof(pos.left) == typeNum;
}

function is_positions_ready(positions, current_tabs) {
    for (var i = 0; i < current_tabs.length; ++i) {
        var tab = current_tabs[i];
        if (positions[tab.url] == null) {
            return false;
        }
    }
    return true;
}

function save_all_windows_tabs() {
    chrome.tabs.query(NOT_PINED_TABS, function (tabs) {
        var current_tabs = [];
        var url_map = {};
        var positions = {};
        tabs.forEach(function (tab) {
            var url = tab.url;
            if (!url_map[url] && is_url_ok(url)) {
                var title = tab.title;
                current_tabs.push({ url: url, title: (title == null || title == EMPTY_STR ? url : title) });
                url_map[url] = true;
                chrome.tabs.executeScript(tab.id, GET_POSITION_INJECTION, function (ary) {
                    if (ary != null && ary.length > 0) {
                        positions[url] = ary[0];
                    }
                });
            }
        });
        var check_id = null;
        check_id = setInterval(function () {
            if (check_id !== null && is_positions_ready(positions, current_tabs)) {
                clearInterval(check_id);
                check_id = null;
                current_tabs.forEach(function (tab) {
                    tab.position = positions[tab.url];
                });
                get_options(function (options) {
                    var diff = current_tabs.length - options.MAX_RECORD_COUNT;
                    if (diff >= 0) {
                        if (diff > 0) {
                            current_tabs = current_tabs.slice(diff, current_tabs.length);
                        }
                        chrome.storage.sync.set({ KEY_YOUR_LAST_TABS: current_tabs });
                    }
                    else {
                        chrome.storage.local.get(KEY_YOUR_LAST_TABS, function (items) {
                            if (has_last_tabs(items)) {
                                var legacy_tabs = items.KEY_YOUR_LAST_TABS;
                                diff += legacy_tabs.length;
                                if (diff < legacy_tabs.length) {
                                    if (diff > 0) {
                                        legacy_tabs = legacy_tabs.slice(diff, legacy_tabs.length);
                                    }
                                    current_tabs.push.apply(current_tabs, legacy_tabs);
                                }
                            }
                            chrome.storage.sync.set({ KEY_YOUR_LAST_TABS: current_tabs });
                        });
                    }
                });
            }
        }, 400);
    });
}
<commit_msg>Fix unsave records problem<commit_after>var CHROME_INNER_URL_PATTERN = /^chrome(-.+)?\:\/\/.+/;
var NEWTAB = { url: 'chrome://newtab/', selected : false };
var NOT_PINED_TABS = { pinned: false, windowType: 'normal' };
var KEY_YOUR_LAST_TABS = 'KEY_YOUR_LAST_TABS';
var GET_POSITION_INJECTION = { code: '({ top: document.body.scrollTop, left: document.body.scrollLeft })' };
var DEFAULT_POSITION = { top: 0, left: 0 };
var OPTIONS_URL = chrome.extension.getURL('page/options.html');
var EMPTY_STR = '';

function is_newtab(tab) {
    return tab.url == NEWTAB.url;
}

function has_last_tabs(items) {
    return items != null && items.KEY_YOUR_LAST_TABS != null && items.KEY_YOUR_LAST_TABS.length > 0;
}

function is_url_ok(url) {
    return url != null && url != EMPTY_STR && !CHROME_INNER_URL_PATTERN.test(url);
}

function is_position_valid(pos) {
    var typeNum = typeof(0);
    return pos != null && typeof(pos.top) == typeNum && typeof(pos.left) == typeNum;
}

function is_positions_ready(positions, current_tabs) {
    for (var i = 0; i < current_tabs.length; ++i) {
        var tab = current_tabs[i];
        if (positions[tab.url] == null) {
            return false;
        }
    }
    return true;
}

function save_all_windows_tabs() {
    chrome.tabs.query(NOT_PINED_TABS, function (tabs) {
        var current_tabs = [];
        var url_map = {};
        var positions = {};
        tabs.forEach(function (tab) {
            var url = tab.url;
            if (!url_map[url] && is_url_ok(url)) {
                var title = tab.title;
                current_tabs.push({ url: url, title: (title == null || title == EMPTY_STR ? url : title) });
                url_map[url] = true;
                chrome.tabs.executeScript(tab.id, GET_POSITION_INJECTION, function (ary) {
                    positions[url] = (chrome.runtime.lastError != null || ary == null || ary.length == 0 ? DEFAULT_POSITION : ary[0]);
                });
            }
        });
        var check_id = null;
        check_id = setInterval(function () {
            if (check_id !== null && is_positions_ready(positions, current_tabs)) {
                clearInterval(check_id);
                check_id = null;
                current_tabs.forEach(function (tab) {
                    tab.position = positions[tab.url];
                });
                get_options(function (options) {
                    var diff = current_tabs.length - options.MAX_RECORD_COUNT;
                    if (diff >= 0) {
                        if (diff > 0) {
                            current_tabs = current_tabs.slice(diff, current_tabs.length);
                        }
                        chrome.storage.sync.set({ KEY_YOUR_LAST_TABS: current_tabs });
                    }
                    else {
                        chrome.storage.local.get(KEY_YOUR_LAST_TABS, function (items) {
                            if (has_last_tabs(items)) {
                                var legacy_tabs = items.KEY_YOUR_LAST_TABS;
                                diff += legacy_tabs.length;
                                if (diff < legacy_tabs.length) {
                                    if (diff > 0) {
                                        legacy_tabs = legacy_tabs.slice(diff, legacy_tabs.length);
                                    }
                                    current_tabs.push.apply(current_tabs, legacy_tabs);
                                }
                            }
                            chrome.storage.sync.set({ KEY_YOUR_LAST_TABS: current_tabs });
                        });
                    }
                });
            }
        }, 400);
    });
}
<|endoftext|>


<commit_before>const tap = require('tap');
const shell = require('shelljs');
const path = require('path');

const test = tap.test;
const zcui = `node ${path.resolve(__dirname, '../../../index.js')} create helper`;
const testProjPath = path.resolve(__dirname, '../../../temp/test-proj');

/*
 * hello-world was project created
 * in new command testing
 */
shell.cd(path.join(testProjPath, 'hello-world'));

test("CREATE_HELPER: Shows help on --help", t => {
  const command = `${zcui} --help`;
  shell.exec(command, {silent:true}, (code, stdout) => {
    if(code === 1) t.fail();
    t.equal(stdout.trim(), `../../../index.js create helper <name>

Options:
  -v, --version  Show version number                                   [boolean]
  -h, --help     Show help                                             [boolean]

Examples:
  ../../../index.js create helper Date
    `.trim());
    t.end();
  });
});

test("CREATE_HELPER: success", t => {
  const command = `${zcui} date`;

  /**
   * Cleanup date helper
   */
  shell.rm('-rf', 'src/helpers/date.js', {silent: true});

  shell.exec(command, {silent:true}, (code, stdout, stderr) => {
    if(code === 1) t.fail(stderr);
    t.equal(stdout.trim(), `✔ date Helper created

  Use:
  import date from '~/helpers/date';
    `.trim());
    t.end();
  });
});

test("CREATE_HELPER: has helper files", t => {

  /**
   * Don not remove date helper
   * date helper created in previous test
   */
  t.ok(shell.test('-f', 'src/helpers/date.js'));
  t.ok(shell.test('-f', 'src/helpers/__tests__/date.spec.js'));
  t.end();
});

test("CREATE_HELPER: error on duplicate", t => {
  const command = `${zcui} date`;

  /**
   * Don not remove date helper
   * date helper created in previous test
   */

  shell.exec(command, {silent:true}, (code, stdout, stderr) => {
    if(code === 0) t.fail(stderr);
    t.equal(stdout.trim(), '✖ date helper already exits! Please choose some another name!!!');
    t.end();
  });
});

<commit_msg>added test cases for generaged helper content<commit_after>const tap = require('tap');
const shell = require('shelljs');
const path = require('path');
const fs = require('fs');

const test = tap.test;
const zcui = `node ${path.resolve(__dirname, '../../../index.js')} create helper`;
const testProjPath = path.resolve(__dirname, '../../../temp/test-proj');

/*
 * hello-world was project created
 * in new command testing
 */
shell.cd(path.join(testProjPath, 'hello-world'));

test("CREATE_HELPER: Shows help on --help", t => {
  const command = `${zcui} --help`;
  shell.exec(command, {silent:true}, (code, stdout) => {
    if(code === 1) t.fail();
    t.equal(stdout.trim(), `../../../index.js create helper <name>

Options:
  -v, --version  Show version number                                   [boolean]
  -h, --help     Show help                                             [boolean]

Examples:
  ../../../index.js create helper Date
    `.trim());
    t.end();
  });
});

test("CREATE_HELPER: success", t => {
  const command = `${zcui} date`;

  /**
   * Cleanup date helper
   */
  shell.rm('-rf', 'src/helpers/date.js', {silent: true});

  shell.exec(command, {silent:true}, (code, stdout, stderr) => {
    if(code === 1) t.fail(stderr);
    t.equal(stdout.trim(), `✔ date Helper created

  Use:
  import date from '~/helpers/date';
    `.trim());
    t.end();
  });
});

test("CREATE_HELPER: has helper files", t => {

  /**
   * Don not remove date helper
   * date helper created in previous test
   */
  t.ok(shell.test('-f', 'src/helpers/date.js'));
  t.ok(shell.test('-f', 'src/helpers/__tests__/date.spec.js'));
  t.end();
});

test("CREATE_HELPER: error on duplicate", t => {
  const command = `${zcui} date`;

  /**
   * Don not remove date helper
   * date helper created in previous test
   */

  shell.exec(command, {silent:true}, (code, stdout, stderr) => {
    if(code === 0) t.fail(stderr);
    t.equal(stdout.trim(), '✖ date helper already exits! Please choose some another name!!!');
    t.end();
  });
});

test("HELPER_CONTENT: helper.js", t => {
  t.equal(fs.readFileSync('src/helpers/date.js', 'utf-8').trim(), `
/* @flow */

export function newHelper(msg:string = 'Hello'): string {
  return \`new Helper \${msg}\`;
}

export default {
  newHelper
}
  `.trim());
  t.end();
});

test("HELPER_CONTENT: __tests__/helper.spec.js", t => {
  t.equal(fs.readFileSync('src/helpers/__tests__/date.spec.js', 'utf-8').trim(), `
/* @flow */

import DateHelper from '../date';

test('DateHelper newHelper', () => {
  expect(DateHelper.newHelper('hello')).toBe('new Helper hello');
});

/** Write your test cases here **/
  `.trim());
  t.end();
});

<|endoftext|>


<commit_before>'use strict'

const functionHelper = require('../../src/functionHelper.js')
const ServerlessOffline = require('../../src/ServerlessOffline.js')
const ServerlessBuilder = require('./ServerlessBuilder.js')

function createHandler(handlers) {
  return (funOptions) => {
    const { handlerName, handlerPath } = funOptions
    const [, path] = handlerPath.split('/')

    return handlers[path][handlerName]
  }
}

module.exports = class OfflineBuilder {
  constructor(serverlessBuilder, options) {
    this.serverlessBuilder = serverlessBuilder || new ServerlessBuilder()
    this.handlers = {}

    // Avoid already wrapped exception when offline is instanciated many times
    // Problem if test are instanciated serveral times
    // FIXME, we could refactor index to have an handlerFactory and just instanciate offline with a factory test stub
    // if (functionHelper.createHandler.restore) {
    //   functionHelper.createHandler.restore();
    // }
    this.options = options || {}
  }

  addFunctionConfig(functionName, functionConfig, handler) {
    this.serverlessBuilder.addFunction(functionName, functionConfig)
    const funOptions = functionHelper.getFunctionOptions(
      functionName,
      functionConfig,
      '.',
    )
    const [, handlerPath] = funOptions.handlerPath.split('/')
    this.handlers[handlerPath] = this.constructor.getFunctionIndex(
      funOptions.handlerName,
      handler,
    )

    return this
  }

  addCustom(prop, value) {
    this.serverlessBuilder.addCustom(prop, value)

    return this
  }

  addApiKeys(keys) {
    this.serverlessBuilder.addApiKeys(keys)

    return this
  }

  static getFunctionIndex(handlerName, handler) {
    const functionIndex = {}
    functionIndex[handlerName] = handler

    return functionIndex
  }

  async toObject() {
    const serverlessOffline = new ServerlessOffline(
      this.serverlessBuilder.toObject(),
      this.options,
    )

    functionHelper.createHandler = jest.fn(createHandler(this.handlers))

    // offline.printBlankLine = jest.fn();

    serverlessOffline.mergeOptions()
    await serverlessOffline._createApiGateway()
    serverlessOffline.setupEvents()

    // offline.apiGateway.printBlankLine = jest.fn();

    // this.server.restore = this.restore;

    return serverlessOffline.getApiGatewayServer()
  }

  // static restore() {
  //   functionHelper.createHandler.restore();
  // }
}
<commit_msg>Simplify static function access<commit_after>'use strict'

const functionHelper = require('../../src/functionHelper.js')
const ServerlessOffline = require('../../src/ServerlessOffline.js')
const ServerlessBuilder = require('./ServerlessBuilder.js')

function createHandler(handlers) {
  return (funOptions) => {
    const { handlerName, handlerPath } = funOptions
    const [, path] = handlerPath.split('/')

    return handlers[path][handlerName]
  }
}

module.exports = class OfflineBuilder {
  constructor(serverlessBuilder, options) {
    this.serverlessBuilder = serverlessBuilder || new ServerlessBuilder()
    this.handlers = {}

    // Avoid already wrapped exception when offline is instanciated many times
    // Problem if test are instanciated serveral times
    // FIXME, we could refactor index to have an handlerFactory and just instanciate offline with a factory test stub
    // if (functionHelper.createHandler.restore) {
    //   functionHelper.createHandler.restore();
    // }
    this.options = options || {}
  }

  addFunctionConfig(functionName, functionConfig, handler) {
    this.serverlessBuilder.addFunction(functionName, functionConfig)

    const funOptions = functionHelper.getFunctionOptions(
      functionName,
      functionConfig,
      '.',
    )
    const [, handlerPath] = funOptions.handlerPath.split('/')

    this.handlers[handlerPath] = OfflineBuilder.getFunctionIndex(
      funOptions.handlerName,
      handler,
    )

    return this
  }

  addCustom(prop, value) {
    this.serverlessBuilder.addCustom(prop, value)

    return this
  }

  addApiKeys(keys) {
    this.serverlessBuilder.addApiKeys(keys)

    return this
  }

  static getFunctionIndex(handlerName, handler) {
    const functionIndex = {}
    functionIndex[handlerName] = handler

    return functionIndex
  }

  async toObject() {
    const serverlessOffline = new ServerlessOffline(
      this.serverlessBuilder.toObject(),
      this.options,
    )

    functionHelper.createHandler = jest.fn(createHandler(this.handlers))

    // offline.printBlankLine = jest.fn();

    serverlessOffline.mergeOptions()
    await serverlessOffline._createApiGateway()
    serverlessOffline.setupEvents()

    // offline.apiGateway.printBlankLine = jest.fn();

    // this.server.restore = this.restore;

    return serverlessOffline.getApiGatewayServer()
  }

  // static restore() {
  //   functionHelper.createHandler.restore();
  // }
}
<|endoftext|>


<commit_before>Imcms.define("imcms-appearance-tab-builder",
    [
        "imcms-bem-builder", "imcms-components-builder", "imcms-page-info-tab-form-builder",
        "imcms-choose-image-builder", "imcms-i18n-texts", "jquery"
    ],
    function (BEM, components, tabFormBuilder, chooseImage, texts, $) {

        texts = texts.pageInfo.title;

        var pageInfoInnerStructureBEM = new BEM({
            block: "imcms-field",
            elements: {
                "checkboxes": "imcms-checkboxes",
                "text-box": "imcms-text-box",
                "text-area": "imcms-text-area",
                "choose-image": "imcms-choose-image",
                "select": "imcms-select",
                "title": "imcms-title",
                "item": ""
            }
        });

        var tabData = {};

        function buildCommonContents(commonContents) {
            tabData.commonContents = [];

            return commonContents.map(buildDocumentCommonContent).reduce(function (cc1, cc2) {
                return cc1.concat(cc2);
            });
        }

        function buildDocumentCommonContent(commonContent) {
            var $checkbox = components.checkboxes.imcmsCheckbox("<div>", {
                    name: commonContent.language.name.toLowerCase(), // fixme: or native name?
                    text: commonContent.language.name,
                    checked: commonContent.enabled ? "checked" : undefined
                }),
                $checkboxWrapper = components.checkboxes.checkboxContainer("<div>", [$checkbox]),
                $checkboxContainer = pageInfoInnerStructureBEM.buildBlock("<div>", [{"checkboxes": $checkboxWrapper}]),
                $pageTitle = components.texts.textBox("<div>", {
                    name: "title",
                    text: texts.title,
                    value: commonContent.headline
                }),
                $pageTitleContainer = pageInfoInnerStructureBEM.buildBlock("<div>", [{"text-box": $pageTitle}]),
                $menuText = components.texts.textArea("<div>", {
                    text: texts.menuText,
                    html: commonContent.menuText,
                    name: "menu-text"
                }),
                $menuTextContainer = pageInfoInnerStructureBEM.buildBlock("<div>", [{"text-area": $menuText}]),
                $linkToImage = chooseImage.container("<div>", {
                    id: "path-to-image",
                    name: "image",
                    value: commonContent.menuImageURL,
                    placeholder: texts.linkToImagePlaceholder,
                    "label-text": texts.linkToImage,
                    "button-text": texts.chooseImage,
                    click: function (selectedImage) {
                        $linkToImage.setValue(selectedImage ? selectedImage.path : "");
                    }
                }),
                $linkToImageContainer = pageInfoInnerStructureBEM.buildBlock("<div>", [{"choose-image": $linkToImage}]);

            tabData.commonContents = tabData.commonContents || [];

            tabData.commonContents.push({
                name: commonContent.language.name,
                checkbox: $checkbox,
                pageTitle: $pageTitle,
                menuText: $menuText,
                linkToImage: $linkToImage
            });

            return [$checkboxContainer, $pageTitleContainer, $menuTextContainer, $linkToImageContainer];
        }

        function buildCommonContentsContainer() {
            return tabData.$commonContentsContainer = $('<div>');
        }

        function buildSelectTargetForDocumentLink() {
            tabData.$showIn = components.selects.imcmsSelect("<div>", {
                id: "show-in",
                text: texts.showIn,
                name: "show-in"
            }, [{
                text: texts.sameFrame,
                "data-value": "_self"
            }, {
                text: texts.newWindow,
                "data-value": "_blank"
            }, {
                text: texts.replaceAll,
                "data-value": "_top"
            }]);

            return pageInfoInnerStructureBEM.buildBlock("<div>", [{"select": tabData.$showIn}]);
        }

        function buildDocumentAliasBlock() {
            tabData.$documentAlias = components.texts.textBox("<div>", {
                name: "alias",
                text: texts.alias,
                placeholder: texts.aliasPlaceholder
            });

            return pageInfoInnerStructureBEM.buildBlock("<div>", [
                {"text-box": tabData.$documentAlias}
            ]);
        }

        function buildBlockForMissingLangSetting() {
            var $languagesTitle = components.texts.titleText("<div>", texts.missingLangRuleTitle);

            tabData.$showDefaultLang = components.radios.imcmsRadio("<div>", {
                text: texts.showInDefault,
                name: "langSetting",
                value: "SHOW_IN_DEFAULT_LANGUAGE",
                checked: "checked" // default value
            });
            tabData.$doNotShow = components.radios.imcmsRadio("<div>", {
                text: texts.doNotShow,
                name: "langSetting",
                value: "DO_NOT_SHOW"
            });

            return pageInfoInnerStructureBEM.buildBlock("<div>", [
                {"title": $languagesTitle},
                {"item": tabData.$showDefaultLang},
                {"item": tabData.$doNotShow}
            ]);
        }

        return {

            name: texts.name,

            tabIndex: null,

            isDocumentTypeSupported: function () {
                return true; // all supported
            },

            showTab: function () {
                tabFormBuilder.showTab(this.tabIndex);
            },

            hideTab: function () {
                tabFormBuilder.hideTab(this.tabIndex);
            },

            buildTab: function (index) {
                this.tabIndex = index;
                var tabElements = [
                    buildCommonContentsContainer(),
                    buildSelectTargetForDocumentLink(),
                    buildDocumentAliasBlock(),
                    buildBlockForMissingLangSetting()
                ];

                return tabFormBuilder.buildFormBlock(tabElements, index);
            },

            fillTabDataFromDocument: function (document) {
                tabData.$commonContentsContainer.prepend(buildCommonContents(document.commonContents));
                tabData.$showIn.selectValue(document.target);
                tabData.$documentAlias.setValue(document.alias);

                components.radios.group(tabData.$showDefaultLang, tabData.$doNotShow)
                    .setCheckedValue(document.disabledLanguageShowMode);
            },

            saveData: function (documentDTO) {
                documentDTO.commonContents.forEach(function (docCommonContent) {
                    tabData.commonContents.forEach(function (commonContent) {

                        if (docCommonContent.language.name !== commonContent.name) {
                            // I can't come up with better solution than double forEach
                            return;
                        }

                        docCommonContent.enabled = commonContent.checkbox.isChecked();
                        docCommonContent.headline = commonContent.pageTitle.getValue();
                        docCommonContent.menuText = commonContent.menuText.getValue();
                        docCommonContent.menuImageURL = commonContent.linkToImage.getValue();
                    });
                });

                documentDTO.alias = tabData.$documentAlias.getValue();
                documentDTO.target = tabData.$showIn.getSelectedValue();

                documentDTO.disabledLanguageShowMode = components.radios
                    .group(tabData.$showDefaultLang, tabData.$doNotShow)
                    .getCheckedValue();

                return documentDTO;
            },

            clearTabData: function () {
                var emptyString = '';

                tabData.commonContents.forEach(function (commonContent, index) {
                    commonContent.checkbox.setChecked(index === 0);//check only first
                    commonContent.pageTitle.setValue(emptyString);
                    commonContent.menuText.setValue(emptyString);
                    commonContent.linkToImage.setValue(emptyString);
                });

                tabData.$commonContentsContainer.empty();

                tabData.$showIn.selectFirst();
                tabData.$documentAlias.setValue(emptyString);
                tabData.$showDefaultLang.setChecked(true); //default value
            }
        };
    }
);
<commit_msg>IMCMS-300 - New design to superadmin-pages: - Refactored appearance tab build process.<commit_after>Imcms.define("imcms-appearance-tab-builder",
    [
        "imcms-bem-builder", "imcms-components-builder", "imcms-page-info-tab-form-builder",
        "imcms-choose-image-builder", "imcms-i18n-texts", "jquery", "imcms-window-tab"
    ],
    function (BEM, components, tabFormBuilder, chooseImage, texts, $, WindowTab) {

        texts = texts.pageInfo.title;

        var pageInfoInnerStructureBEM = new BEM({
            block: "imcms-field",
            elements: {
                "checkboxes": "imcms-checkboxes",
                "text-box": "imcms-text-box",
                "text-area": "imcms-text-area",
                "choose-image": "imcms-choose-image",
                "select": "imcms-select",
                "title": "imcms-title",
                "item": ""
            }
        });

        var tabData = {};

        function buildCommonContents(commonContents) {
            tabData.commonContents = [];

            return commonContents.map(buildDocumentCommonContent).reduce(function (cc1, cc2) {
                return cc1.concat(cc2);
            });
        }

        function buildDocumentCommonContent(commonContent) {
            var $checkbox = components.checkboxes.imcmsCheckbox("<div>", {
                    name: commonContent.language.name.toLowerCase(), // fixme: or native name?
                    text: commonContent.language.name,
                    checked: commonContent.enabled ? "checked" : undefined
                }),
                $checkboxWrapper = components.checkboxes.checkboxContainer("<div>", [$checkbox]),
                $checkboxContainer = pageInfoInnerStructureBEM.buildBlock("<div>", [{"checkboxes": $checkboxWrapper}]),
                $pageTitle = components.texts.textBox("<div>", {
                    name: "title",
                    text: texts.title,
                    value: commonContent.headline
                }),
                $pageTitleContainer = pageInfoInnerStructureBEM.buildBlock("<div>", [{"text-box": $pageTitle}]),
                $menuText = components.texts.textArea("<div>", {
                    text: texts.menuText,
                    html: commonContent.menuText,
                    name: "menu-text"
                }),
                $menuTextContainer = pageInfoInnerStructureBEM.buildBlock("<div>", [{"text-area": $menuText}]),
                $linkToImage = chooseImage.container("<div>", {
                    id: "path-to-image",
                    name: "image",
                    value: commonContent.menuImageURL,
                    placeholder: texts.linkToImagePlaceholder,
                    "label-text": texts.linkToImage,
                    "button-text": texts.chooseImage,
                    click: function (selectedImage) {
                        $linkToImage.setValue(selectedImage ? selectedImage.path : "");
                    }
                }),
                $linkToImageContainer = pageInfoInnerStructureBEM.buildBlock("<div>", [{"choose-image": $linkToImage}]);

            tabData.commonContents = tabData.commonContents || [];

            tabData.commonContents.push({
                name: commonContent.language.name,
                checkbox: $checkbox,
                pageTitle: $pageTitle,
                menuText: $menuText,
                linkToImage: $linkToImage
            });

            return [$checkboxContainer, $pageTitleContainer, $menuTextContainer, $linkToImageContainer];
        }

        function buildCommonContentsContainer() {
            return tabData.$commonContentsContainer = $('<div>');
        }

        function buildSelectTargetForDocumentLink() {
            tabData.$showIn = components.selects.imcmsSelect("<div>", {
                id: "show-in",
                text: texts.showIn,
                name: "show-in"
            }, [{
                text: texts.sameFrame,
                "data-value": "_self"
            }, {
                text: texts.newWindow,
                "data-value": "_blank"
            }, {
                text: texts.replaceAll,
                "data-value": "_top"
            }]);

            return pageInfoInnerStructureBEM.buildBlock("<div>", [{"select": tabData.$showIn}]);
        }

        function buildDocumentAliasBlock() {
            tabData.$documentAlias = components.texts.textBox("<div>", {
                name: "alias",
                text: texts.alias,
                placeholder: texts.aliasPlaceholder
            });

            return pageInfoInnerStructureBEM.buildBlock("<div>", [
                {"text-box": tabData.$documentAlias}
            ]);
        }

        function buildBlockForMissingLangSetting() {
            var $languagesTitle = components.texts.titleText("<div>", texts.missingLangRuleTitle);

            tabData.$showDefaultLang = components.radios.imcmsRadio("<div>", {
                text: texts.showInDefault,
                name: "langSetting",
                value: "SHOW_IN_DEFAULT_LANGUAGE",
                checked: "checked" // default value
            });
            tabData.$doNotShow = components.radios.imcmsRadio("<div>", {
                text: texts.doNotShow,
                name: "langSetting",
                value: "DO_NOT_SHOW"
            });

            return pageInfoInnerStructureBEM.buildBlock("<div>", [
                {"title": $languagesTitle},
                {"item": tabData.$showDefaultLang},
                {"item": tabData.$doNotShow}
            ]);
        }

        var AppearanceTab = function (name) {
            WindowTab.call(this, name);
        };

        AppearanceTab.prototype = Object.create(WindowTab.prototype);

        AppearanceTab.prototype.isDocumentTypeSupported = function () {
            return true; // all supported
        };
        AppearanceTab.prototype.buildTab = function (index) {
            this.tabIndex = index;
            var tabElements = [
                buildCommonContentsContainer(),
                buildSelectTargetForDocumentLink(),
                buildDocumentAliasBlock(),
                buildBlockForMissingLangSetting()
            ];

            return tabFormBuilder.buildFormBlock(tabElements, index);
        };
        AppearanceTab.prototype.fillTabDataFromDocument = function (document) {
            tabData.$commonContentsContainer.prepend(buildCommonContents(document.commonContents));
            tabData.$showIn.selectValue(document.target);
            tabData.$documentAlias.setValue(document.alias);

            components.radios.group(tabData.$showDefaultLang, tabData.$doNotShow)
                .setCheckedValue(document.disabledLanguageShowMode);
        };
        AppearanceTab.prototype.saveData = function (documentDTO) {
            documentDTO.commonContents.forEach(function (docCommonContent) {
                tabData.commonContents.forEach(function (commonContent) {

                    if (docCommonContent.language.name !== commonContent.name) {
                        // I can't come up with better solution than double forEach
                        return;
                    }

                    docCommonContent.enabled = commonContent.checkbox.isChecked();
                    docCommonContent.headline = commonContent.pageTitle.getValue();
                    docCommonContent.menuText = commonContent.menuText.getValue();
                    docCommonContent.menuImageURL = commonContent.linkToImage.getValue();
                });
            });

            documentDTO.alias = tabData.$documentAlias.getValue();
            documentDTO.target = tabData.$showIn.getSelectedValue();

            documentDTO.disabledLanguageShowMode = components.radios
                .group(tabData.$showDefaultLang, tabData.$doNotShow)
                .getCheckedValue();

            return documentDTO;
        };
        AppearanceTab.prototype.clearTabData = function () {
            var emptyString = '';

            tabData.commonContents.forEach(function (commonContent, index) {
                commonContent.checkbox.setChecked(index === 0);//check only first
                commonContent.pageTitle.setValue(emptyString);
                commonContent.menuText.setValue(emptyString);
                commonContent.linkToImage.setValue(emptyString);
            });

            tabData.$commonContentsContainer.empty();

            tabData.$showIn.selectFirst();
            tabData.$documentAlias.setValue(emptyString);
            tabData.$showDefaultLang.setChecked(true); //default value
        };

        return new AppearanceTab(texts.name);
    }
);
<|endoftext|>


<commit_before>const scripts = require('../scripts')
const google = require('googleapis')
const sheet = google.sheets('v4')

module.exports = (()=>{

  filterMonthlyEsEvents = (data) => {
    return data[1] == scripts.esMonths()
  }

  filterDailyEsEvents = (data) => {
    for (var i = 0; i < data.length; i++) {
      if (data[i][2] == scripts.curDay()) {
        return data[i]
      }
    }
  }

  getMonthlyActivities = (spreadsheet) => {
    return spreadsheet.filter(filterMonthlyEsEvents)
  }

  getDailyActivities = (rows) => {
    // We now have an array with activities for the current month.
    let monthlyActivities = getMonthlyActivities(rows)
    return filterDailyEsEvents(monthlyActivities)
  }

  getNonMatchingEvents = (list) => {
    // Make sure array is empty before adding to it
    nonMatchingEvents = []
    for (var i = 0; i < list.length; i++) {
      let row = list[i]
      if (row[1] | row[2] == "" || "N/A") {
        nonMatchingEvents.push(row)
      }
    }
    return nonMatchingEvents
  }

  gatherMessage = (rows) => {

    let cannon = getDailyActivities(rows)
    let result = []

    // Check if we have matching events for today
    if (cannon !== undefined) {

      for (var i = 0; i < cannon.length; i++) {
        result.push(cannon[i])
      }

      return messageStructure(result)

    }else {

      let nonMatching = getNonMatchingEvents(rows)
      let result = scripts.randomQuote(nonMatching)

      return messageStructure(result)

    }
  }

  messageStructure = (gather) => {
    let messageDetails = []
    let year, month, day, pageSource, infoOrigin, notes

    try {

      if (gather[0] == 'N/A' || '') {
        year = '__Unknown__'
      }else{
        year = gather[0]
      }

      messageDetails.push(year)

      if (gather[1] == 'N/A') {
        month = '__Unknown__'
      }else{
        month = gather[1]
      }

      messageDetails.push(month)

      if (gather[2] == 'N/A') {
        // If date is not present, we know this is a random event
        messageDetails.push('**__RANDOM ELDER SCROLLS CANON__**')
        day = '__Unknown__'
      }else{
        messageDetails.push('**__TODAY IN ELDER SCROLLS__**')
        day = gather[2]
      }

      messageDetails.push(day)

      // gather[3] is the event name
      messageDetails.push(gather[3])

      // if (gather[4]) {
      //   pageSource = gather[4]
      // }else{
      //   pageSource = 'No References Found'
      // }

      messageDetails.push(pageSource)

      if (gather[5]) {
        infoOrigin = gather[5]
      }else{
        infoOrigin = 'Information Origin Not Applicable'
      }

      messageDetails.push(infoOrigin)

      if (gather[6]) {
        notes = gather[6]
      }else {
        notes = 'No Notes Found on Selected Reference'
      }

      messageDetails.push(notes)

    } catch (e) {

      throw( new Error('There was a problem with the details of your results: ' + e) )

    } finally {

      return messageConstruct(messageDetails)

    }

  }

  messageConstruct = (rows) => {

    let message = []

      try {

        let content = rows[2] + '\n'+'\n' +
            '**Year:** ' + rows[0] + '\n' +
            '**Month:** '+ rows[1] + '\n' +
            '**Day:** ' + rows[3] + '\n' + '\n' +
            '*' + rows[4] + '*' + '\n' + '\n' +
            // '**Source:** ' + rows[5] + '\n' +
            '**Info Origin:** ' + rows[6] + '\n' +
            '**Notes:** ' + rows[7] + '\n'

        message.push(content)

        // Returns the messge that will be sent to chat window
        return message

      } catch (e) {

        throw( new Error('There was an error assembling your message: ' + e) )

      }

  }

  ElderScrolls = function(cb){
    sheet.spreadsheets.values.get({
    key: process.env.googleSheetsKey,
    spreadsheetId: process.env.elderScrollsSheetID,
    range: process.env.elderScrollsSheetRange
    }, function (err, response) {
      if (err) {
        return cb(new Error('Error accessing spreadsheet', err))
      } else {
        let rows = response.values
        if (rows.length == 0) {
          return cb(new Error("No rows found! Something happend to the spreadsheet!!"))
        } else {
          return cb(null, gatherMessage(rows))
        }
      }
    })
  }

  return {
    ElderScrolls: ElderScrolls
  }

})()<commit_msg>add check for multi-line notes.<commit_after>const scripts = require('../scripts')
const google = require('googleapis')
const sheet = google.sheets('v4')

module.exports = (()=>{

  filterMonthlyEsEvents = (data) => {
    return data[1] == scripts.esMonths()
  }

  filterDailyEsEvents = (data) => {
    for (var i = 0; i < data.length; i++) {
      if (data[i][2] == scripts.curDay()) {
        return data[i]
      }
    }
  }

  getMonthlyActivities = (spreadsheet) => {
    return spreadsheet.filter(filterMonthlyEsEvents)
  }

  getDailyActivities = (rows) => {
    // We now have an array with activities for the current month.
    let monthlyActivities = getMonthlyActivities(rows)
    return filterDailyEsEvents(monthlyActivities)
  }

  getNonMatchingEvents = (list) => {
    // Make sure array is empty before adding to it
    nonMatchingEvents = []
    for (var i = 0; i < list.length; i++) {
      let row = list[i]
      if (row[1] | row[2] == "" || "N/A") {
        nonMatchingEvents.push(row)
      }
    }
    return nonMatchingEvents
  }

  gatherMessage = (rows) => {

    let cannon = getDailyActivities(rows)
    let result = []

    // Check if we have matching events for today
    if (cannon !== undefined) {

      for (var i = 0; i < cannon.length; i++) {
        result.push(cannon[i])
      }

      return messageStructure(result)

    }else {

      let nonMatching = getNonMatchingEvents(rows)
      let result = scripts.randomQuote(nonMatching)

      return messageStructure(result)

    }
  }

  messageStructure = (gather) => {
    let messageDetails = []
    let year, month, day, pageSource, infoOrigin, notes

    try {

      if (gather[0] == 'N/A' || '') {
        year = '__Unknown__'
      }else{
        year = gather[0]
      }

      messageDetails.push(year)

      if (gather[1] == 'N/A') {
        month = '__Unknown__'
      }else{
        month = gather[1]
      }

      messageDetails.push(month)

      if (gather[2] == 'N/A') {
        // If date is not present, we know this is a random event
        messageDetails.push('**__RANDOM ELDER SCROLLS CANON__**')
        day = '__Unknown__'
      }else{
        messageDetails.push('**__TODAY IN ELDER SCROLLS__**')
        day = gather[2]
      }

      messageDetails.push(day)

      // gather[3] is the event name
      messageDetails.push(gather[3])

      // if (gather[4]) {
      //   pageSource = gather[4]
      // }else{
      //   pageSource = 'No References Found'
      // }

      messageDetails.push(pageSource)

      if (gather[5]) {
        infoOrigin = gather[5]
      }else{
        infoOrigin = 'Information Origin Not Applicable'
      }

      messageDetails.push(infoOrigin)

      if (gather[6]) {
        notes = gather[6]
      }else {
        notes = 'No Notes Found on Selected Reference'
      }

      messageDetails.push(notes)

    } catch (e) {

      throw( new Error('There was a problem with the details of your results: ' + e) )

    } finally {

      return messageConstruct(messageDetails)

    }

  }

  messageConstruct = (rows) => {

    let message = []

    if(rows[7].includes('- ')){
      rows[7].replace('- ', '\/n- ')
    }

      try {

        let content = rows[2] + '\n'+'\n' +
            '**Year:** ' + rows[0] + '\n' +
            '**Month:** '+ rows[1] + '\n' +
            '**Day:** ' + rows[3] + '\n' + '\n' +
            '*' + rows[4] + '*' + '\n' + '\n' +
            // '**Source:** ' + rows[5] + '\n' +
            '**Info Origin:** ' + rows[6] + '\n' +
            '**Notes:** ' + rows[7] + '\n'

        message.push(content)

        // Returns the messge that will be sent to chat window
        return message

      } catch (e) {

        throw( new Error('There was an error assembling your message: ' + e) )

      }

  }

  ElderScrolls = function(cb){
    sheet.spreadsheets.values.get({
    key: process.env.googleSheetsKey,
    spreadsheetId: process.env.elderScrollsSheetID,
    range: process.env.elderScrollsSheetRange
    }, function (err, response) {
      if (err) {
        return cb(new Error('Error accessing spreadsheet', err))
      } else {
        let rows = response.values
        if (rows.length == 0) {
          return cb(new Error("No rows found! Something happend to the spreadsheet!!"))
        } else {
          return cb(null, gatherMessage(rows))
        }
      }
    })
  }

  return {
    ElderScrolls: ElderScrolls
  }

})()<|endoftext|>


<commit_before>var Timeline = {
    init: function() {
        $('#bottom .timeline').mousedown(function(event) {
            Timeline.manualUpdate(event);
        });
        $('#bottom .timeline .slider .knob').mousedown(function(event) {
            Timeline.startDrag(event);
        });
        $(window).mouseup(function(event) {
            Timeline.stopDrag(event);
        });
        $(window).mousemove(function(event) {
            Timeline.onDrag(event);
        });
    },
    isDragging: false,
    updateHandle: null,
    startDrag: function(event) {
        Timeline.isDragging = true;
    },
    stopDrag: function(event) {
        if (Timeline.isDragging) {
            Timeline.stop();
            Timeline.isDragging = false;
            Timeline.manualUpdate(event);
            Timeline.start();
        }
    },
    onDrag: function(event) {
        if (!Timeline.isDragging) {
            return;
        }
        Timeline.manualUpdate(event);
    },
	start: function() {
		$('#bottom .timeline .knob').show();
		Timeline.updateHandle = setInterval(Timeline.update, 100);
	},
    manualUpdate: function(event) {
        var maxWidth = $('#bottom .timeline').width(),
            mouseX = event.pageX - $('#bottom .timeline .slider').offset().left,
            pos = null,
            len = player.getTotalPlaybackTime();

        if (mouseX < 0) {
            mouseX = 0;
        }
        if (mouseX > maxWidth) {
            mouseX = maxWidth;
        }
        pos = mouseX / maxWidth * len;

        $('#bottom .timeline-wrapper .position').html(Math.floor(pos/60)+':' + ((Math.round(pos%60) <10) ? '0' : '') + Math.round(pos%60));
        $('#bottom .timeline-wrapper .length').html(Math.floor(len/60)+':' + ((Math.round(len%60) <10) ? '0' : '') + Math.round(len%60));
		$('#bottom .timeline-wrapper .slider').width(pos/len*$('#bottom .timeline').width());

        if (!Timeline.isDragging) {
            player.seekTo(pos);
        }
    },
	update: function(percent) {
		if (Timeline.isDragging) {
            return;
        }
        var pos = player.getCurrentPlaybackTime(),
            len = player.getTotalPlaybackTime();

        if (pos && len) {
            $('#bottom .timeline-wrapper .position').html(Math.floor(pos/60)+':' + ((Math.round(pos%60) <10) ? '0' : '') + Math.round(pos%60));
            $('#bottom .timeline-wrapper .length').html(Math.floor(len/60)+':' + ((Math.round(len%60) <10) ? '0' : '') + Math.round(len%60));
            $('#bottom .timeline-wrapper .slider').width(pos/len*$('#bottom .timeline').width());
        } else {
            $('#bottom .timeline-wrapper .position').html('0:00');
            $('#bottom .timeline-wrapper .length').html('0:00');
            $('#bottom .timeline-wrapper .slider').width(0);
        }
	},

	stop: function() {
		if (Timeline.updateHandle) {
			clearInterval(Timeline.updateHandle);
			Timeline.updateHandle = null;
		}
	}
};
<commit_msg>Fix performance issue to do with Timeline.update<commit_after>var Timeline = {
    init: function() {
        $('#bottom .timeline').mousedown(function(event) {
            Timeline.manualUpdate(event);
        });
        $('#bottom .timeline .slider .knob').mousedown(function(event) {
            Timeline.startDrag(event);
        });
        $(window).mouseup(function(event) {
            Timeline.stopDrag(event);
        });
        $(window).mousemove(function(event) {
            Timeline.onDrag(event);
        });
    },
    isDragging: false,
    updateHandle: null,
    startDrag: function(event) {
        Timeline.isDragging = true;
    },
    stopDrag: function(event) {
        if (Timeline.isDragging) {
            Timeline.stop();
            Timeline.isDragging = false;
            Timeline.manualUpdate(event);
            Timeline.start();
        }
    },
    onDrag: function(event) {
        if (!Timeline.isDragging) {
            return;
        }
        Timeline.manualUpdate(event);
    },
	start: function() {
		$('#bottom .timeline .knob').show();
        if (Timeline.updateHandle === null) {
            Timeline.updateHandle = setInterval(Timeline.update, 100);
        }
	},
    manualUpdate: function(event) {
        var maxWidth = $('#bottom .timeline').width(),
            mouseX = event.pageX - $('#bottom .timeline .slider').offset().left,
            pos = null,
            len = player.getTotalPlaybackTime();

        if (mouseX < 0) {
            mouseX = 0;
        }
        if (mouseX > maxWidth) {
            mouseX = maxWidth;
        }
        pos = mouseX / maxWidth * len;

        $('#bottom .timeline-wrapper .position').html(Math.floor(pos/60)+':' + ((Math.round(pos%60) <10) ? '0' : '') + Math.round(pos%60));
        $('#bottom .timeline-wrapper .length').html(Math.floor(len/60)+':' + ((Math.round(len%60) <10) ? '0' : '') + Math.round(len%60));
		$('#bottom .timeline-wrapper .slider').width(pos/len*$('#bottom .timeline').width());

        if (!Timeline.isDragging) {
            player.seekTo(pos);
        }
    },
	update: function(percent) {
		if (Timeline.isDragging) {
            return;
        }
        var pos = player.getCurrentPlaybackTime(),
            len = player.getTotalPlaybackTime();

        if (pos && len) {
            $('#bottom .timeline-wrapper .position').html(Math.floor(pos/60)+':' + ((Math.round(pos%60) <10) ? '0' : '') + Math.round(pos%60));
            $('#bottom .timeline-wrapper .length').html(Math.floor(len/60)+':' + ((Math.round(len%60) <10) ? '0' : '') + Math.round(len%60));
            $('#bottom .timeline-wrapper .slider').width(pos/len*$('#bottom .timeline').width());
        } else {
            $('#bottom .timeline-wrapper .position').html('0:00');
            $('#bottom .timeline-wrapper .length').html('0:00');
            $('#bottom .timeline-wrapper .slider').width(0);
        }
	},

	stop: function() {
		if (Timeline.updateHandle) {
			clearInterval(Timeline.updateHandle);
			Timeline.updateHandle = null;
		}
	}
};
<|endoftext|>


<commit_before>var w = 720;
var h = 200;

void setup() {
  size(w, h);
  background(100,100,255);
  //noLoop();
}

void draw() {
  /*
  var brk = {
    "canPass":false,
    "draw": draw_brick(x,y);
  };

  var rug = {
    "canPass":true,
    "draw": draw_rug(x,y);
  };

  var map = [[brk, brk, brk, brk, brk, brk, brk, brk, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, brk, brk, brk, brk, brk, brk, brk, brk]];

  for(y = 0, y < map.length; y++) {
    for(x = 0, x < map[y].length; x++) {
      map[y][x].draw(x,y);
    }
  }
  */

  for(var y = 1; y < 11; y++) {
     draw_bg('water',1,y);
     draw_bg('swamp',2,y);
     draw_bg('grass',3,y);
     draw_bg('path',4,y);
     draw_bg('brick',5,y);
     draw_bg('brick',34,y);
     draw_bg('path',35,y);
     draw_bg('sand',36,y);
   }

  draw_bg('brick',6,1);
  draw_bg('brick',6,10);
    draw_bg('brick',33,1);
  draw_bg('brick',33,10);

    for(var y = 2; y < 10; y++) {
     draw_bg('floor',6,y);
     draw_bg('floor',33,y);
   }

  for(var x = 7; x < 33; x++) {
    draw_bg('brick',x,1);
    draw_bg('brick',x,10);
    draw_bg('floor',x,9);
    draw_bg('floor',x,2);
    for(var y = 3; y < 9; y++) {
      draw_bg('rug',x,y);
    }
  }

draw_PlayerFacingDown();
}

void reload() {
  redraw();
  updateStats();
}

void draw_PlayerFacingDown() {
  fill(player.skin[0],player.skin[1],player.skin[2]);
  //ears
  ellipse(player.x-6-player.face*2,player.y-12,4,4);
  ellipse(player.x+6+player.face*2,player.y-12,4,4);
   // head
  ellipse(player.x,player.y-10,12+player.face*4,20);

  // arms
  rect(player.x-10,player.y+8,4,4);
  rect(player.x+6,player.y+8,4,4);

  // tshirt
  fill(player.tColor[0],player.tColor[1],player.tColor[2]);
  rect(player.x-6,player.y,12,14);
  rect(player.x-10,player.y,4,8);
  rect(player.x+6,player.y,4,8);

  /*
  // hat
  rect(player.x-player.face-6, player.y-25, player.face*2+12, 5);
  fill(0,0,100);
  rect(player.x-player.face-6-3, player.y-21, 3, 2);
  */

  // tshirt logo
  fill(255,255,255);
  text(player.tshirt,player.x-3,player.y+10);

  // eye whites
  fill(255,255,255);
  ellipse(player.x-3-player.face,player.y-11,4,5);
  ellipse(player.x+3+player.face,player.y-11,4,5);

  //pupils
  fill(0,0,0);
  ellipse(player.x-3-player.face,player.y-11,1,1);
  ellipse(player.x+3+player.face,player.y-11,1,1);

  // mouth
  rect(player.x-3,player.y-5,6,1);

  // hair
  for(x = player.x-player.face*2; x <= player.x+player.face*2; x+=2) {
    noFill();
    stroke(player.hairColor[0],player.hairColor[1],player.hairColor[2]);
    ellipse(x,player.y-20,2,3);
  }
  stroke(0,0,0);

  //pants
  fill(player.pColor[0],player.pColor[1],player.pColor[2]);
  noStroke();
  rect(player.x-6,player.y+16,4,3);
  rect(player.x+2, player.y+16,4,3);
  rect(player.x-6,player.y+14,12,2);
  stroke(0,0,0);

  //shoes
  fill(0,0,0);
  rect(player.x-5,player.y+18,5,2);
  rect(player.x+2,player.y+18,5,2);
}

void draw_bg(bgo, x,y) {
  switch(bgo) {
    case 'brick':
      //stroke(255, 255, 255);
      x = 20*x-20;
      y = 20*y-20;
      for(var yi = y; yi < y+16; yi+=8) {
        //1st line
        stroke(30, 0, 0);
        fill(random(31,255),0,0);
        rect(x,yi,6,4);
        fill(random(31,225),0,0);
        rect(x+7,yi,7,4);
        stroke(30, 0, 0);
        fill(random(31,225),0,0);
        rect(x+14,yi,6,4);
        //2nd line
        noStroke();
        fill(random(31,255),0,0);
        rect(x,yi+4,4,4);
        fill(random(31,225),0,0);
        rect(x+16,yi+4,4,4);
        stroke(30, 0, 0);
        fill(random(31,225),0,0);
        rect(x+4,yi+4,7,4);
        fill(random(31,225),0,0);
        rect(x+10,yi+4,6,4);
      }
      //last line
      var yi = y+16;
      stroke(30, 0, 0);
      fill(random(31,255),0,0);
      rect(x,yi,6,4);
      fill(random(31,225),0,0);
      rect(x+7,yi,7,4);
      stroke(30, 0, 0);
      fill(random(31,225),0,0);
      rect(x+14,yi,6,4);
      rect(x+10,yi,6,4);
      noStroke();
      break;
    case 'rug':
        noStroke();
        x = 20*x-20;
        y = 20*y-20;
        for(var xi = x; xi < x+20; xi+=4) {
          for(var yi = y; yi < y+20; yi+=4) {
            noStroke();
            fill(random(175,200), 0, 0);
            rect(xi,yi,4,4);
          }
        }
        break;
    }
  case 'grass':
    noStroke();
    x = 20*x-20;
    y = 20*y-20;
    for(var xi = x; xi < x+20; xi+=4) {
        for(var yi = y; yi < y+20; yi+=4) {
            noStroke();
            fill(random(75,100),random(225,255),random(75,100));
            rect(xi,yi,4,4);
        }
    }
  break;
  case 'floor':
     //stroke(255, 255, 255);
    x = 20*x-20;
    y = 20*y-20;
    for(var xi = x; xi < x+16; xi+=8) {
        //1st line
        //stroke(51, 32, 2);
        fill(random(100,125),random(75,100),0);
        rect(xi,y,4,7);
        fill(random(100,125),random(75,100),0);
        rect(xi,y+7,4,7);
        //stroke(30, 0, 0);
        fill(random(100,125),random(75,100),0);
        rect(xi,y+14,4,6);
        //2nd line
        noStroke();
        fill(random(100,125),random(75,100),0);
        rect(xi+4,y,4,4);
        fill(random(100,125),random(75,100),0);
        rect(xi+4,y+16,4,4);
        //stroke(30, 0, 0);
        fill(random(100,125),random(75,100),0);
        rect(xi+4,y+4,4,7);
        fill(random(100,125),random(75,100),0);
        rect(xi+4,y+10,4,6);
    }
    //last line
    var xi = x+16;
    //stroke(51, 32, 2);
    fill(random(100,125),random(75,100),0);
    rect(xi,y,4,7);
    fill(random(100,125),random(75,100),0);
    rect(xi,y+7,4,7);
    //stroke(30, 0, 0);
    fill(random(100,125),random(75,100),0);
    rect(xi,y+14,4,6);
    break;
  case 'path':
    noStroke();
    x = 20*x-20;
    y = 20*y-20;
    for(var xi = x; xi < x+20; xi+=4) {
        for(var yi = y; yi < y+20; yi+=4) {
            noStroke();
            fill(random(175,200), random(175,200), 0);
            rect(xi,yi,4,4);
        }
    }
    break;
  case 'sand':
    noStroke();
    x = 20*x-20;
    y = 20*y-20;
    for(var xi = x; xi < x+20; xi+=4) {
        for(var yi = y; yi < y+20; yi+=4) {
            noStroke();
            //224, 166, 137
            fill(random(230,255), random(200,229), random(175,199));
            rect(xi,yi,4,4);
        }
    }
    break;
  case 'swamp':
    noStroke();
    x = 20*x-20;
    y = 20*y-20;
    for(var xi = x; xi < x+20; xi+=4) {
        for(var yi = y; yi < y+20; yi+=4) {
            noStroke();
            fill(0,random(50,200),random(50,150));
            rect(xi,yi,4,4);
        }
    }
    break;
  case 'water':
    noStroke();
    x = 20*x-20;
    y = 20*y-20;
    for(var xi = x; xi < x+20; xi+=4) {
        for(var yi = y; yi < y+20; yi+=4) {
            noStroke();
            fill(random(0,50),random(0,50),random(225,255));
            rect(xi,yi,4,4);
        }
    }
    break;
}

<commit_msg>Update drawgame.js<commit_after>var w = 720;
var h = 200;

void setup() {
  size(w, h);
  background(100,100,255);
  //noLoop();
}

void draw() {
  /*
  var brk = {
    "canPass":false,
    "draw": draw_brick(x,y);
  };

  var rug = {
    "canPass":true,
    "draw": draw_rug(x,y);
  };

  var map = [[brk, brk, brk, brk, brk, brk, brk, brk, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, rug, rug, rug, rug, rug, rug, rug, brk],
             [brk, brk, brk, brk, brk, brk, brk, brk, brk]];

  for(y = 0, y < map.length; y++) {
    for(x = 0, x < map[y].length; x++) {
      map[y][x].draw(x,y);
    }
  }
  */

  for(var y = 1; y < 11; y++) {
     draw_bg('water',1,y);
     draw_bg('swamp',2,y);
     draw_bg('grass',3,y);
     draw_bg('path',4,y);
     draw_bg('brick',5,y);
     draw_bg('brick',34,y);
     draw_bg('path',35,y);
     draw_bg('sand',36,y);
   }

  draw_bg('brick',6,1);
  draw_bg('brick',6,10);
    draw_bg('brick',33,1);
  draw_bg('brick',33,10);

    for(var y = 2; y < 10; y++) {
     draw_bg('floor',6,y);
     draw_bg('floor',33,y);
   }

  for(var x = 7; x < 33; x++) {
    draw_bg('brick',x,1);
    draw_bg('brick',x,10);
    draw_bg('floor',x,9);
    draw_bg('floor',x,2);
    for(var y = 3; y < 9; y++) {
      draw_bg('rug',x,y);
    }
  }

draw_PlayerFacingDown();
}

void reload() {
  redraw();
  updateStats();
}

void draw_PlayerFacingDown() {
  fill(player.skin[0],player.skin[1],player.skin[2]);
  //ears
  ellipse(player.x-6-player.face*2,player.y-12,4,4);
  ellipse(player.x+6+player.face*2,player.y-12,4,4);
   // head
  ellipse(player.x,player.y-10,12+player.face*4,20);

  // arms
  rect(player.x-10,player.y+8,4,4);
  rect(player.x+6,player.y+8,4,4);

  // tshirt
  fill(player.tColor[0],player.tColor[1],player.tColor[2]);
  rect(player.x-6,player.y,12,14);
  rect(player.x-10,player.y,4,8);
  rect(player.x+6,player.y,4,8);

  /*
  // hat
  rect(player.x-player.face-6, player.y-25, player.face*2+12, 5);
  fill(0,0,100);
  rect(player.x-player.face-6-3, player.y-21, 3, 2);
  */

  // tshirt logo
  fill(255,255,255);
  text(player.tshirt,player.x-3,player.y+10);

  // eye whites
  fill(255,255,255);
  ellipse(player.x-3-player.face,player.y-11,4,5);
  ellipse(player.x+3+player.face,player.y-11,4,5);

  //pupils
  fill(0,0,0);
  ellipse(player.x-3-player.face,player.y-11,1,1);
  ellipse(player.x+3+player.face,player.y-11,1,1);

  // mouth
  rect(player.x-3,player.y-5,6,1);

  // hair
  for(x = player.x-player.face*2; x <= player.x+player.face*2; x+=2) {
    noFill();
    stroke(player.hairColor[0],player.hairColor[1],player.hairColor[2]);
    ellipse(x,player.y-20,2,3);
  }
  stroke(0,0,0);

  //pants
  fill(player.pColor[0],player.pColor[1],player.pColor[2]);
  noStroke();
  rect(player.x-6,player.y+16,4,3);
  rect(player.x+2, player.y+16,4,3);
  rect(player.x-6,player.y+14,12,2);
  stroke(0,0,0);

  //shoes
  fill(0,0,0);
  rect(player.x-5,player.y+18,5,2);
  rect(player.x+2,player.y+18,5,2);
}

void draw_bg(bgo, x,y) {
  switch(bgo) {
    case 'brick':
      //stroke(255, 255, 255);
      x = 20*x-20;
      y = 20*y-20;
      for(var yi = y; yi < y+16; yi+=8) {
        //1st line
        stroke(30, 0, 0);
        fill(random(31,255),0,0);
        rect(x,yi,6,4);
        fill(random(31,225),0,0);
        rect(x+7,yi,7,4);
        stroke(30, 0, 0);
        fill(random(31,225),0,0);
        rect(x+14,yi,6,4);
        //2nd line
        noStroke();
        fill(random(31,255),0,0);
        rect(x,yi+4,4,4);
        fill(random(31,225),0,0);
        rect(x+16,yi+4,4,4);
        stroke(30, 0, 0);
        fill(random(31,225),0,0);
        rect(x+4,yi+4,7,4);
        fill(random(31,225),0,0);
        rect(x+10,yi+4,6,4);
      }
      //last line
      var yi = y+16;
      stroke(30, 0, 0);
      fill(random(31,255),0,0);
      rect(x,yi,6,4);
      fill(random(31,225),0,0);
      rect(x+7,yi,7,4);
      stroke(30, 0, 0);
      fill(random(31,225),0,0);
      rect(x+14,yi,6,4);
      rect(x+10,yi,6,4);
      noStroke();
      break;
    case 'rug':
        noStroke();
        x = 20*x-20;
        y = 20*y-20;
        for(var xi = x; xi < x+20; xi+=4) {
          for(var yi = y; yi < y+20; yi+=4) {
            noStroke();
            fill(random(175,200), 0, 0);
            rect(xi,yi,4,4);
          }
        }
        break;
    }
  case 'grass':
    noStroke();
    x = 20*x-20;
    y = 20*y-20;
    for(var xi = x; xi < x+20; xi+=4) {
        for(var yi = y; yi < y+20; yi+=4) {
            noStroke();
            fill(random(75,100),random(225,255),random(75,100));
            rect(xi,yi,4,4);
        }
    }
  break;
  case 'floor':
     //stroke(255, 255, 255);
    x = 20*x-20;
    y = 20*y-20;
    for(var xi = x; xi < x+16; xi+=8) {
        //1st line
        //stroke(51, 32, 2);
        fill(random(100,125),random(75,100),0);
        rect(xi,y,4,7);
        fill(random(100,125),random(75,100),0);
        rect(xi,y+7,4,7);
        //stroke(30, 0, 0);
        fill(random(100,125),random(75,100),0);
        rect(xi,y+14,4,6);
        //2nd line
        noStroke();
        fill(random(100,125),random(75,100),0);
        rect(xi+4,y,4,4);
        fill(random(100,125),random(75,100),0);
        rect(xi+4,y+16,4,4);
        //stroke(30, 0, 0);
        fill(random(100,125),random(75,100),0);
        rect(xi+4,y+4,4,7);
        fill(random(100,125),random(75,100),0);
        rect(xi+4,y+10,4,6);
    }
    //last line
    var xi = x+16;
    //stroke(51, 32, 2);
    fill(random(100,125),random(75,100),0);
    rect(xi,y,4,7);
    fill(random(100,125),random(75,100),0);
    rect(xi,y+7,4,7);
    //stroke(30, 0, 0);
    fill(random(100,125),random(75,100),0);
    rect(xi,y+14,4,6);
    break;
  case 'path':
    noStroke();
    x = 20*x-20;
    y = 20*y-20;
    for(var xi = x; xi < x+20; xi+=4) {
        for(var yi = y; yi < y+20; yi+=4) {
            noStroke();
            fill(random(175,200), random(175,200), 0);
            rect(xi,yi,4,4);
        }
    }
    break;
  case 'sand':
    noStroke();
    x = 20*x-20;
    y = 20*y-20;
    for(var xi = x; xi < x+20; xi+=4) {
        for(var yi = y; yi < y+20; yi+=4) {
            noStroke();
            //224, 166, 137
            fill(random(230,255), random(200,229), random(175,199));
            rect(xi,yi,4,4);
        }
    }
    break;
  case 'swamp':
    noStroke();
    x = 20*x-20;
    y = 20*y-20;
    for(var xi = x; xi < x+20; xi+=4) {
        for(var yi = y; yi < y+20; yi+=4) {
            noStroke();
            fill(0,random(50,200),random(50,150));
            rect(xi,yi,4,4);
        }
    }
    break;
  case 'water':
    noStroke();
    x = 20*x-20;
    y = 20*y-20;
    for(var xi = x; xi < x+20; xi+=4) {
        for(var yi = y; yi < y+20; yi+=4) {
            noStroke();
            fill(random(0,50),random(0,50),random(225,255));
            rect(xi,yi,4,4);
        }
    }
    break;
  }
}

<|endoftext|>


<commit_before>/*
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

/**
 * Get, cache and send feedback when connected.
 */
function Feedback() {}

Feedback.FEEDBACK_PREFIX = 'pending_feedback_';
Feedback.MAX_FEEDBACKS = 9;
Feedback.BUSY = false;

/**
 * Save feedback into the datastore.
 *
 * The datastore doesn't permit duplicates, so we use the FEEDBACK_PREFIX
 * followed by a number to store feedback. At most we allow 10 pending
 * feedbacks.
 *
 * @param deviceLat The latitude of the device, could be null.
 * @param deviceLng The longitude of the device, could be null.
 * @param code The currently displayed code, could be null.
 * @param address The currently displayed short code and address. Could be null.
 * @param compassFunction true if the compass looks ok, false otherwise.
 * @param lang The current language setting.
 * @param comment The comment from the user, truncated to 400 chars.
 */
Feedback.storeFeedback = function(deviceLat, deviceLng, code, address, mapFunction, compassFunction, lang, comment) {
  // Do we have the maximum pending feedbacks?
  if (DataStore.has(Feedback.FEEDBACK_PREFIX + Feedback.MAX_FEEDBACKS)) {
    return;
  }
  // Feedback format is a string concat of all the information.
  // We have to do this so we can store it in the data store or as a cookie
  // until we can send it.
  var feedback = '';
  feedback += deviceLat + ':' + deviceLng + ':';
  feedback += mapFunction + ':';
  feedback += compassFunction + ':';
  feedback += lang + ':';
  feedback += $(window).height() + ':' + $(window).width() + ':';
  feedback += code + ':';
  feedback += encodeURIComponent(address) + ':';
  feedback += encodeURIComponent(comment.substr(0, 1024)) + ':';
  for (var i = 0; i <= Feedback.MAX_FEEDBACKS; i++) {
    if (!DataStore.has(Feedback.FEEDBACK_PREFIX + i)) {
      DataStore.putString(Feedback.FEEDBACK_PREFIX + i, feedback);
      break;
    }
  }
  Feedback.sendFeedback();
};

/** Try to send a feedback item. If successful remove it from the datastore. */
Feedback.sendFeedback = function() {
  if (Feedback.FEEDBACK_BUSY) {
    return;
  }
  var hasPendingFeedback = false;
  for (var i = Feedback.MAX_FEEDBACKS; i >= 0; i--) {
    if (DataStore.has(Feedback.FEEDBACK_PREFIX + i)) {
      hasPendingFeedback = true;
      Feedback.FEEDBACK_BUSY = true;
      var fields = DataStore.get(Feedback.FEEDBACK_PREFIX + i).split(':');
      // Try to send it asynchronously with jquery AJAX.
      var request = $.ajax({
        url: 'http://feedback.plus.codes/feedback.php',
        type: 'POST',
        data: {
                lat: fields[0],
                lng: fields[1],
                map: fields[2],
                compass: fields[3],
                lang: fields[4],
                height: fields[5],
                width: fields[6],
                code: fields[7],
                address: decodeURIComponent(fields[8]),
                comment: decodeURIComponent(fields[9]),
                ua: navigator.userAgent},
        dataType: 'text',
        statusCode: {
          404: function() {
            DataStore.clear(Feedback.FEEDBACK_PREFIX + i);
          }
        }
      });

      request.done(function(msg) {
        Feedback.FEEDBACK_BUSY = false;
        DataStore.clear(Feedback.FEEDBACK_PREFIX + i);
      });

      request.fail(function(jqXHR, textStatus) {
        Feedback.FEEDBACK_BUSY = false;
      });
      break;
    }
  }
  if (hasPendingFeedback) {
    setTimeout(Feedback.sendFeedback, 10000);
  }
}
<commit_msg>Correct comment text<commit_after>/*
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

/**
 * Get, cache and send feedback when connected.
 */
function Feedback() {}

Feedback.FEEDBACK_PREFIX = 'pending_feedback_';
Feedback.MAX_FEEDBACKS = 9;
Feedback.BUSY = false;

/**
 * Save feedback into the datastore.
 *
 * The datastore doesn't permit duplicates, so we use the FEEDBACK_PREFIX
 * followed by a number to store feedback. At most we allow 10 pending
 * feedbacks.
 *
 * @param deviceLat The latitude of the device, could be null.
 * @param deviceLng The longitude of the device, could be null.
 * @param code The currently displayed code, could be null.
 * @param address The currently displayed short code and address. Could be null.
 * @param compassFunction true if the compass looks ok, false otherwise.
 * @param lang The current language setting.
 * @param comment The comment from the user, truncated to 1024 chars.
 */
Feedback.storeFeedback = function(deviceLat, deviceLng, code, address, mapFunction, compassFunction, lang, comment) {
  // Do we have the maximum pending feedbacks?
  if (DataStore.has(Feedback.FEEDBACK_PREFIX + Feedback.MAX_FEEDBACKS)) {
    return;
  }
  // Feedback format is a string concat of all the information.
  // We have to do this so we can store it in the data store or as a cookie
  // until we can send it.
  var feedback = '';
  feedback += deviceLat + ':' + deviceLng + ':';
  feedback += mapFunction + ':';
  feedback += compassFunction + ':';
  feedback += lang + ':';
  feedback += $(window).height() + ':' + $(window).width() + ':';
  feedback += code + ':';
  feedback += encodeURIComponent(address) + ':';
  feedback += encodeURIComponent(comment.substr(0, 1024)) + ':';
  for (var i = 0; i <= Feedback.MAX_FEEDBACKS; i++) {
    if (!DataStore.has(Feedback.FEEDBACK_PREFIX + i)) {
      DataStore.putString(Feedback.FEEDBACK_PREFIX + i, feedback);
      break;
    }
  }
  Feedback.sendFeedback();
};

/** Try to send a feedback item. If successful remove it from the datastore. */
Feedback.sendFeedback = function() {
  if (Feedback.FEEDBACK_BUSY) {
    return;
  }
  var hasPendingFeedback = false;
  for (var i = Feedback.MAX_FEEDBACKS; i >= 0; i--) {
    if (DataStore.has(Feedback.FEEDBACK_PREFIX + i)) {
      hasPendingFeedback = true;
      Feedback.FEEDBACK_BUSY = true;
      var fields = DataStore.get(Feedback.FEEDBACK_PREFIX + i).split(':');
      // Try to send it asynchronously with jquery AJAX.
      var request = $.ajax({
        url: 'http://feedback.plus.codes/feedback.php',
        type: 'POST',
        data: {
                lat: fields[0],
                lng: fields[1],
                map: fields[2],
                compass: fields[3],
                lang: fields[4],
                height: fields[5],
                width: fields[6],
                code: fields[7],
                address: decodeURIComponent(fields[8]),
                comment: decodeURIComponent(fields[9]),
                ua: navigator.userAgent},
        dataType: 'text',
        statusCode: {
          404: function() {
            DataStore.clear(Feedback.FEEDBACK_PREFIX + i);
          }
        }
      });

      request.done(function(msg) {
        Feedback.FEEDBACK_BUSY = false;
        DataStore.clear(Feedback.FEEDBACK_PREFIX + i);
      });

      request.fail(function(jqXHR, textStatus) {
        Feedback.FEEDBACK_BUSY = false;
      });
      break;
    }
  }
  if (hasPendingFeedback) {
    setTimeout(Feedback.sendFeedback, 10000);
  }
}
<|endoftext|>


<commit_before>/*
Copyright 2017 New Vector Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
 * Regenerates the translations base file by walking the source tree and
 * parsing each file with flow-parser. Emits a JSON file with the
 * translatable strings mapped to themselves in the order they appeared
 * in the files and grouped by the file they appeared in.
 *
 * Usage: node scripts/gen-i18n.js
 */
const fs = require('fs');
const path = require('path');

const walk = require('walk');

const flowParser = require('flow-parser');
const estreeWalker = require('estree-walker');

const TRANSLATIONS_FUNCS = ['_t', '_td', '_tJsx'];

const INPUT_TRANSLATIONS_FILE = 'src/i18n/strings/en_EN.json';

const FLOW_PARSER_OPTS = {
  esproposal_class_instance_fields: true,
  esproposal_class_static_fields: true,
  esproposal_decorators: true,
  esproposal_export_star_as: true,
  types: true,
};

function getObjectValue(obj, key) {
    for (const prop of obj.properties) {
        if (prop.key.type == 'Identifier' && prop.key.name == key) {
            return prop.value;
        }
    }
    return null;
}

function getTKey(arg) {
    if (arg.type == 'Literal') {
        return arg.value;
    } else if (arg.type == 'BinaryExpression' && arg.operator == '+') {
        return getTKey(arg.left) + getTKey(arg.right);
    } else if (arg.type == 'TemplateLiteral') {
        return arg.quasis.map((q) => {
            return q.value.raw;
        }).join('');
    }
    return null;
}

function getTranslations(file) {
    const tree = flowParser.parse(fs.readFileSync(file, { encoding: 'utf8' }), FLOW_PARSER_OPTS);

    const trs = new Set();

    estreeWalker.walk(tree, {
        enter: function(node, parent) {
            if (
                node.type == 'CallExpression' &&
                TRANSLATIONS_FUNCS.includes(node.callee.name)
            ) {
                const tKey = getTKey(node.arguments[0]);
                if (tKey === null) return;

                let isPlural = false;
                if (node.arguments.length > 1 && node.arguments[1].type == 'ObjectExpression') {
                    const countVal = getObjectValue(node.arguments[1], 'count');
                    if (countVal) {
                        isPlural = true;
                    }
                }

                if (isPlural) {
                    trs.add(tKey + "|other");
                    const plurals = enPlurals[tKey];
                    if (plurals) {
                        for (const pluralType of Object.keys(plurals)) {
                            trs.add(tKey + "|" + pluralType);
                        }
                    }
                } else {
                    trs.add(tKey);
                }
            }
        }
    });

    return trs;
}

// gather en_EN plural strings from the input translations file:
// the en_EN strings are all in the source with the exception of
// pluralised strings, which we need to pull in from elsewhere.
const inputTranslationsRaw = JSON.parse(fs.readFileSync(INPUT_TRANSLATIONS_FILE, { encoding: 'utf8' }));
const enPlurals = {};

for (const key of Object.keys(inputTranslationsRaw)) {
    const parts = key.split("|");
    if (parts.length > 1) {
        const plurals = enPlurals[parts[0]] || {};
        plurals[parts[1]] = inputTranslationsRaw[key];
        enPlurals[parts[0]] = plurals;
    }
}

const translatables = new Set();

walk.walkSync("src", {
    listeners: {
        file: function(root, fileStats, next) {
            if (!fileStats.name.endsWith('.js')) return;

            const fullPath = path.join(root, fileStats.name);
            const trs = getTranslations(fullPath);
            console.log(`${fullPath} (${trs.size} strings)`);
            for (const tr of trs.values()) {
                translatables.add(tr);
            }
        },
    }
});

const trObj = {};
for (const tr of translatables) {
    trObj[tr] = tr;
    if (tr.includes("|")) {
        trObj[tr] = inputTranslationsRaw[tr];
    }
}

fs.writeFileSync(
    "src/i18n/strings/en_EN.json",
    JSON.stringify(trObj, translatables.values(), 4) + "\n"
);

<commit_msg>Comment ignoring getTKey returning null<commit_after>/*
Copyright 2017 New Vector Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
 * Regenerates the translations base file by walking the source tree and
 * parsing each file with flow-parser. Emits a JSON file with the
 * translatable strings mapped to themselves in the order they appeared
 * in the files and grouped by the file they appeared in.
 *
 * Usage: node scripts/gen-i18n.js
 */
const fs = require('fs');
const path = require('path');

const walk = require('walk');

const flowParser = require('flow-parser');
const estreeWalker = require('estree-walker');

const TRANSLATIONS_FUNCS = ['_t', '_td', '_tJsx'];

const INPUT_TRANSLATIONS_FILE = 'src/i18n/strings/en_EN.json';

const FLOW_PARSER_OPTS = {
  esproposal_class_instance_fields: true,
  esproposal_class_static_fields: true,
  esproposal_decorators: true,
  esproposal_export_star_as: true,
  types: true,
};

function getObjectValue(obj, key) {
    for (const prop of obj.properties) {
        if (prop.key.type == 'Identifier' && prop.key.name == key) {
            return prop.value;
        }
    }
    return null;
}

function getTKey(arg) {
    if (arg.type == 'Literal') {
        return arg.value;
    } else if (arg.type == 'BinaryExpression' && arg.operator == '+') {
        return getTKey(arg.left) + getTKey(arg.right);
    } else if (arg.type == 'TemplateLiteral') {
        return arg.quasis.map((q) => {
            return q.value.raw;
        }).join('');
    }
    return null;
}

function getTranslations(file) {
    const tree = flowParser.parse(fs.readFileSync(file, { encoding: 'utf8' }), FLOW_PARSER_OPTS);

    const trs = new Set();

    estreeWalker.walk(tree, {
        enter: function(node, parent) {
            if (
                node.type == 'CallExpression' &&
                TRANSLATIONS_FUNCS.includes(node.callee.name)
            ) {
                const tKey = getTKey(node.arguments[0]);
                // This happens whenever we call _t with non-literals (ie. whenever we've
                // had to use a _td to compensate) so is expected.
                if (tKey === null) return;

                let isPlural = false;
                if (node.arguments.length > 1 && node.arguments[1].type == 'ObjectExpression') {
                    const countVal = getObjectValue(node.arguments[1], 'count');
                    if (countVal) {
                        isPlural = true;
                    }
                }

                if (isPlural) {
                    trs.add(tKey + "|other");
                    const plurals = enPlurals[tKey];
                    if (plurals) {
                        for (const pluralType of Object.keys(plurals)) {
                            trs.add(tKey + "|" + pluralType);
                        }
                    }
                } else {
                    trs.add(tKey);
                }
            }
        }
    });

    return trs;
}

// gather en_EN plural strings from the input translations file:
// the en_EN strings are all in the source with the exception of
// pluralised strings, which we need to pull in from elsewhere.
const inputTranslationsRaw = JSON.parse(fs.readFileSync(INPUT_TRANSLATIONS_FILE, { encoding: 'utf8' }));
const enPlurals = {};

for (const key of Object.keys(inputTranslationsRaw)) {
    const parts = key.split("|");
    if (parts.length > 1) {
        const plurals = enPlurals[parts[0]] || {};
        plurals[parts[1]] = inputTranslationsRaw[key];
        enPlurals[parts[0]] = plurals;
    }
}

const translatables = new Set();

walk.walkSync("src", {
    listeners: {
        file: function(root, fileStats, next) {
            if (!fileStats.name.endsWith('.js')) return;

            const fullPath = path.join(root, fileStats.name);
            const trs = getTranslations(fullPath);
            console.log(`${fullPath} (${trs.size} strings)`);
            for (const tr of trs.values()) {
                translatables.add(tr);
            }
        },
    }
});

const trObj = {};
for (const tr of translatables) {
    trObj[tr] = tr;
    if (tr.includes("|")) {
        trObj[tr] = inputTranslationsRaw[tr];
    }
}

fs.writeFileSync(
    "src/i18n/strings/en_EN.json",
    JSON.stringify(trObj, translatables.values(), 4) + "\n"
);

<|endoftext|>


<commit_before>
"use strict";

window.onload = function() {

// setup enviroment
var comPosition = document.getElementById("seascape");
var vista = comPosition.getContext("2d");

var lineColor = "DarkSlateGrey";

var noteHeadStyle = "2em monospace";
var noteHeadColor = "Olive";
var noteHeadDark = "\u25CF";

var noteStemStyle = "4em monospace";
var noteStemColor = "Olive";
var noteStemChar = "\x7C";

var noteFlagStyle = "3em monospace";
var noteFlagColor = "Olive";
var noteFlagChar = "\x2F";

var noteRestStyle = "2.5em monospace";
var noteRestColor = "Olive";
var noteRestChar = "\x37";

var bellClaveStyle = "4.75em monospace";
var bellClaveColor = "SaddleBrown";
var bellClaveChar = "\xBE";

var singleBarStyle = "4em monospace";
var singleBarColor = "DarkGrey";
var singleBarChar = "\u2502";

var doubleBarStyle = "4em monospace";
var doubleBarColor = "DarkGrey";
var doubleBarChar = "\u2551";

// demarcate canvas
  vista.beginPath();
  vista.moveTo(0, 0);
  vista.lineTo(0, 630);
  vista.lineTo(1120, 630);
  vista.lineTo(1120, 0);
  vista.closePath();
  vista.strokeStyle = "aquamarine";
  vista.stroke();

// upper staff

  vista.beginPath();
  vista.moveTo(214, 120);
  vista.lineTo(906, 120);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 135);
  vista.lineTo(906, 135);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 150);
  vista.lineTo(906, 150);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 165);
  vista.lineTo(906, 165);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 180);
  vista.lineTo(906, 180);
  vista.strokeStyle = lineColor;
  vista.stroke();

// lower staff

  vista.beginPath();
  vista.moveTo(214, 320);
  vista.lineTo(906, 320);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 335);
  vista.lineTo(906, 335);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 350);
  vista.lineTo(906, 350);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 365);
  vista.lineTo(906, 365);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 380);
  vista.lineTo(906, 380);
  vista.strokeStyle = lineColor;
  vista.stroke();

// upper note heads

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 290, 179);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 375, 172);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 460, 164);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 550, 156);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 640, 148);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 730, 141);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 820, 134);

// lower note heads

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 290, 379);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 375, 372);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 460, 364);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 550, 356);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 640, 348);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 730, 341);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 820, 334);

// upper note stems

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 278, 158);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 363, 152);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 448, 144);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 538, 187);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 628, 180);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 718, 173);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 808, 166);

// lower note stems

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 278, 358);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 363, 352);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 448, 344);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 538, 387);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 628, 380);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 718, 373);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 808, 366);

// upper note beam

  vista.beginPath();
  vista.moveTo(552, 195);
  vista.lineTo(552, 198);
  vista.lineTo(640, 191);
  vista.lineTo(640, 188);
  vista.closePath();
  vista.strokeStyle = noteStemColor;
  vista.stroke();
  vista.fillStyle = noteStemColor;
  vista.fill();

// lower note beam

  vista.beginPath();
  vista.moveTo(552, 395);
  vista.lineTo(552, 398);
  vista.lineTo(640, 391);
  vista.lineTo(640, 388);
  vista.closePath();
  vista.strokeStyle = noteStemColor;
  vista.stroke();
  vista.fillStyle = noteStemColor;
  vista.fill();

// upper flags

  vista.font = noteFlagStyle;
  vista.fillStyle = noteFlagColor;
  vista.fillText(noteFlagChar, 729, 180);

  vista.font = noteFlagStyle;
  vista.fillStyle = noteFlagColor;
  vista.fillText(noteFlagChar, 819, 173);

// lower flags

  vista.font = noteFlagStyle;
  vista.fillStyle = noteFlagColor;
  vista.fillText(noteFlagChar, 729, 380);

  vista.font = noteFlagStyle;
  vista.fillStyle = noteFlagColor;
  vista.fillText(noteFlagChar, 819, 373);

// upper eigth Rests

  vista.font = noteRestStyle;
  vista.fillStyle = noteRestColor;
  vista.fillText(noteRestChar, 685, 165);

  vista.font = noteRestStyle;
  vista.fillStyle = noteRestColor;
  vista.fillText(noteRestChar, 777, 165);

// lower eigth Rests

  vista.font = noteRestStyle;
  vista.fillStyle = noteRestColor;
  vista.fillText(noteRestChar, 685, 365);

  vista.font = noteRestStyle;
  vista.fillStyle = noteRestColor;
  vista.fillText(noteRestChar, 777, 365);

// upper time signature

  vista.font = bellClaveStyle;
  vista.fillStyle = bellClaveColor;
  vista.fillText(bellClaveChar, 220, 171);

// lower time signature

  vista.font = bellClaveStyle;
  vista.fillStyle = bellClaveColor;
  vista.fillText(bellClaveChar, 220, 371);

// upper measure bars

  vista.font = singleBarStyle;
  vista.fillStyle = singleBarColor;
  vista.fillText(singleBarChar, 200, 165);

  vista.font = singleBarStyle;
  vista.fillStyle = singleBarColor;
  vista.fillText(singleBarChar, 495, 165);

  vista.font = doubleBarStyle;
  vista.fillStyle = doubleBarColor;
  vista.fillText(doubleBarChar, 888, 165);

// lower measure bars

  vista.font = singleBarStyle;
  vista.fillStyle = singleBarColor;
  vista.fillText(singleBarChar, 200, 365);

  vista.font = singleBarStyle;
  vista.fillStyle = singleBarColor;
  vista.fillText(singleBarChar, 495, 365);

  vista.font = doubleBarStyle;
  vista.fillStyle = doubleBarColor;
  vista.fillText(doubleBarChar, 888, 365);

};

<commit_msg>150416.1<commit_after>
"use strict";

window.onload = function() {

// setup enviroment

var comPosition = document.getElementById("seascape");
var vista = comPosition.getContext("2d");

var lineColor = "DarkSlateGrey";

var noteHeadStyle = "2em monospace";
var noteHeadColor = "Olive";
var noteHeadDark = "\u25CF";

var noteStemStyle = "4em monospace";
var noteStemColor = "Olive";
var noteStemChar = "\x7C";

var noteFlagStyle = "3em monospace";
var noteFlagColor = "Olive";
var noteFlagChar = "\x2F";

var noteRestStyle = "2.5em monospace";
var noteRestColor = "Olive";
var noteRestChar = "\x37";

var bellClaveStyle = "4.75em monospace";
var bellClaveColor = "SaddleBrown";
var bellClaveChar = "\xBE";

var singleBarStyle = "4em monospace";
var singleBarColor = "DarkGrey";
var singleBarChar = "\u2502";

var doubleBarStyle = "4em monospace";
var doubleBarColor = "DarkGrey";
var doubleBarChar = "\u2551";

// demarcate canvas

  vista.beginPath();
  vista.moveTo(0, 0);
  vista.lineTo(0, 630);
  vista.lineTo(1120, 630);
  vista.lineTo(1120, 0);
  vista.closePath();
  vista.strokeStyle = "aquamarine";
  vista.stroke();

// upper staff

  vista.beginPath();
  vista.moveTo(214, 120);
  vista.lineTo(906, 120);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 135);
  vista.lineTo(906, 135);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 150);
  vista.lineTo(906, 150);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 165);
  vista.lineTo(906, 165);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 180);
  vista.lineTo(906, 180);
  vista.strokeStyle = lineColor;
  vista.stroke();

// lower staff

  vista.beginPath();
  vista.moveTo(214, 320);
  vista.lineTo(906, 320);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 335);
  vista.lineTo(906, 335);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 350);
  vista.lineTo(906, 350);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 365);
  vista.lineTo(906, 365);
  vista.strokeStyle = lineColor;
  vista.stroke();

  vista.beginPath();
  vista.moveTo(214, 380);
  vista.lineTo(906, 380);
  vista.strokeStyle = lineColor;
  vista.stroke();

// upper note heads

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 290, 179);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 375, 172);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 460, 164);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 550, 156);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 640, 148);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 730, 141);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 820, 134);

// lower note heads

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 290, 379);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 375, 372);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 460, 364);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 550, 356);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 640, 348);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 730, 341);

  vista.font = noteHeadStyle;
  vista.fillStyle = noteHeadColor;
  vista.fillText(noteHeadDark, 820, 334);

// upper note stems

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 278, 158);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 363, 152);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 448, 144);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 538, 187);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 628, 180);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 718, 173);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 808, 166);

// lower note stems

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 278, 358);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 363, 352);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 448, 344);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 538, 387);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 628, 380);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 718, 373);

  vista.font = noteStemStyle;
  vista.fillStyle = noteStemColor;
  vista.fillText(noteStemChar, 808, 366);

// upper note beam

  vista.beginPath();
  vista.moveTo(552, 195);
  vista.lineTo(552, 198);
  vista.lineTo(640, 191);
  vista.lineTo(640, 188);
  vista.closePath();
  vista.strokeStyle = noteStemColor;
  vista.stroke();
  vista.fillStyle = noteStemColor;
  vista.fill();

// lower note beam

  vista.beginPath();
  vista.moveTo(552, 395);
  vista.lineTo(552, 398);
  vista.lineTo(640, 391);
  vista.lineTo(640, 388);
  vista.closePath();
  vista.strokeStyle = noteStemColor;
  vista.stroke();
  vista.fillStyle = noteStemColor;
  vista.fill();

// upper flags

  vista.font = noteFlagStyle;
  vista.fillStyle = noteFlagColor;
  vista.fillText(noteFlagChar, 729, 180);

  vista.font = noteFlagStyle;
  vista.fillStyle = noteFlagColor;
  vista.fillText(noteFlagChar, 819, 173);

// lower flags

  vista.font = noteFlagStyle;
  vista.fillStyle = noteFlagColor;
  vista.fillText(noteFlagChar, 729, 380);

  vista.font = noteFlagStyle;
  vista.fillStyle = noteFlagColor;
  vista.fillText(noteFlagChar, 819, 373);

// upper eighth Rests

  vista.font = noteRestStyle;
  vista.fillStyle = noteRestColor;
  vista.fillText(noteRestChar, 685, 165);

  vista.font = noteRestStyle;
  vista.fillStyle = noteRestColor;
  vista.fillText(noteRestChar, 777, 165);

// lower eighth Rests

  vista.font = noteRestStyle;
  vista.fillStyle = noteRestColor;
  vista.fillText(noteRestChar, 685, 365);

  vista.font = noteRestStyle;
  vista.fillStyle = noteRestColor;
  vista.fillText(noteRestChar, 777, 365);

// upper time signature

  vista.font = bellClaveStyle;
  vista.fillStyle = bellClaveColor;
  vista.fillText(bellClaveChar, 220, 171);

// lower time signature

  vista.font = bellClaveStyle;
  vista.fillStyle = bellClaveColor;
  vista.fillText(bellClaveChar, 220, 371);

// upper measure bars

  vista.font = singleBarStyle;
  vista.fillStyle = singleBarColor;
  vista.fillText(singleBarChar, 200, 165);

  vista.font = singleBarStyle;
  vista.fillStyle = singleBarColor;
  vista.fillText(singleBarChar, 495, 165);

  vista.font = doubleBarStyle;
  vista.fillStyle = doubleBarColor;
  vista.fillText(doubleBarChar, 888, 165);

// lower measure bars

  vista.font = singleBarStyle;
  vista.fillStyle = singleBarColor;
  vista.fillText(singleBarChar, 200, 365);

  vista.font = singleBarStyle;
  vista.fillStyle = singleBarColor;
  vista.fillText(singleBarChar, 495, 365);

  vista.font = doubleBarStyle;
  vista.fillStyle = doubleBarColor;
  vista.fillText(doubleBarChar, 888, 365);

};

<|endoftext|>