<commit_before>/*global window, document, Ghost, $, _, Backbone, JST */
(function () {
    "use strict";

    Ghost.Views.Debug = Ghost.View.extend({
        events: {
            "click .settings-menu a": "handleMenuClick",
            "click .js-delete": "handleDeleteClick"
        },

        initialize: function () {
            // Disable import button and initizalize BlueImp file upload
            $('#startupload').prop('disabled', true);
            $('#importfile').fileupload({
                url: Ghost.paths.apiRoot + '/db/',
                limitMultiFileUploads: 1,
                replaceFileInput: false,
                headers: {
                    'X-CSRF-Token': $("meta[name='csrf-param']").attr('content')
                },
                dataType: 'json',
                add: function (e, data) {
                    /*jslint unparam:true*/
                    // unregister click event to preveng duplicate binding
                    $('#startupload').off("click");
                    data.context = $('#startupload').prop('disabled', false)
                        .click(function () {
                            $('#startupload').prop('disabled', true);
                            data.context = $('#startupload').text('Importing');
                            data.submit();
                            // unregister click event to allow different subsequent uploads
                            $('#startupload').off('click');
                        });
                },
                done: function (e, data) {
                    /*jslint unparam:true*/
                    $('#startupload').text('Import');
                    if (!data.result) {
                        throw new Error('No response received from server.');
                    }
                    if (!data.result.message) {
                        throw new Error('Unknown error');
                    }

                    Ghost.notifications.addItem({
                        type: 'success',
                        message: data.result.message,
                        status: 'passive'
                    });
                },
                error: function (response) {
                    $('#startupload').text('Import');
                    var responseJSON = response.responseJSON,
                        message = responseJSON && responseJSON.error ? responseJSON.error : 'unknown';
                    Ghost.notifications.addItem({
                        type: 'error',
                        message: ['A problem was encountered while importing new content to your blog. Error: ', message].join(''),
                        status: 'passive'
                    });
                }

            });

        },

        handleMenuClick: function (ev) {
            ev.preventDefault();

            var $target = $(ev.currentTarget);

            // Hide the current content
            this.$(".settings-content").hide();

            // Show the clicked content
            this.$("#debug-" + $target.attr("class")).show();

            return false;
        },

        handleDeleteClick: function (ev) {
            ev.preventDefault();
            this.addSubview(new Ghost.Views.Modal({
                model: {
                    options: {
                        close: true,
                        confirm: {
                            accept: {
                                func: function () {
                                    $.ajax({
                                        url: Ghost.paths.apiRoot + '/db/',
                                        type: 'DELETE',
                                        headers: {
                                            'X-CSRF-Token': $("meta[name='csrf-param']").attr('content')
                                        },
                                        success: function onSuccess(response) {
                                            if (!response) {
                                                throw new Error('No response received from server.');
                                            }
                                            if (!response.message) {
                                                throw new Error(response.detail || 'Unknown error');
                                            }

                                            Ghost.notifications.addItem({
                                                type: 'success',
                                                message: response.message,
                                                status: 'passive'
                                            });

                                        },
                                        error: function onError(response) {
                                            var responseText = JSON.parse(response.responseText),
                                                message = responseText && responseText.error ? responseText.error : 'unknown';
                                            Ghost.notifications.addItem({
                                                type: 'error',
                                                message: ['A problem was encountered while deleting content from your blog. Error: ', message].join(''),
                                                status: 'passive'
                                            });

                                        }
                                    });
                                },
                                text: "Yes"
                            },
                            reject: {
                                func: function () {
                                    return true;
                                },
                                text: "No"
                            }
                        },
                        type: "action",
                        style: ["wide", "centered"],
                        animation: 'fade'
                    },
                    content: {
                        template: 'blank',
                        title: 'Would you really like to delete all content from your blog?',
                        text: '
This is permanent! No backups, no restores, no magic undo button.
 We warned you, ok?
'
                    }
                }
            }));
        }
    });
}());<commit_msg>Refactor click handlers on upload button.<commit_after>/*global window, document, Ghost, $, _, Backbone, JST */
(function () {
    "use strict";

    Ghost.Views.Debug = Ghost.View.extend({
        events: {
            "click .settings-menu a": "handleMenuClick",
            "click #startupload": "handleUploadClick",
            "click .js-delete": "handleDeleteClick"
        },

        initialize: function () {
            var view = this;

            this.uploadButton = this.$el.find('#startupload');

            // Disable import button and initizalize BlueImp file upload
            this.uploadButton.prop('disabled', 'disabled');
            $('#importfile').fileupload({
                url: Ghost.paths.apiRoot + '/db/',
                limitMultiFileUploads: 1,
                replaceFileInput: false,
                headers: {
                    'X-CSRF-Token': $("meta[name='csrf-param']").attr('content')
                },
                dataType: 'json',
                add: function (e, data) {
                    /*jslint unparam:true*/

                    // Bind the upload data to the view, so it is
                    // available to the click handler, and enable the
                    // upload button.
                    view.fileUploadData = data;
                    data.context = view.uploadButton.removeProp('disabled');
                },
                done: function (e, data) {
                    /*jslint unparam:true*/
                    $('#startupload').text('Import');
                    if (!data.result) {
                        throw new Error('No response received from server.');
                    }
                    if (!data.result.message) {
                        throw new Error('Unknown error');
                    }

                    Ghost.notifications.addItem({
                        type: 'success',
                        message: data.result.message,
                        status: 'passive'
                    });
                },
                error: function (response) {
                    $('#startupload').text('Import');
                    var responseJSON = response.responseJSON,
                        message = responseJSON && responseJSON.error ? responseJSON.error : 'unknown';
                    Ghost.notifications.addItem({
                        type: 'error',
                        message: ['A problem was encountered while importing new content to your blog. Error: ', message].join(''),
                        status: 'passive'
                    });
                }

            });

        },

        handleMenuClick: function (ev) {
            ev.preventDefault();

            var $target = $(ev.currentTarget);

            // Hide the current content
            this.$(".settings-content").hide();

            // Show the clicked content
            this.$("#debug-" + $target.attr("class")).show();

            return false;
        },

        handleUploadClick: function (ev) {
            ev.preventDefault();

            if (!this.uploadButton.prop('disabled')) {
                this.fileUploadData.context = this.uploadButton.text('Importing');
                this.fileUploadData.submit();
            }

            // Prevent double post by disabling the button.
            this.uploadButton.prop('disabled', 'disabled');
        },

        handleDeleteClick: function (ev) {
            ev.preventDefault();
            this.addSubview(new Ghost.Views.Modal({
                model: {
                    options: {
                        close: true,
                        confirm: {
                            accept: {
                                func: function () {
                                    $.ajax({
                                        url: Ghost.paths.apiRoot + '/db/',
                                        type: 'DELETE',
                                        headers: {
                                            'X-CSRF-Token': $("meta[name='csrf-param']").attr('content')
                                        },
                                        success: function onSuccess(response) {
                                            if (!response) {
                                                throw new Error('No response received from server.');
                                            }
                                            if (!response.message) {
                                                throw new Error(response.detail || 'Unknown error');
                                            }

                                            Ghost.notifications.addItem({
                                                type: 'success',
                                                message: response.message,
                                                status: 'passive'
                                            });

                                        },
                                        error: function onError(response) {
                                            var responseText = JSON.parse(response.responseText),
                                                message = responseText && responseText.error ? responseText.error : 'unknown';
                                            Ghost.notifications.addItem({
                                                type: 'error',
                                                message: ['A problem was encountered while deleting content from your blog. Error: ', message].join(''),
                                                status: 'passive'
                                            });

                                        }
                                    });
                                },
                                text: "Yes"
                            },
                            reject: {
                                func: function () {
                                    return true;
                                },
                                text: "No"
                            }
                        },
                        type: "action",
                        style: ["wide", "centered"],
                        animation: 'fade'
                    },
                    content: {
                        template: 'blank',
                        title: 'Would you really like to delete all content from your blog?',
                        text: '
This is permanent! No backups, no restores, no magic undo button.
 We warned you, ok?
'
                    }
                }
            }));
        }
    });
}());
<|endoftext|>


<commit_before>import createTestHelpers from '../createTestHelpers';
const {expectTransform} = createTestHelpers([
  'class',
  'template',
  'arrow',
  'let',
  'default-param',
  'arg-spread',
  'obj-method',
  'obj-shorthand',
  'no-strict',
  'commonjs',
  'exponent',
]);

describe('Whitespace', () => {
  it('should not eliminate leading newlines', () => {
    expectTransform(
      '\n\nvar x = 42;'
    ).toReturn(
      '\n\nconst x = 42;'
    );
  });

  it('should not eliminate trailing newlines', () => {
    expectTransform(
      'var x = 42;\n\n'
    ).toReturn(
      'const x = 42;\n\n'
    );
  });

  it('ignores #! comment at the beginning of file', () => {
    expectTransform(
      '#!/usr/bin/env node\n' +
      'var x = 42;'
    ).toReturn(
      '#!/usr/bin/env node\n' +
      'const x = 42;'
    );
  });

  it('ignores #! comment almost at the beginning of file', () => {
    expectTransform(
      '\n' +
      '#!/usr/local/bin/node\n' +
      'if (true) {\n' +
      '  var foo = 42;\n' +
      '}'
    ).toReturn(
      '\n' +
      '#!/usr/local/bin/node\n' +
      'if (true) {\n' +
      '  const foo = 42;\n' +
      '}'
    );
  });

  it('should preserve #! comment using CRLF', () => {
    expectTransform(
      '#!/usr/bin/env node\r\n' +
      'var x = 42;'
    ).toReturn(
      '#!/usr/bin/env node\r\n' +
      'const x = 42;'
    );
  });

  it('should preserve CRLF line terminators', () => {
    expectTransform(
      'var f = function(x) {\r\n' +
      '  if (x > 10)\r\n' +
      '    return 42;\r\n' +
      '};'
    ).toReturn(
      'const f = x => {\r\n' +
      '  if (x > 10)\r\n' +
      '    return 42;\r\n' +
      '};'
    );
  });

  it('should use LF in case of mixed line terminators', () => {
    expectTransform(
      'var f = function(x) {\n' +
      '  if (x > 10)\r\n' +
      '    return 42;\r\n' +
      '};'
    ).toReturn(
      'const f = x => {\n' +
      '  if (x > 10)\n' +
      '    return 42;\n' +
      '};'
    );
  });
});
<commit_msg>Add test for preserving TABs<commit_after>import createTestHelpers from '../createTestHelpers';
const {expectTransform} = createTestHelpers([
  'class',
  'template',
  'arrow',
  'let',
  'default-param',
  'arg-spread',
  'obj-method',
  'obj-shorthand',
  'no-strict',
  'commonjs',
  'exponent',
]);

describe('Whitespace', () => {
  it('should not eliminate leading newlines', () => {
    expectTransform(
      '\n\nvar x = 42;'
    ).toReturn(
      '\n\nconst x = 42;'
    );
  });

  it('should not eliminate trailing newlines', () => {
    expectTransform(
      'var x = 42;\n\n'
    ).toReturn(
      'const x = 42;\n\n'
    );
  });

  it('ignores #! comment at the beginning of file', () => {
    expectTransform(
      '#!/usr/bin/env node\n' +
      'var x = 42;'
    ).toReturn(
      '#!/usr/bin/env node\n' +
      'const x = 42;'
    );
  });

  it('ignores #! comment almost at the beginning of file', () => {
    expectTransform(
      '\n' +
      '#!/usr/local/bin/node\n' +
      'if (true) {\n' +
      '  var foo = 42;\n' +
      '}'
    ).toReturn(
      '\n' +
      '#!/usr/local/bin/node\n' +
      'if (true) {\n' +
      '  const foo = 42;\n' +
      '}'
    );
  });

  it('should preserve #! comment using CRLF', () => {
    expectTransform(
      '#!/usr/bin/env node\r\n' +
      'var x = 42;'
    ).toReturn(
      '#!/usr/bin/env node\r\n' +
      'const x = 42;'
    );
  });

  it('should preserve CRLF line terminators', () => {
    expectTransform(
      'var f = function(x) {\r\n' +
      '  if (x > 10)\r\n' +
      '    return 42;\r\n' +
      '};'
    ).toReturn(
      'const f = x => {\r\n' +
      '  if (x > 10)\r\n' +
      '    return 42;\r\n' +
      '};'
    );
  });

  it('should use LF in case of mixed line terminators', () => {
    expectTransform(
      'var f = function(x) {\n' +
      '  if (x > 10)\r\n' +
      '    return 42;\r\n' +
      '};'
    ).toReturn(
      'const f = x => {\n' +
      '  if (x > 10)\n' +
      '    return 42;\n' +
      '};'
    );
  });

  it('should preserve TABs', () => {
    expectTransform(
      'var f = function(x) {\n' +
      '\tif (x > 10)\n' +
      '\t\tvar y = 42;\n' +
      '\t\treturn {x: x, y: y};\n' +
      '};'
    ).toReturn(
      'const f = x => {\n' +
      '\tif (x > 10)\n' +
      '\t\tconst y = 42;\n' +
      '\t\treturn {x, y};\n' +
      '};'
    );
  });
});
<|endoftext|>


<commit_before>Package.describe({
  name: 'daishi:blaze-google-maps',
  version: '0.0.4',
  summary: 'Easy Blaze template for Google Maps with reactivity',
  git: 'https://github.com/dai-shi/meteor-blaze-google-maps',
  documentation: 'README.md'
});

Package.onUse(function(api) {
  api.versionsFrom('1.2.0.1');
  api.use('ecmascript');
  api.use('templating');
  api.use('tracker');
  api.use('adelevie:meteor-lodash', 'client');
  api.addFiles(['blaze-google-maps.html', 'blaze-google-maps.js'], 'client');
  api.export('GoogleMaps', 'client');
});

Package.onTest(function(api) {
  api.use('ecmascript');
  api.use('templating');
  api.use('tinytest');
  api.use('daishi:blaze-google-maps', 'client');
  api.addFiles('blaze-google-maps-tests.js', 'client');
});
<commit_msg>fix package.js for publish<commit_after>Package.describe({
  name: 'daishi:blaze-google-maps',
  version: '0.0.4',
  summary: 'Easy Blaze template for Google Maps with reactivity',
  git: 'https://github.com/dai-shi/meteor-blaze-google-maps',
  documentation: 'README.md'
});

Package.onUse(function(api) {
  api.versionsFrom('1.2.0.1');
  api.use('ecmascript');
  api.use('templating');
  api.use('tracker');
  api.use('adelevie:meteor-lodash@3.10.1', 'client');
  api.addFiles(['blaze-google-maps.html', 'blaze-google-maps.js'], 'client');
  api.export('GoogleMaps', 'client');
});

Package.onTest(function(api) {
  api.use('ecmascript');
  api.use('templating');
  api.use('tinytest');
  api.use('daishi:blaze-google-maps', 'client');
  api.addFiles('blaze-google-maps-tests.js', 'client');
});
<|endoftext|>


<commit_before>Package.describe({
  name: 'dispatch:phoneformat.js',
  summary: 'phoneformat.js packaged for meteor',
  version: '1.2.3',
  git: 'https://github.com/DispatchMe/phoneformat.js.git',
});

Package.onUse(function (api) {
  api.use([
    'reactive-var@1.0.5', 'templating@1.1.1'
  ], 'web');

  api.addFiles([
    'google.phoneformat.js',
    'phoneformat.js',
    'country_code_map.js',
    'components/phone_input.html', 'components/phone_input.css', 'components/phone_input.js'
  ], 'web');

  api.use([
    'http@1.1.0'
  ], 'server');

  api.addFiles('server.js', 'server');

  api.export('Phoneformat');
});
<commit_msg>Bump version to 1.2.4<commit_after>Package.describe({
  name: 'dispatch:phoneformat.js',
  summary: 'phoneformat.js packaged for meteor',
  version: '1.2.4',
  git: 'https://github.com/DispatchMe/phoneformat.js.git',
});

Package.onUse(function (api) {
  api.use([
    'reactive-var@1.0.5', 'templating@1.1.1'
  ], 'web');

  api.addFiles([
    'google.phoneformat.js',
    'phoneformat.js',
    'country_code_map.js',
    'components/phone_input.html', 'components/phone_input.css', 'components/phone_input.js'
  ], 'web');

  api.use([
    'http@1.1.0'
  ], 'server');

  api.addFiles('server.js', 'server');

  api.export('Phoneformat');
});
<|endoftext|>


<commit_before>Package.describe({
    name: 'cultofcoders:redis-oplog',
    version: '2.0.4',
    // Brief, one-line summary of the package.
    summary: "Replacement for Meteor's MongoDB oplog implementation",
    // URL to the Git repository containing the source code for this package.
    git: 'https://github.com/cult-of-coders/redis-oplog',
    // By default, Meteor will default to using README.md for documentation.
    // To avoid submitting documentation, set this field to null.
    documentation: 'README.md'
});

Npm.depends({
    redis: '2.8.0',
    'deep-extend': '0.5.0',
    'lodash.clonedeep': '4.5.0'
});

Package.onUse(function(api) {
    api.versionsFrom('1.5.1');
    api.use([
        'underscore',
        'ecmascript',
        'ejson',
        'minimongo',
        'mongo',
        'random',
        'ddp-server',
        'diff-sequence',
        'id-map',
        'mongo-id',
        'tracker'
    ]);

    api.mainModule('redis-oplog.js', 'server');
    api.mainModule('redis-oplog.client.js', 'client');
});

Package.onTest(function(api) {
    api.use('cultofcoders:redis-oplog');

    // extensions
    api.use('aldeed:collection2@3.0.0');
    api.use('reywood:publish-composite@1.5.2');
    api.use('natestrauser:publish-performant-counts@0.1.2');
    api.use('socialize:user-presence@0.4.0');

    api.use('ecmascript');
    api.use('tracker');
    api.use('mongo');
    api.use('random');
    api.use('accounts-password');
    api.use('matb33:collection-hooks@0.8.4');
    api.use('alanning:roles@1.2.16');

    api.use(['meteortesting:mocha']);

    api.mainModule('testing/main.server.js', 'server');
    api.addFiles('testing/publishComposite/boot.js', 'server');
    api.addFiles('testing/optimistic-ui/boot.js', 'server');

    api.mainModule('testing/main.client.js', 'client');
});
<commit_msg>Bump to 2.0.5<commit_after>Package.describe({
    name: 'cultofcoders:redis-oplog',
    version: '2.0.5',
    // Brief, one-line summary of the package.
    summary: "Replacement for Meteor's MongoDB oplog implementation",
    // URL to the Git repository containing the source code for this package.
    git: 'https://github.com/cult-of-coders/redis-oplog',
    // By default, Meteor will default to using README.md for documentation.
    // To avoid submitting documentation, set this field to null.
    documentation: 'README.md'
});

Npm.depends({
    redis: '2.8.0',
    'deep-extend': '0.5.0',
    'lodash.clonedeep': '4.5.0'
});

Package.onUse(function(api) {
    api.versionsFrom('1.5.1');
    api.use([
        'underscore',
        'ecmascript',
        'ejson',
        'minimongo',
        'mongo',
        'random',
        'ddp-server',
        'diff-sequence',
        'id-map',
        'mongo-id',
        'tracker'
    ]);

    api.mainModule('redis-oplog.js', 'server');
    api.mainModule('redis-oplog.client.js', 'client');
});

Package.onTest(function(api) {
    api.use('cultofcoders:redis-oplog');

    // extensions
    api.use('aldeed:collection2@3.0.0');
    api.use('reywood:publish-composite@1.5.2');
    api.use('natestrauser:publish-performant-counts@0.1.2');
    api.use('socialize:user-presence@0.4.0');

    api.use('ecmascript');
    api.use('tracker');
    api.use('mongo');
    api.use('random');
    api.use('accounts-password');
    api.use('matb33:collection-hooks@0.8.4');
    api.use('alanning:roles@1.2.16');

    api.use(['meteortesting:mocha']);

    api.mainModule('testing/main.server.js', 'server');
    api.addFiles('testing/publishComposite/boot.js', 'server');
    api.addFiles('testing/optimistic-ui/boot.js', 'server');

    api.mainModule('testing/main.client.js', 'client');
});
<|endoftext|>


<commit_before>Package.describe({
  summary: "State of the art, out of the box Meteor pagination"
});

Package.on_use(function(api){
    api.use([
        "deps",
        "underscore",
        "coffeescript"
    ]);

    api.use([
        "templating",
        "handlebars",
        "spark",
        "session"
    ], "client");

    api.use([
        "deps",
        "underscore",
        "coffeescript",
        "check"
    ], "server");

    api.add_files([
        "paginate.coffee"
    ]);

    api.add_files([
        "client/templates.html",
        "client/main.coffee",
        "client/pages.css",
        "loader.gif"
    ], "client");
});

Package.on_test(function(api){
    api.use([
        "deps",
        "underscore",
        "coffeescript"
    ]);

    api.use([
        "templating",
        "handlebars",
        "spark",
        "session"
    ], "client");

    api.use([
        "deps",
        "underscore",
        "coffeescript",
        "check"
    ], "server");

    api.add_files([
        "tests.coffee"
    ]);

    api.add_files([
        "client/templates.html",
        "client/main.coffee",
        "client/pages.css",
        "loader.gif"
    ], "client");
});<commit_msg>spark replaced by ui<commit_after>Package.describe({
  summary: "State of the art, out of the box Meteor pagination"
});

Package.on_use(function(api){
    api.use([
        "deps",
        "underscore",
        "coffeescript"
    ]);

    api.use([
        "templating",
        "handlebars",
        "ui",
        "session"
    ], "client");

    api.use([
        "deps",
        "underscore",
        "coffeescript",
        "check"
    ], "server");

    api.add_files([
        "paginate.coffee"
    ]);

    api.add_files([
        "client/templates.html",
        "client/main.coffee",
        "client/pages.css",
        "loader.gif"
    ], "client");
});

Package.on_test(function(api){
    api.use([
        "deps",
        "underscore",
        "coffeescript"
    ]);

    api.use([
        "templating",
        "handlebars",
        "ui",
        "session"
    ], "client");

    api.use([
        "deps",
        "underscore",
        "coffeescript",
        "check"
    ], "server");

    api.add_files([
        "tests.coffee"
    ]);

    api.add_files([
        "client/templates.html",
        "client/main.coffee",
        "client/pages.css",
        "loader.gif"
    ], "client");
});
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////
// Simplyfying the usage of the browser's Worker object //
//////////////////////////////////////////////////////////

/*** Usage ***
var worker = lively.Worker.create(function() {
    // code inside this function is run in the worker context
    // when the worker is created
    setInterval(function() {
        self.postMessage('Worker is still running...');
    }, 1000);
    self.postMessage("Init done!");
});
worker.onMessage = function(evt) { show(evt.data); }
worker.postMessage({command: "eval", source: "3+4"}); // direct eval
worker.run(function(a, b) { postMessage(a+b); }, 1, 2); // run with arguments
(function() { worker.postMessage({command: "close"}); }).delay(5);
*/

lively.Worker = {
    isAvailable: !!window.Worker,
    pool: [],
    createInPool: function(customInitFunc, autoShutdownDelay/*ms*/) {
        var worker = this.create(customInitFunc);
        if (autoShutdownDelay) {
            var shutdownCode =  Strings.format("self.terminateIfNotBusyIn(%s);", autoShutdownDelay);
            worker.postMessage({command: 'eval', source: shutdownCode});
        }
        lively.Worker.pool.push(worker);
        lively.bindings.connect(worker, 'ready', lively.Worker.pool, 'remove', {
            updater: function($upd, readyState) { if (readyState) return; $upd(this.sourceObj); }});
        return worker;
    },
    create: function(customInitFunc) {
        // This code is triggered in the UI process directly after the
        // creation of the worker and sends the setup message to the worker
        // for initializing it.
        function init(worker) {
            var bootstrapFiles = LivelyLoader.bootstrapFiles.map(function(url) {
                return '/' + URL.create(url).relativePathFrom(URL.root); });
            worker.postMessage({
                command: 'setup',
                options: {
                    locationDirectory: JSLoader.currentDir(),
                    bootstrapFiles: bootstrapFiles,
                    codeBase: Config.codeBase,
                    rootPath: Config.rootPath
                }
            });
            worker.onmessage = function(evt) {
                if (evt.data.workerReady !== undefined) { worker.ready = !!evt.data.workerReady; return; }
                if (worker.onMessage) worker.onMessage(evt);
            }
            worker.errors = [];
            worker.onerror = function(evt) {
                console.error(evt);
                worker.errors.push(evt);
                if (worker.onError) worker.onError(evt);
            }
            worker.run = function(/*func, args*/) {
                var args = Array.from(arguments), doFunc = args.shift(),
                    code = Strings.format('(%s).apply(self, evt.data.args);', doFunc);
                this.basicRun({func: doFunc, args: args, useWhenDone: false});
            }
            worker.basicRun = function(options) {
                // options = {
                //   func: FUNCTION,
                //   args: ARRAY,  /*transported to worker and applied to func*/
                //   useWhenDone: BOOL
                /* If true, func receives a callback as first parameter that should be called
                   with two arguments: (error, result) to indicate worker func is done. */
                var func = options.func,
                    args = options.args,
                    passInWhenDoneCallback = !!options.useWhenDone,
                    codeTemplate = passInWhenDoneCallback ?
                        'self.isBusy = true;\n'
                      + 'function whenDone(err, result) { self.isBusy = false; postMessage({type: "runResponse", error: err, result: result}); }\n;'
                      + ';(%s).apply(self, [whenDone].concat(evt.data.args));' :
                        ';(%s).apply(self, evt.data.args);',
                    code = Strings.format(codeTemplate, func);
                worker.postMessage({command: 'eval', silent: true, source: code, args: args || []});
            }
        }

        // This code is run inside the worker and initializes it. It installs
        // a console.log method since since this is not available by default.
        function workerSetupCode() {
            // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
            // yoshiki and robert, 05/08/13: Inserted code that sets up the lively context
            // and globals of Lively:
            function initGlobals(options) {
                // 1) establish required objects
                Global = this;
                Global.window = Global;
                Global.lively={};
                Global.console = {
                    log: function() {}, error: function() {}, warn: function() {}
                }
                if (!Global.Config) Global.Config = {codeBase: options.codeBase, rootPath: options.rootPath};
                if (!Global.document) Global.document = {location: self.location, URL: self.location.toString()}
                var loadedURLs = [];
                Global.JSLoader = {
                    loadJs: function(url, callback) {
                        var match = url.match(/http:\/\/[^\/]+(\/?.*)/);
                        if (match && match[1]) url = match[1];
                        loadedURLs.push(url);
                        importScripts(url);
                    },
                    currentDir: function () { return options.locationDirectory; },
                    scriptInDOM: function(url) { return loadedURLs.indexOf(url) !== -1; },
                }
                Global.LivelyMigrationSupport = {
                    fixModuleName: function(n) { return n; },
                    addModuleRename: function(modName) {}
                }
                // 2) Load bootstrap files
                importScripts.apply(this, options.bootstrapFiles || []);
            }

            self.onmessage = function(evt) {
                if (evt.data.command == "eval") {
                    var result;
                    try { result = eval(evt.data.source); } catch (e) { result = e.stack || e; }
                    if (!evt.data.silent) postMessage({type: "evalResponse", value: String(result)});
                    return;
                } else if (evt.data.command == "close") {
                    self.close();
                    postMessage({type: "closed", workerReady: false});
                    return;
                }
                if (evt.data.command !== "setup") return;
                var options = evt.data.options || {};
                initGlobals(options);
                self.httpRequest = function (options) {
                    if (!options.url) {
                        console.log("Error, httpRequest needs url");
                        return;
                    }
                    var req = new XMLHttpRequest(),
                        method = options.method || 'GET';
                    function handleStateChange() {
                        if (req.readyState === 4) {
                            // req.status
                            options.done && options.done(req);
                        }
                    }
                    req.onreadystatechange = handleStateChange;
                    req.open(method, options.url);
                    req.send();
                }

                self.terminateIfNotBusyIn = function(ms) {
                    setTimeout(function() {
                        if (self.isBusy) { self.terminateIfNotBusyIn(ms); return; }
                        self.postMessage({type: "closed", workerReady: false});
                        self.close();
                    }, ms);
                }

                postMessage({workerReady: true});
            }
        }

        // temporarily create a file with the worker setup code
        // rk 05/08/13: tried out the blob object in Chrome as described in
        // http://www.html5rocks.com/en/tutorials/workers/basics/
        // but with no success
        var workerCode = Strings.format('(%s)();', String(workerSetupCode));
        if (customInitFunc) {
            var code = Strings.format('(%s)();', customInitFunc);
            workerCode += '\n' + code;
        }
        var codeFile = URL.root.getDirectory().withFilename('temp-worker-code.js').asWebResource();
        codeFile.put(workerCode);
        var worker = new Worker(codeFile.getURL().toString());
        lively.bindings.connect(worker, 'ready', codeFile, 'del');
        init(worker);
        return worker;
    }
}
<commit_msg>bootstrap: fix for nodejs<commit_after>//////////////////////////////////////////////////////////
// Simplyfying the usage of the browser's Worker object //
//////////////////////////////////////////////////////////

/*** Usage ***
var worker = lively.Worker.create(function() {
    // code inside this function is run in the worker context
    // when the worker is created
    setInterval(function() {
        self.postMessage('Worker is still running...');
    }, 1000);
    self.postMessage("Init done!");
});
worker.onMessage = function(evt) { show(evt.data); }
worker.postMessage({command: "eval", source: "3+4"}); // direct eval
worker.run(function(a, b) { postMessage(a+b); }, 1, 2); // run with arguments
(function() { worker.postMessage({command: "close"}); }).delay(5);
*/

lively.Worker = {
    isAvailable: !!Global.Worker,
    pool: [],
    createInPool: function(customInitFunc, autoShutdownDelay/*ms*/) {
        var worker = this.create(customInitFunc);
        if (autoShutdownDelay) {
            var shutdownCode =  Strings.format("self.terminateIfNotBusyIn(%s);", autoShutdownDelay);
            worker.postMessage({command: 'eval', source: shutdownCode});
        }
        lively.Worker.pool.push(worker);
        lively.bindings.connect(worker, 'ready', lively.Worker.pool, 'remove', {
            updater: function($upd, readyState) { if (readyState) return; $upd(this.sourceObj); }});
        return worker;
    },
    create: function(customInitFunc) {
        // This code is triggered in the UI process directly after the
        // creation of the worker and sends the setup message to the worker
        // for initializing it.
        function init(worker) {
            var bootstrapFiles = LivelyLoader.bootstrapFiles.map(function(url) {
                return '/' + URL.create(url).relativePathFrom(URL.root); });
            worker.postMessage({
                command: 'setup',
                options: {
                    locationDirectory: JSLoader.currentDir(),
                    bootstrapFiles: bootstrapFiles,
                    codeBase: Config.codeBase,
                    rootPath: Config.rootPath
                }
            });
            worker.onmessage = function(evt) {
                if (evt.data.workerReady !== undefined) { worker.ready = !!evt.data.workerReady; return; }
                if (worker.onMessage) worker.onMessage(evt);
            }
            worker.errors = [];
            worker.onerror = function(evt) {
                console.error(evt);
                worker.errors.push(evt);
                if (worker.onError) worker.onError(evt);
            }
            worker.run = function(/*func, args*/) {
                var args = Array.from(arguments), doFunc = args.shift(),
                    code = Strings.format('(%s).apply(self, evt.data.args);', doFunc);
                this.basicRun({func: doFunc, args: args, useWhenDone: false});
            }
            worker.basicRun = function(options) {
                // options = {
                //   func: FUNCTION,
                //   args: ARRAY,  /*transported to worker and applied to func*/
                //   useWhenDone: BOOL
                /* If true, func receives a callback as first parameter that should be called
                   with two arguments: (error, result) to indicate worker func is done. */
                var func = options.func,
                    args = options.args,
                    passInWhenDoneCallback = !!options.useWhenDone,
                    codeTemplate = passInWhenDoneCallback ?
                        'self.isBusy = true;\n'
                      + 'function whenDone(err, result) { self.isBusy = false; postMessage({type: "runResponse", error: err, result: result}); }\n;'
                      + ';(%s).apply(self, [whenDone].concat(evt.data.args));' :
                        ';(%s).apply(self, evt.data.args);',
                    code = Strings.format(codeTemplate, func);
                worker.postMessage({command: 'eval', silent: true, source: code, args: args || []});
            }
        }

        // This code is run inside the worker and initializes it. It installs
        // a console.log method since since this is not available by default.
        function workerSetupCode() {
            // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
            // yoshiki and robert, 05/08/13: Inserted code that sets up the lively context
            // and globals of Lively:
            function initGlobals(options) {
                // 1) establish required objects
                Global = this;
                Global.window = Global;
                Global.lively={};
                Global.console = {
                    log: function() {}, error: function() {}, warn: function() {}
                }
                if (!Global.Config) Global.Config = {codeBase: options.codeBase, rootPath: options.rootPath};
                if (!Global.document) Global.document = {location: self.location, URL: self.location.toString()}
                var loadedURLs = [];
                Global.JSLoader = {
                    loadJs: function(url, callback) {
                        var match = url.match(/http:\/\/[^\/]+(\/?.*)/);
                        if (match && match[1]) url = match[1];
                        loadedURLs.push(url);
                        importScripts(url);
                    },
                    currentDir: function () { return options.locationDirectory; },
                    scriptInDOM: function(url) { return loadedURLs.indexOf(url) !== -1; },
                }
                Global.LivelyMigrationSupport = {
                    fixModuleName: function(n) { return n; },
                    addModuleRename: function(modName) {}
                }
                // 2) Load bootstrap files
                importScripts.apply(this, options.bootstrapFiles || []);
            }

            self.onmessage = function(evt) {
                if (evt.data.command == "eval") {
                    var result;
                    try { result = eval(evt.data.source); } catch (e) { result = e.stack || e; }
                    if (!evt.data.silent) postMessage({type: "evalResponse", value: String(result)});
                    return;
                } else if (evt.data.command == "close") {
                    self.close();
                    postMessage({type: "closed", workerReady: false});
                    return;
                }
                if (evt.data.command !== "setup") return;
                var options = evt.data.options || {};
                initGlobals(options);
                self.httpRequest = function (options) {
                    if (!options.url) {
                        console.log("Error, httpRequest needs url");
                        return;
                    }
                    var req = new XMLHttpRequest(),
                        method = options.method || 'GET';
                    function handleStateChange() {
                        if (req.readyState === 4) {
                            // req.status
                            options.done && options.done(req);
                        }
                    }
                    req.onreadystatechange = handleStateChange;
                    req.open(method, options.url);
                    req.send();
                }

                self.terminateIfNotBusyIn = function(ms) {
                    setTimeout(function() {
                        if (self.isBusy) { self.terminateIfNotBusyIn(ms); return; }
                        self.postMessage({type: "closed", workerReady: false});
                        self.close();
                    }, ms);
                }

                postMessage({workerReady: true});
            }
        }

        // temporarily create a file with the worker setup code
        // rk 05/08/13: tried out the blob object in Chrome as described in
        // http://www.html5rocks.com/en/tutorials/workers/basics/
        // but with no success
        var workerCode = Strings.format('(%s)();', String(workerSetupCode));
        if (customInitFunc) {
            var code = Strings.format('(%s)();', customInitFunc);
            workerCode += '\n' + code;
        }
        var codeFile = URL.root.getDirectory().withFilename('temp-worker-code.js').asWebResource();
        codeFile.put(workerCode);
        var worker = new Worker(codeFile.getURL().toString());
        lively.bindings.connect(worker, 'ready', codeFile, 'del');
        init(worker);
        return worker;
    }
}
<|endoftext|>


<commit_before>/* global describe, it */
var expect = require('expect.js');

describe('runner~timings', function () {
    var Timings = require('../../lib/runner/timings');

    it('must expose a constructor', function () {
        expect(Timings).be.a('function');
    });

    it('must instantiate a new timings object', function () {
        expect(function () {
            var t = new Timings();
            expect(t instanceof Timings).be.ok();
        }).withArgs().to.not.throwError();
    });

    it('must instantiate a new timings object with initial records', function () {
        var t = new Timings({
            labelOne: 1468345625321,
            labelTwo: 1368345625321
        });

        expect(t).have.property('labelOne', 1468345625321);
        expect(t).have.property('labelTwo', 1368345625321);
    });

    it('can use the create method to initialise a new instance', function () {
        var t = Timings.create({
            labelOne: 1468345625321,
            labelTwo: 1368345625321
        });

        expect(t instanceof Timings).be.ok();
        expect(t).have.property('labelOne', 1468345625321);
        expect(t).have.property('labelTwo', 1368345625321);
    });

    it('casts non numeric initial records to numbers', function () {
        var t = new Timings({
            string: '1468345625321',
            float: 136834562532.29,
            date: new Date(1468345625321)
        });

        expect(t).have.property('string', 1468345625321);
        expect(t).have.property('float', 136834562532);
        expect(isNaN(t.date)).be.ok();
    });

    it('records the current date time with a label', function () {
        var t = new Timings();
        t.record('capture');
        expect(t).have.property('capture');
        expect(t.capture).be.a('number');
        expect(t.capture <= Date.now()).be.ok();
    });

    it('recording twice overrides old label', function (done) {
        var t = new Timings();

        t.record('capture');
        expect(t.capture <= Date.now()).be.ok();

        setTimeout(function () {
            var old = t.capture;
            expect(t.record('capture') >= old).be.ok();
            done();
        }, 5);
    });

    it('can be serialised to an object', function () {
        var t = new Timings({
            labelOne: 1468345625321,
            labelTwo: 1368345625321
        });

        expect(t.toObject()).eql({
            labelOne: 1468345625321,
            labelTwo: 1368345625321
        });
    });
});
<commit_msg>Update runner-timings to chai<commit_after>var expect = require('chai').expect;

describe('runner~timings', function () {
    var Timings = require('../../lib/runner/timings');

    it('should expose a constructor', function () {
        expect(Timings).to.be.a('function');
    });

    it('should instantiate a new timings object', function () {
        expect(function () {
            var t = new Timings();
            expect(t).to.be.an.instanceOf(Timings);
        }).to.not.throw();
    });

    it('should instantiate a new timings object with initial records', function () {
        var t = new Timings({
            labelOne: 1468345625321,
            labelTwo: 1368345625321
        });

        expect(t).to.deep.include({
            labelOne: 1468345625321,
            labelTwo: 1368345625321
        });
    });

    it('can use the create method to initialise a new instance', function () {
        var t = Timings.create({
            labelOne: 1468345625321,
            labelTwo: 1368345625321
        });

        expect(t).to.be.an.instanceof(Timings);
        expect(t).to.deep.include({
            labelOne: 1468345625321,
            labelTwo: 1368345625321
        });
    });

    it('casts non numeric initial records to numbers', function () {
        var t = new Timings({
            string: '1468345625321',
            float: 136834562532.29,
            date: new Date(1468345625321)
        });

        expect(t).to.deep.include({
            string: 1468345625321,
            float: 136834562532
        });
        expect(t).to.have.property('date').that.is.NaN;
    });

    it('records the current date time with a label', function () {
        var t = new Timings();
        t.record('capture');
        expect(t).to.have.property('capture').that.is.a('number');
        expect(t.capture <= Date.now()).to.be.ok;
    });

    it('recording twice overrides old label', function (done) {
        var t = new Timings();

        t.record('capture');
        expect(t.capture <= Date.now()).to.be.ok;

        setTimeout(function () {
            var old = t.capture;
            expect(t.record('capture') >= old).to.be.ok;
            done();
        }, 5);
    });

    it('can be serialised to an object', function () {
        var t = new Timings({
            labelOne: 1468345625321,
            labelTwo: 1368345625321
        });

        expect(t.toObject()).eql({
            labelOne: 1468345625321,
            labelTwo: 1368345625321
        });
    });
});
<|endoftext|>


<commit_before>/*globals hqDefine */
hqDefine('app_manager/js/app_manager.js', function () {
    'use strict';
    var module = eventize({});

    module.setCommcareVersion = function (version) {
        module.commcareVersion(version);
    };
    module.checkCommcareVersion = function (version) {
        return module.versionGE(module.commcareVersion(), version);
    };
    module.checkAreWeThereYet = function (version) {
        if (!module.latestCommcareVersion()) {
            // We don't know the latest version. Assume this version has arrived
            return true;
        } else {
            return module.versionGE(module.latestCommcareVersion(), version);
        }
    };
    module.versionGE = function (commcareVersion1, commcareVersion2) {
        function parse(version) {
            version = version.split('.');
            version = [parseInt(version[0]), parseInt(version[1])];
            return version;
        }
        commcareVersion1 = parse(commcareVersion1);
        commcareVersion2 = parse(commcareVersion2);
        if (commcareVersion1[0] > commcareVersion2[0]) {
            return true;
        } else if (commcareVersion1[0] === commcareVersion2[0]) {
            return commcareVersion1[1] >= commcareVersion2[1];

        } else {
            return false;
        }
    };
    module.init = function (args) {
        var appVersion = args.appVersion;
        module.commcareVersion = ko.observable();
        module.latestCommcareVersion = ko.observable();
        module.latestCommcareVersion(args.latestCommcareVersion);

        function updateDOM(update) {
            if (update.hasOwnProperty('app-version')) {
                appVersion = update['app-version'];
                $('.variable-version').text(appVersion);
            }
            if (update.hasOwnProperty('commcare-version')) {
                module.setCommcareVersion(update['commcare-version']);
            }
            if (module.fetchAndShowFormValidation) {
                module.fetchAndShowFormValidation();
            }
            COMMCAREHQ.updateDOM(update);
        }
        module.updateDOM = updateDOM;
        function getVar(name) {
            var r = $('input[name="' + name + '"]').first().val();
            return JSON.parse(r);
        }
        function resetIndexes($sortable) {
            var $sortables = $sortable.children.get(),
                i;
            for (i in $sortables) {
                if ($sortables.hasOwnProperty(i)) {
                    $($sortables[i]).data('index', i);
                }
            }
        }
        COMMCAREHQ.resetIndexes = resetIndexes;

        (function () {
            var $forms = $('.save-button-form');
            $forms.each(function () {
                var $form = $(this),
                    $buttonHolder = $form.find('.save-button-holder'),
                    button = COMMCAREHQ.SaveButton.initForm($form, {
                        unsavedMessage: gettext("You have unsaved changes"),
                        success: function (data) {
                            var key;
                            module.updateDOM(data.update);
                            for (key in data.corrections) {
                                if (data.corrections.hasOwnProperty(key)) {
                                    $form.find('[name="' + key + '"]').val(data.corrections[key]);
                                    $(document).trigger('correction', [key, data.corrections[key]]);
                                }
                            }
                            if (data.hasOwnProperty('case_list-show') &&
                                    module.hasOwnProperty('module_view')) {
                                var requires_case_details = hqImport('app_manager/js/detail-screen-config.js').state.requires_case_details;
                                requires_case_details(data['case_list-show']);
                            }
                        }
                    });
                button.ui.appendTo($buttonHolder);
                $buttonHolder.data('button', button);
            });
        }());

        $('#form-tabs').show();
        $('#forms').tab('show');

        $('.sortable .sort-action').addClass('sort-disabled');
        $('.drag_handle').addClass(COMMCAREHQ.icons.GRIP);
        $('.sortable').each(function () {
            var min_elem = $(this).hasClass('sortable-forms') ? 1 : 2;
            if ($(this).children().not('.sort-disabled').length < min_elem) {
                var $sortable = $(this);
                $('.drag_handle', this).each(function () {
                    if ($(this).closest('.sortable')[0] === $sortable[0]) {
                        $(this).removeClass('drag_handle').hide();
                    }
                });
            }
        });
        $('.sortable').each(function () {
            var $sortable = $(this);
            var sorting_forms = $sortable.hasClass('sortable-forms');
            var min_elem = $(this).hasClass('sortable-forms') ? 0 : 1;
            if ($(this).children().not('.sort-disabled').length > min_elem) {
                var init_dict = {
                    handle: '.drag_handle ',
                    items: ">*:not(.sort-disabled)",
                    update: function (e, ui) {
                        // because the event is triggered on both sortables when moving between one sortable list to
                        // another, do a check to see if this is the sortable list we're moving the item to
                        if ($sortable.find(ui.item).length < 1) {
                            return;
                        }

                        var to = -1,
                            from = -1,
                            to_module_id = parseInt($sortable.parents('.edit-module-li').data('index'), 10),
                            moving_to_new_module = false,
                            $form;

                        // if you're moving modules or moving forms within the same module, use this logic to find to and from
                        if (!sorting_forms || to_module_id === parseInt(ui.item.data('moduleid'), 10)) {
                            $(this).children().not('.sort-disabled').each(function (i) {
                                var index = parseInt($(this).data('index'), 10);
                                if (from !== -1) {
                                    if (from === index) {
                                        to = i;
                                        return false;
                                    }
                                }
                                if (i !== index) {
                                    if (i + 1 === index) {
                                        from = i;
                                    } else {
                                        to = i;
                                        from = index;
                                        return false;
                                    }
                                }
                            });
                        } else { //moving forms to a new submodule
                            $(this).children().not('.sort-disabled').each(function (i) {
                                if (parseInt($(this).data('moduleid'), 10) !== to_module_id) {
                                    moving_to_new_module = true;
                                    to = i;
                                    from = parseInt(ui.item.data('index'), 10);
                                    return false;
                                }
                            });
                        }

                        if (moving_to_new_module || to !== from) {
                            var from_module_id = parseInt(ui.item.data('moduleid'), 10);
                            $form = $(this).find('> .sort-action form');
                            $form.find('[name="from"], [name="to"]').remove();
                            $form.append('<input type="hidden" name="from" value="' + from.toString() + '" />');
                            $form.append('<input type="hidden" name="to"   value="' + to.toString()   + '" />');
                            if (sorting_forms) {
                                $form.append('<input type="hidden" name="from_module_id" value="' + from_module_id.toString() + '" />');
                                $form.append('<input type="hidden" name="to_module_id"   value="' + to_module_id.toString()   + '" />');
                            }

                            // disable sortable
                            $sortable.find('.drag_handle').css('color', 'transparent').removeClass('drag_handle');
                            $sortable.sortable('option', 'disabled', true);
                            if ($form.find('input[name="ajax"]').first().val() === "true") {
                                resetIndexes($sortable);
                                $.post($form.attr('action'), $form.serialize(), function (data) {
                                    module.updateDOM(JSON.parse(data).update);
                                    // re-enable sortable
                                    $sortable.sortable('option', 'disabled', false);
                                    $sortable.find('.drag_handle').show(1000);
                                });
                            } else {
                                $form.submit();
                            }
                        }
                    }
                };
                if (sorting_forms) {
                    init_dict["connectWith"] = '.sortable-forms';
                }
                $(this).sortable(init_dict);
            }
        });
        $('.sort-action').hide();

        $('select.applications').change(function () {
            var url = $(this).find('option:selected').attr('value');
            $(document).attr('location', url);
        });
        $('#langs select').change(function () {
            var lang = $(this).find('option:selected').attr('value');
            $(document).attr('location', window.location.href + (window.location.search ? '&' : '?') + 'lang=' + lang);
        });

        // Auto set input and select values according to the following 'div.immutable'
        $('select').each(function () {
            var val = $(this).next('div.immutable').text();
            if (val) {
                $(this).find('option').prop('selected', false);
                $(this).find('option[value="' + val + '"]').prop('selected', true);
            }
        });
        $('input[type="text"]').each(function () {
            var val = $(this).next('div.immutable').text();
            if (val) {
                $(this).attr('value', val);
            }
        });

        $('.new-module').on('click', function (e) {
            e.preventDefault();
            var dataType = $(this).data('type');
            $('#new-module-type').val(dataType);
            var form = $('#new-module-form');
            if (!form.data('clicked')) {
                form.data('clicked', 'true');
                $('.new-module-icon').removeClass().addClass("fa fa-refresh icon-spin");
                form.submit();
            }
        });

        if (COMMCAREHQ.toggleEnabled('APP_MANAGER_V2')) {
            $('.new-form').on('click', function (e) {
                e.preventDefault();
                var $a = $(this),
                    $form = $a.siblings("form"),
                    action = $a.data("case-action");
                $form.find("input[name='case_action']").val(action);
                $form.find("input[name='name']").val(action === "update" ? "Untitled Followup" : "Untitled Survey");
                if (!$form.data('clicked')) {
                    $form.data('clicked', 'true');
                    $a.find(".fa-plus").removeClass("fa-plus").addClass("fa fa-refresh icon-spin");
                    $form.submit();
                }
            });
        }

        module.commcareVersion.subscribe(function () {
            $('.commcare-feature').each(function () {
                // .attr() keeps zero intact in 2.10, data() doesn't
                var version = '' + $(this).attr('data-since-version') || '1.1',
                    upgradeMessage = $(''),
                    area = $(this);

                if (module.checkCommcareVersion(version)) {
                    area.find('upgrade-message').remove();
                    area.find('*:not(".hide")').show();
                } else if (!module.checkAreWeThereYet(version)) {
                    area.parent().hide();
                } else {
                    area.find('*').hide();
                    upgradeMessage.append(
                        $('').addClass('fa').addClass('fa-arrow-left')
                    ).append(
                        $('').text(' Requires CommCare ' + version)
                    ).appendTo(area);
                }
            });
        });
        module.setCommcareVersion(args.commcareVersion);
    };

    module.setupValidation = function (validation_url) {
        module.fetchAndShowFormValidation = function () {
            $.getJSON(validation_url, function (data) {
                $('#build_errors').html(data.error_html);
            });
        };
        if ($.cookie('suppress_build_errors')) {
            $.removeCookie('suppress_build_errors', { path: '/' });
        } else {
            module.fetchAndShowFormValidation();
        }
    };
    return module;
});
<commit_msg>add global of COMMCAREHQ to app_manager.js<commit_after>/* globals hqDefine COMMCAREHQ */
hqDefine('app_manager/js/app_manager.js', function () {
    'use strict';
    var module = eventize({});

    module.setCommcareVersion = function (version) {
        module.commcareVersion(version);
    };
    module.checkCommcareVersion = function (version) {
        return module.versionGE(module.commcareVersion(), version);
    };
    module.checkAreWeThereYet = function (version) {
        if (!module.latestCommcareVersion()) {
            // We don't know the latest version. Assume this version has arrived
            return true;
        } else {
            return module.versionGE(module.latestCommcareVersion(), version);
        }
    };
    module.versionGE = function (commcareVersion1, commcareVersion2) {
        function parse(version) {
            version = version.split('.');
            version = [parseInt(version[0]), parseInt(version[1])];
            return version;
        }
        commcareVersion1 = parse(commcareVersion1);
        commcareVersion2 = parse(commcareVersion2);
        if (commcareVersion1[0] > commcareVersion2[0]) {
            return true;
        } else if (commcareVersion1[0] === commcareVersion2[0]) {
            return commcareVersion1[1] >= commcareVersion2[1];

        } else {
            return false;
        }
    };
    module.init = function (args) {
        var appVersion = args.appVersion;
        module.commcareVersion = ko.observable();
        module.latestCommcareVersion = ko.observable();
        module.latestCommcareVersion(args.latestCommcareVersion);

        function updateDOM(update) {
            if (update.hasOwnProperty('app-version')) {
                appVersion = update['app-version'];
                $('.variable-version').text(appVersion);
            }
            if (update.hasOwnProperty('commcare-version')) {
                module.setCommcareVersion(update['commcare-version']);
            }
            if (module.fetchAndShowFormValidation) {
                module.fetchAndShowFormValidation();
            }
            COMMCAREHQ.updateDOM(update);
        }
        module.updateDOM = updateDOM;
        function getVar(name) {
            var r = $('input[name="' + name + '"]').first().val();
            return JSON.parse(r);
        }
        function resetIndexes($sortable) {
            var $sortables = $sortable.children.get(),
                i;
            for (i in $sortables) {
                if ($sortables.hasOwnProperty(i)) {
                    $($sortables[i]).data('index', i);
                }
            }
        }
        COMMCAREHQ.resetIndexes = resetIndexes;

        (function () {
            var $forms = $('.save-button-form');
            $forms.each(function () {
                var $form = $(this),
                    $buttonHolder = $form.find('.save-button-holder'),
                    button = COMMCAREHQ.SaveButton.initForm($form, {
                        unsavedMessage: gettext("You have unsaved changes"),
                        success: function (data) {
                            var key;
                            module.updateDOM(data.update);
                            for (key in data.corrections) {
                                if (data.corrections.hasOwnProperty(key)) {
                                    $form.find('[name="' + key + '"]').val(data.corrections[key]);
                                    $(document).trigger('correction', [key, data.corrections[key]]);
                                }
                            }
                            if (data.hasOwnProperty('case_list-show') &&
                                    module.hasOwnProperty('module_view')) {
                                var requires_case_details = hqImport('app_manager/js/detail-screen-config.js').state.requires_case_details;
                                requires_case_details(data['case_list-show']);
                            }
                        }
                    });
                button.ui.appendTo($buttonHolder);
                $buttonHolder.data('button', button);
            });
        }());

        $('#form-tabs').show();
        $('#forms').tab('show');

        $('.sortable .sort-action').addClass('sort-disabled');
        $('.drag_handle').addClass(COMMCAREHQ.icons.GRIP);
        $('.sortable').each(function () {
            var min_elem = $(this).hasClass('sortable-forms') ? 1 : 2;
            if ($(this).children().not('.sort-disabled').length < min_elem) {
                var $sortable = $(this);
                $('.drag_handle', this).each(function () {
                    if ($(this).closest('.sortable')[0] === $sortable[0]) {
                        $(this).removeClass('drag_handle').hide();
                    }
                });
            }
        });
        $('.sortable').each(function () {
            var $sortable = $(this);
            var sorting_forms = $sortable.hasClass('sortable-forms');
            var min_elem = $(this).hasClass('sortable-forms') ? 0 : 1;
            if ($(this).children().not('.sort-disabled').length > min_elem) {
                var init_dict = {
                    handle: '.drag_handle ',
                    items: ">*:not(.sort-disabled)",
                    update: function (e, ui) {
                        // because the event is triggered on both sortables when moving between one sortable list to
                        // another, do a check to see if this is the sortable list we're moving the item to
                        if ($sortable.find(ui.item).length < 1) {
                            return;
                        }

                        var to = -1,
                            from = -1,
                            to_module_id = parseInt($sortable.parents('.edit-module-li').data('index'), 10),
                            moving_to_new_module = false,
                            $form;

                        // if you're moving modules or moving forms within the same module, use this logic to find to and from
                        if (!sorting_forms || to_module_id === parseInt(ui.item.data('moduleid'), 10)) {
                            $(this).children().not('.sort-disabled').each(function (i) {
                                var index = parseInt($(this).data('index'), 10);
                                if (from !== -1) {
                                    if (from === index) {
                                        to = i;
                                        return false;
                                    }
                                }
                                if (i !== index) {
                                    if (i + 1 === index) {
                                        from = i;
                                    } else {
                                        to = i;
                                        from = index;
                                        return false;
                                    }
                                }
                            });
                        } else { //moving forms to a new submodule
                            $(this).children().not('.sort-disabled').each(function (i) {
                                if (parseInt($(this).data('moduleid'), 10) !== to_module_id) {
                                    moving_to_new_module = true;
                                    to = i;
                                    from = parseInt(ui.item.data('index'), 10);
                                    return false;
                                }
                            });
                        }

                        if (moving_to_new_module || to !== from) {
                            var from_module_id = parseInt(ui.item.data('moduleid'), 10);
                            $form = $(this).find('> .sort-action form');
                            $form.find('[name="from"], [name="to"]').remove();
                            $form.append('<input type="hidden" name="from" value="' + from.toString() + '" />');
                            $form.append('<input type="hidden" name="to"   value="' + to.toString()   + '" />');
                            if (sorting_forms) {
                                $form.append('<input type="hidden" name="from_module_id" value="' + from_module_id.toString() + '" />');
                                $form.append('<input type="hidden" name="to_module_id"   value="' + to_module_id.toString()   + '" />');
                            }

                            // disable sortable
                            $sortable.find('.drag_handle').css('color', 'transparent').removeClass('drag_handle');
                            $sortable.sortable('option', 'disabled', true);
                            if ($form.find('input[name="ajax"]').first().val() === "true") {
                                resetIndexes($sortable);
                                $.post($form.attr('action'), $form.serialize(), function (data) {
                                    module.updateDOM(JSON.parse(data).update);
                                    // re-enable sortable
                                    $sortable.sortable('option', 'disabled', false);
                                    $sortable.find('.drag_handle').show(1000);
                                });
                            } else {
                                $form.submit();
                            }
                        }
                    }
                };
                if (sorting_forms) {
                    init_dict["connectWith"] = '.sortable-forms';
                }
                $(this).sortable(init_dict);
            }
        });
        $('.sort-action').hide();

        $('select.applications').change(function () {
            var url = $(this).find('option:selected').attr('value');
            $(document).attr('location', url);
        });
        $('#langs select').change(function () {
            var lang = $(this).find('option:selected').attr('value');
            $(document).attr('location', window.location.href + (window.location.search ? '&' : '?') + 'lang=' + lang);
        });

        // Auto set input and select values according to the following 'div.immutable'
        $('select').each(function () {
            var val = $(this).next('div.immutable').text();
            if (val) {
                $(this).find('option').prop('selected', false);
                $(this).find('option[value="' + val + '"]').prop('selected', true);
            }
        });
        $('input[type="text"]').each(function () {
            var val = $(this).next('div.immutable').text();
            if (val) {
                $(this).attr('value', val);
            }
        });

        $('.new-module').on('click', function (e) {
            e.preventDefault();
            var dataType = $(this).data('type');
            $('#new-module-type').val(dataType);
            var form = $('#new-module-form');
            if (!form.data('clicked')) {
                form.data('clicked', 'true');
                $('.new-module-icon').removeClass().addClass("fa fa-refresh icon-spin");
                form.submit();
            }
        });

        if (COMMCAREHQ.toggleEnabled('APP_MANAGER_V2')) {
            $('.new-form').on('click', function (e) {
                e.preventDefault();
                var $a = $(this),
                    $form = $a.siblings("form"),
                    action = $a.data("case-action");
                $form.find("input[name='case_action']").val(action);
                $form.find("input[name='name']").val(action === "update" ? "Untitled Followup" : "Untitled Survey");
                if (!$form.data('clicked')) {
                    $form.data('clicked', 'true');
                    $a.find(".fa-plus").removeClass("fa-plus").addClass("fa fa-refresh icon-spin");
                    $form.submit();
                }
            });
        }

        module.commcareVersion.subscribe(function () {
            $('.commcare-feature').each(function () {
                // .attr() keeps zero intact in 2.10, data() doesn't
                var version = '' + $(this).attr('data-since-version') || '1.1',
                    upgradeMessage = $(''),
                    area = $(this);

                if (module.checkCommcareVersion(version)) {
                    area.find('upgrade-message').remove();
                    area.find('*:not(".hide")').show();
                } else if (!module.checkAreWeThereYet(version)) {
                    area.parent().hide();
                } else {
                    area.find('*').hide();
                    upgradeMessage.append(
                        $('').addClass('fa').addClass('fa-arrow-left')
                    ).append(
                        $('').text(' Requires CommCare ' + version)
                    ).appendTo(area);
                }
            });
        });
        module.setCommcareVersion(args.commcareVersion);
    };

    module.setupValidation = function (validation_url) {
        module.fetchAndShowFormValidation = function () {
            $.getJSON(validation_url, function (data) {
                $('#build_errors').html(data.error_html);
            });
        };
        if ($.cookie('suppress_build_errors')) {
            $.removeCookie('suppress_build_errors', { path: '/' });
        } else {
            module.fetchAndShowFormValidation();
        }
    };
    return module;
});
<|endoftext|>


<commit_before>"use strict";

const glob = require('glob'),
  fs = require('fs-promise'),
  lh = require('./lineage_hunter'),
  Pattern = require('./object_factory').Pattern,
  plutils = require('./utilities'),
  path = require('path');

function promiseGlobMatches(currentPattern, paths) {
  //look for a pseudo pattern by checking if there is a file containing same
  //name, with ~ in it, ending in .json
  const needle = currentPattern.subdir + '/' + currentPattern.fileName + '~*.json';

  return new Promise((resolve, reject) => {
    glob(
      needle,
      { cwd: paths.source.patterns, debug: false, nodir: true },
      function (err, matches) {
        if (err) { reject(err); }
        resolve(matches);
      }
    );
  });
}

function createPseudoPatternObject(variantFileData, pattern, pseudoPattern, patternlab) {
  const variantName = pseudoPattern.substring(pseudoPattern.indexOf('~') + 1).split('.')[0];
  const variantFilePath = path.join(pattern.subdir, pattern.fileName + '~' + variantName + '.json');

  return Pattern.create(variantFilePath, variantFileData, {
    //use the same template as the non-variant
    template: pattern.template,
    fileExtension: pattern.fileExtension,
    extendedTemplate: pattern.extendedTemplate,
    isPseudoPattern: true,
    basePattern: pattern,
    stylePartials: pattern.stylePartials,
    parameteredPartials: pattern.parameteredPartials,

    // use the same template engine as the non-variant
    engine: pattern.engine
  }, patternlab);
}

function processPseudoPattern(patternVariant, patternlab) {
  const pa = require('./pattern_assembler');
  const pattern_assembler = new pa();
  const lineage_hunter = new lh();

  pattern_assembler.parse_pattern_markdown(patternVariant, patternlab);

  //find pattern lineage
  lineage_hunter.find_lineage(patternVariant, patternlab);

  //add to patternlab object so we can look these up later.
  pattern_assembler.addPattern(patternVariant, patternlab);
}

/**
 * The only public API in this module. This will search for pseudo
 * patterns and returns a Promise that resolves when it's done. It
 * doesn't return anything; processPseudoPattern() just updates the
 * global state.
 * @param {Object} currentPattern
 * @param {Object} patternlab
 * @returns {Promise}
 */
function findPseudoPatterns(currentPattern, patternlab) {
  /* eslint-disable no-shadow */
  const paths = patternlab.config.paths;

  return promiseGlobMatches(currentPattern, paths)
    .then(pseudoPatternsPaths => {
      return Promise.all(pseudoPatternsPaths.map(pseudoPatternPath => {
        if (patternlab.config.debug) {
          console.log('found pseudoPattern variant of ' + currentPattern.patternPartial);
        }

        // we return a Promise for each file descriptor to form an array
        // of Promises for Promise.all to resolve when they're all
        // complete
        return fs.readJSON(path.resolve(paths.source.patterns, pseudoPatternPath))
          .then(variantFileData => {
            const patternVariant = createPseudoPatternObject(
              plutils.mergeData(currentPattern.jsonFileData, variantFileData),
              currentPattern,
              pseudoPatternPath,
              patternlab
            );

            //process the companion markdown file if it exists
            processPseudoPattern(patternVariant, patternlab);
          })
          .catch(plutils.reportError(
            'There was an error processing the pseudopattern' + pseudoPatternPath
          ));
      }));
    })
    .catch(plutils.reportError(
      'There was an error parsing pseudopattern JSON for ' + currentPattern.relPath
    ));
}

module.exports = {
  find_pseudopatterns: function (pattern, patternlab) {
    return findPseudoPatterns(pattern, patternlab);
  }
};
<commit_msg>get rid of some path and console string concatenations in favor of template literals<commit_after>"use strict";

const glob = require('glob'),
  fs = require('fs-promise'),
  lh = require('./lineage_hunter'),
  Pattern = require('./object_factory').Pattern,
  plutils = require('./utilities'),
  path = require('path');

function promiseGlobMatches(currentPattern, paths) {
  //look for a pseudo pattern by checking if there is a file containing same
  //name, with ~ in it, ending in .json
  const needle = path.join(currentPattern.subdir, `${currentPattern.fileName}~*.json`);

  return new Promise((resolve, reject) => {
    glob(
      needle,
      { cwd: paths.source.patterns, debug: false, nodir: true },
      function (err, matches) {
        if (err) { reject(err); }
        resolve(matches);
      }
    );
  });
}

function createPseudoPatternObject(variantFileData, pattern, pseudoPattern, patternlab) {
  const variantName = pseudoPattern.substring(pseudoPattern.indexOf('~') + 1).split('.')[0];
  const variantFilePath = path.join(pattern.subdir, `${pattern.fileName}~${variantName}.json`);

  return Pattern.create(variantFilePath, variantFileData, {
    //use the same template as the non-variant
    template: pattern.template,
    fileExtension: pattern.fileExtension,
    extendedTemplate: pattern.extendedTemplate,
    isPseudoPattern: true,
    basePattern: pattern,
    stylePartials: pattern.stylePartials,
    parameteredPartials: pattern.parameteredPartials,

    // use the same template engine as the non-variant
    engine: pattern.engine
  }, patternlab);
}

function processPseudoPattern(patternVariant, patternlab) {
  const pa = require('./pattern_assembler');
  const pattern_assembler = new pa();
  const lineage_hunter = new lh();

  pattern_assembler.parse_pattern_markdown(patternVariant, patternlab);

  //find pattern lineage
  lineage_hunter.find_lineage(patternVariant, patternlab);

  //add to patternlab object so we can look these up later.
  pattern_assembler.addPattern(patternVariant, patternlab);
}

/**
 * The only public API in this module. This will search for pseudo
 * patterns and returns a Promise that resolves when it's done. It
 * doesn't return anything; processPseudoPattern() just updates the
 * global state.
 * @param {Object} currentPattern
 * @param {Object} patternlab
 * @returns {Promise}
 */
function findPseudoPatterns(currentPattern, patternlab) {
  /* eslint-disable no-shadow */
  const paths = patternlab.config.paths;

  return promiseGlobMatches(currentPattern, paths)
    .then(pseudoPatternsPaths => {
      return Promise.all(pseudoPatternsPaths.map(pseudoPatternPath => {
        if (patternlab.config.debug) {
          console.log(`found pseudoPattern variant of ${currentPattern.patternPartial}`);
        }

        // we return a Promise for each file descriptor to form an array
        // of Promises for Promise.all to resolve when they're all
        // complete
        return fs.readJSON(path.resolve(paths.source.patterns, pseudoPatternPath))
          .then(variantFileData => {
            const patternVariant = createPseudoPatternObject(
              plutils.mergeData(currentPattern.jsonFileData, variantFileData),
              currentPattern,
              pseudoPatternPath,
              patternlab
            );

            //process the companion markdown file if it exists
            processPseudoPattern(patternVariant, patternlab);
          })
          .catch(plutils.reportError(
            `There was an error processing the pseudopattern $(pseudoPatternPath)`
          ));
      }));
    })
    .catch(plutils.reportError(
      `There was an error parsing pseudopattern JSON for ${currentPattern.relPath}`
    ));
}

module.exports = {
  find_pseudopatterns: function (pattern, patternlab) {
    return findPseudoPatterns(pattern, patternlab);
  }
};
<|endoftext|>


<commit_before>define([
  'd3',
  'moment',
  'underscore',
  'handlebars',
  'countries/models/IndicatorsModel',
  'countries/views/show/IndicatorView',
  'countries/views/indicators/LineChart',
  'text!countries/templates/indicators/LineGraphIndicator.handlebars'
], function(d3, moment, _, Handlebars, IndicatorsModel, IndicatorView, LineChart, tpl) {

  'use strict';

  var LineChartIndicator = IndicatorView.extend({

    template: Handlebars.compile(tpl),

    events: function() {
      return _.extend({}, IndicatorView.prototype.events, {});
    },

    initialize: function() {
      this.constructor.__super__.initialize.apply(this);
      this.model = IndicatorsModel;
    },

    _getData: function(ind) {
      // API call
      return this.model.getByParams(ind);
    },

    _drawGraph: function(values, graphicId) {
      //Fixear keys. No magic numbers
      var keys = { x: 'year', y: 'loss' };
      var parseDate = d3.time.format("%Y").parse;
      var type = function(d) {
        d[keys.x] = parseDate(d[keys.x]);
        d[keys.y] = +d[keys.y];
        return d;
      }
      var data = [];

      values.values.forEach(function(d) {
        if (Number(d.year !== 0)) {

          var n = d.year.toString();

          data.push({
            year: parseDate(n),
            loss: ~~d.value
          });
        }
      });

      var graphContainer = this.$el.find('#' + graphicId + '.content')[0];

      var lineChart = new LineChart({
        graphcId: graphicId,
        data: data,
        el: graphContainer,
        sizing: {top: 0, right: 0, bottom: 20, left: 0},
        innerPadding: { top: 0, right: 15, bottom: 0, left: 30 },
        keys: keys
      });

      lineChart.render();
    },

    //When we will implement tabs functionality, we can take the 'ind' value
    //from the tab element and give it to this function.
    render: function(ind, graphicId) {
      this.$el.html(this.template({ 'graphicId' : graphicId }));
      var self = this;

      //Here, we retrieve the data for the first option in tabs
      var data = this._getData(ind);

      $.when($, data).done(function() {
        self._drawGraph(data.responseJSON, graphicId);
      });

      return this;
    }

  });

  return LineChartIndicator;

});
<commit_msg>comment for Andres<commit_after>define([
  'd3',
  'moment',
  'underscore',
  'handlebars',
  'countries/models/IndicatorsModel',
  'countries/views/show/IndicatorView',
  'countries/views/indicators/LineChart',
  'text!countries/templates/indicators/LineGraphIndicator.handlebars'
], function(d3, moment, _, Handlebars, IndicatorsModel, IndicatorView, LineChart, tpl) {

  'use strict';

  var LineChartIndicator = IndicatorView.extend({

    template: Handlebars.compile(tpl),

    events: function() {
      return _.extend({}, IndicatorView.prototype.events, {});
    },

    initialize: function() {
      this.constructor.__super__.initialize.apply(this);
      this.model = IndicatorsModel;
    },

    _getData: function(ind) {
      // API call
      return this.model.getByParams(ind);
    },

    _drawGraph: function(values, graphicId) {
      //Fixear keys. No magic numbers
      var keys = { x: 'year', y: 'loss' };
      var parseDate = d3.time.format("%Y").parse;
      var type = function(d) {
        d[keys.x] = parseDate(d[keys.x]);
        d[keys.y] = +d[keys.y];
        return d;
      }
      var data = [];

      //Repasar parseo de datos.
      //Funcioan bien en iso = GUY
      values.values.forEach(function(d) {
        if (Number(d.year !== 0)) {

          var n = d.year.toString();

          data.push({
            year: parseDate(n),
            loss: ~~d.value
          });
        }
      });

      var graphContainer = this.$el.find('#' + graphicId + '.content')[0];

      var lineChart = new LineChart({
        graphcId: graphicId,
        data: data,
        el: graphContainer,
        sizing: {top: 0, right: 0, bottom: 20, left: 0},
        innerPadding: { top: 0, right: 15, bottom: 0, left: 30 },
        keys: keys
      });

      lineChart.render();
    },

    //When we will implement tabs functionality, we can take the 'ind' value
    //from the tab element and give it to this function.
    render: function(ind, graphicId) {
      this.$el.html(this.template({ 'graphicId' : graphicId }));
      var self = this;

      //Here, we retrieve the data for the first option in tabs
      var data = this._getData(ind);

      $.when($, data).done(function() {
        self._drawGraph(data.responseJSON, graphicId);
      });

      return this;
    }

  });

  return LineChartIndicator;

});
<|endoftext|>