<commit_before>/**
 * Created by wilso_000 on 4/9/2015.
 */
'use strict';

angular.module('core').controller('PictureController', ['$scope',
    function($scope) {
        $scope.pictures = [
            {
                filepath: 'modules/core/img/slider/1.jpg'
            },
            {
                filepath: 'modules/core/img/slider/2.jpg'
            }
        ];

        $scope.picturesbw = [
            {
                filepath: 'modules/core/img/slider/5.jpg'
            },
            {
                filepath: 'modules/core/img/slider/6.jpg'
            }
        ];

        $scope.picturesfaces = [
            {
                filepath: 'modules/core/img/slider/3.jpg'
            },
            {
                filepath: 'modules/core/img/slider/4.jpg'
            }
        ];

    }
]);
<commit_msg>bug fix<commit_after>/**
 * Created by wilso_000 on 4/9/2015.
 */
'use strict';

angular.module('core').controller('PictureController', ['$scope',
    function($scope) {
        $scope.pictures = [
            {
                filepath: 'modules/core/img/slider/1.jpg'
            },
            {
                filepath: 'modules/core/img/slider/2.jpg'
            }
        ];

        $scope.picturesbw = [
            {
                filepath: 'modules/core/img/slider/5.jpg'
            },
            {
                filepath: 'modules/core/img/slider/6.jpg'
            }
        ];

        $scope.picturesfaces = [
            {
                filepath: 'modules/core/img/slider/3.jpg'
            },
            {
                filepath: 'modules/core/img/slider/4.jpg'
            }
        ];

    }
]);
<|endoftext|>


<commit_before>var os = require("os");
var path = require("path");
var _ = require("lodash");
var Q = require("q");
var spawn = require('child_process').spawn;

var types = require("./types");

var config = {
    grepCmd: "grep",
    perlCmd: "perl",
    platform: os.platform()
};

var assembleCommand = function(options) {
    var include = "";
    var cmd = config.grepCmd + " -s -r --color=never --binary-files=without-match -n " +
        (!options.casesensitive ? "-i " : "") +
        (process.platform != "darwin" ? "-P " : "");

    if (options.pattern) { // handles grep peculiarities with --include
        if (options.pattern.split(",").length > 1)
            include = "{" + options.pattern + "}";
        else
            include = options.pattern;
    }
    else {
        include = (process.platform != "darwin" ? "\\" : "") + "*{" + types.PATTERN_EXT + "}";
    }

    if (options.maxresults)
        cmd += "-m " + parseInt(options.maxresults, 10);
    if (options.wholeword)
        cmd += " -w";

    var query = options.query;
    if (!query)
        return;

    // grep has a funny way of handling new lines (that is to say, it's non-existent)
    // if we're not doing a regex search, then we must split everything between the
    // new lines, escape the content, and then smush it back together; due to
    // new lines, this is also why we're  now passing -P as default to grep
    if (!options.replaceAll && !options.regexp) {
        var splitQuery = query.split("\\n");

        for (var q in splitQuery) {
            splitQuery[q] = types.grepEscapeRegExp(splitQuery[q]);
        }
        query = splitQuery.join("\\n");
    }

    query = query.replace(new RegExp("\\\'", "g"), "'\\''"); // ticks must be double escaped for BSD grep

    cmd += " " + types.PATTERN_EDIR + " " +
           " --include=" + include +
           " '" + query.replace(/-/g, "\\-") + "'" +
           " \"" + types.escapeShell(options.path) + "\"";

    if (options.replaceAll) {
        if (!options.replacement)
            options.replacement = "";

        if (options.regexp)
            query = types.escapeRegExp(query);

        // pipe the grep results into perl
        cmd += " -l | xargs " + config.perlCmd +
        // print the grep result to STDOUT (to arrange in parseSearchResult())
        " -pi -e 'print STDOUT \"$ARGV:$.:$_\""     +
        // do the actual replace
        " if s/" + query + "/" + options.replacement + "/mg" + ( options.casesensitive ? "" : "i" ) + ";'";
    }

    var args = ["-c", cmd];
    args.command = "bash";
    return args;
};

var search = function(root, args) {
    var d = Q.defer();
    var results = {};

    args = _.defaults(args || {}, {
        pattern: null,
        casesensitive: false,
        maxresults: null,
        wholeword: false,
        regexp: null,

        // replace
        replaceAll: false,
        replacement: null
    });

    if (!args.query) return Q.reject(new Error("Need a query to search for code"));

    var command = assembleCommand(_.extend({}, args, {
        path: root
    }));

    var proc = spawn(command.command, command);
    proc.stdout.on('data', function(data) {
        data = data.toString();

        _.each(data.toString().split("\n"), function(line) {
            var parts = line.split(":");
            if (parts.length < 3) return;

            var _path = path.normalize(parts[0]);

            results[_path] = results[_path] || [];
            results[_path].push({
                'line': parseInt(parts[1]),
                'content': parts[2]
            });
        });
    });

    proc.on('error', function(err) {
        d.reject(err)
    });
    proc.on('exit', function(code) {
        if (code !== 0) {
            d.reject(new Error("ack exited with code "+code));
        } else {
            d.resolve(results);
        }
    });

    return d.promise;
};

module.exports = search;<commit_msg>Improve results parsing in code search<commit_after>var os = require("os");
var path = require("path");
var _ = require("lodash");
var Q = require("q");
var spawn = require('child_process').spawn;

var types = require("./types");

var config = {
    grepCmd: "grep",
    perlCmd: "perl",
    platform: os.platform()
};

var assembleCommand = function(options) {
    var include = "";
    var cmd = config.grepCmd + " -s -r --color=never --binary-files=without-match -n " +
        (!options.casesensitive ? "-i " : "") +
        (process.platform != "darwin" ? "-P " : "");

    if (options.pattern) { // handles grep peculiarities with --include
        if (options.pattern.split(",").length > 1)
            include = "{" + options.pattern + "}";
        else
            include = options.pattern;
    }
    else {
        include = (process.platform != "darwin" ? "\\" : "") + "*{" + types.PATTERN_EXT + "}";
    }

    if (options.maxresults)
        cmd += "-m " + parseInt(options.maxresults, 10);
    if (options.wholeword)
        cmd += " -w";

    var query = options.query;
    if (!query)
        return;

    // grep has a funny way of handling new lines (that is to say, it's non-existent)
    // if we're not doing a regex search, then we must split everything between the
    // new lines, escape the content, and then smush it back together; due to
    // new lines, this is also why we're  now passing -P as default to grep
    if (!options.replaceAll && !options.regexp) {
        var splitQuery = query.split("\\n");

        for (var q in splitQuery) {
            splitQuery[q] = types.grepEscapeRegExp(splitQuery[q]);
        }
        query = splitQuery.join("\\n");
    }

    query = query.replace(new RegExp("\\\'", "g"), "'\\''"); // ticks must be double escaped for BSD grep

    cmd += " " + types.PATTERN_EDIR + " " +
           " --include=" + include +
           " '" + query.replace(/-/g, "\\-") + "'" +
           " \"" + types.escapeShell(options.path) + "\"";

    if (options.replaceAll) {
        if (!options.replacement)
            options.replacement = "";

        if (options.regexp)
            query = types.escapeRegExp(query);

        // pipe the grep results into perl
        cmd += " -l | xargs " + config.perlCmd +
        // print the grep result to STDOUT (to arrange in parseSearchResult())
        " -pi -e 'print STDOUT \"$ARGV:$.:$_\""     +
        // do the actual replace
        " if s/" + query + "/" + options.replacement + "/mg" + ( options.casesensitive ? "" : "i" ) + ";'";
    }

    var args = ["-c", cmd];
    args.command = "bash";
    return args;
};

var search = function(root, args) {
    var d = Q.defer(), prevfile = null;
    var results = {};

    args = _.defaults(args || {}, {
        pattern: null,
        casesensitive: false,
        maxresults: null,
        wholeword: false,
        regexp: null,

        // replace
        replaceAll: false,
        replacement: null
    });

    if (!args.query) return Q.reject(new Error("Need a query to search for code"));

    var command = assembleCommand(_.extend({}, args, {
        path: root
    }));

    var proc = spawn(command.command, command);
    proc.stdout.on('data', function(data) {
        data = data.toString();
        var lines = data.toString().split(/([\n\r]+)/g);

        for (var i = 0, l = lines.length; i < l; ++i) {
            var parts = lines[i].split(":");
            if (parts.length < 3) continue;

            var _path = path.normalize(parts.shift().replace(root, "").trimRight());
            var _line = parseInt(parts.shift());
            if (!_line) {
                if (prevfile) {
                    results[prevfile][results[prevfile].length - 1].content += "\n\r"+lines[i];
                }
                continue;
            }

            prevfile = _path;
            results[_path] = results[_path] || [];
            results[_path].push({
                'line': _line,
                'content': parts.join(":")
            });
        }
    });

    proc.on('error', function(err) {
        d.reject(err)
    });
    proc.on('exit', function(code) {
        if (code !== 0) {
            d.reject(new Error("ack exited with code "+code));
        } else {
            d.resolve(results);
        }
    });

    return d.promise;
};

module.exports = search;<|endoftext|>


<commit_before>const withOffline = require('next-offline')

module.exports = withOffline({
  workboxOpts: {
    swDest: process.env.NEXT_EXPORT
      ? 'service-worker.js'
      : 'static/service-worker.js',
  },
  experimental: {
    async rewrites() {
      return [
        {
          source: '/service-worker.js',
          destination: '/_next/static/service-worker.js',
        },
      ]
    },
  },
})
<commit_msg>fix with-next-offline example (#9900)<commit_after>const withOffline = require('next-offline')

module.exports = withOffline({
  workboxOpts: {
    swDest: process.env.NEXT_EXPORT
      ? 'service-worker.js'
      : 'static/service-worker.js',
    runtimeCaching: [
      {
        urlPattern: /^https?.*/,
        handler: 'NetworkFirst',
        options: {
          cacheName: 'offlineCache',
          expiration: {
            maxEntries: 200,
          },
        },
      },
    ],
  },
  experimental: {
    async rewrites() {
      return [
        {
          source: '/service-worker.js',
          destination: '/_next/static/service-worker.js',
        },
      ]
    },
  },
})
<|endoftext|>


<commit_before>'use strict';

const Feplet = require('feplet');
const fs = require('fs-extra');
const marked = require('marked');

module.exports = class {
  constructor(options, html) {
    this.options = options;
    this.conf = options.conf;
    this.rootDir = options.rootDir;
    this.utils = options.utils;

    this.html = html;
  }

  main() {
    return (req, res) => {
console.warn(req)
      fs.readFile(`${this.rootDir}/README.md`, this.conf.enc, (err, dat) => {
        const successMsg = 'Installation success!';
        const ts = this.utils.deepGet(req, 'query.ts') ? req.query.ts : '';
        const successSimple = `<!DOCTYPE html><meta charset="utf-8">
${successMsg}
Open Fepper UI`;

        if (!dat) {
          res.send(successSimple);

          return;
        }

        let htmlMd;

        try {
          htmlMd = marked(dat);
          // Escape curly braces so they don't get interpreted as stashes.
          htmlMd = htmlMd.replace(/\{/g, '{');
          htmlMd = htmlMd.replace(/\}/g, '}');
        }
        catch (err1) /* istanbul ignore next */ {
          const internalServerError = 500;

          this.utils.error(err1);
          res.status(internalServerError).send(this.utils.httpCodes[internalServerError] + ' - ' + err1);

          return;
        }

        let outputFpt = this.html.headWithMsg;
        outputFpt += this.html.success;
        outputFpt += htmlMd + '\n';
        outputFpt += '

\n';
        outputFpt += '

\n';
        outputFpt += this.html.foot;

        const output = Feplet.render(
          outputFpt,
          {
            title: successMsg,
            main_id: 'success-page',
            main_class: 'success-page',
            msg_class: 'success',
            message: `<h1>${successMsg}</h1>`,
            origin: req.headers.host,
            search: ts ? `?ts=${ts}` : ''
          }
        );

        res.send(output);
      });
    };
  }
};
<commit_msg>removed console statement<commit_after>'use strict';

const Feplet = require('feplet');
const fs = require('fs-extra');
const marked = require('marked');

module.exports = class {
  constructor(options, html) {
    this.options = options;
    this.conf = options.conf;
    this.rootDir = options.rootDir;
    this.utils = options.utils;

    this.html = html;
  }

  main() {
    return (req, res) => {
      fs.readFile(`${this.rootDir}/README.md`, this.conf.enc, (err, dat) => {
        const successMsg = 'Installation success!';
        const ts = this.utils.deepGet(req, 'query.ts') ? req.query.ts : '';
        const successSimple = `<!DOCTYPE html><meta charset="utf-8">
${successMsg}
Open Fepper UI`;

        if (!dat) {
          res.send(successSimple);

          return;
        }

        let htmlMd;

        try {
          htmlMd = marked(dat);
          // Escape curly braces so they don't get interpreted as stashes.
          htmlMd = htmlMd.replace(/\{/g, '{');
          htmlMd = htmlMd.replace(/\}/g, '}');
        }
        catch (err1) /* istanbul ignore next */ {
          const internalServerError = 500;

          this.utils.error(err1);
          res.status(internalServerError).send(this.utils.httpCodes[internalServerError] + ' - ' + err1);

          return;
        }

        let outputFpt = this.html.headWithMsg;
        outputFpt += this.html.success;
        outputFpt += htmlMd + '\n';
        outputFpt += '

\n';
        outputFpt += '

\n';
        outputFpt += this.html.foot;

        const output = Feplet.render(
          outputFpt,
          {
            title: successMsg,
            main_id: 'success-page',
            main_class: 'success-page',
            msg_class: 'success',
            message: `<h1>${successMsg}</h1>`,
            origin: req.headers.host,
            search: ts ? `?ts=${ts}` : ''
          }
        );

        res.send(output);
      });
    };
  }
};
<|endoftext|>


<commit_before>// Copyright 2012 Joyent, Inc.  All rights reserved.

var assert = require('assert');
var util = require('util');
var restify = require('restify');

// --- Globals

var CODE = 'QuotaExceeded';
var MESSAGE = 'To have your limits raised please contact Support.';

module.exports = {
    preProvision: function (cfg) {

        if (!cfg || typeof (cfg) !== 'object') {
            throw new TypeError('cfg (object) is required');
        }

        if (!cfg.datacenter) {
            throw new TypeError('cfg.datacenter is required');
        }

        if (!cfg.defaults || typeof (cfg.defaults) !== 'object') {
            throw new TypeError('cfg.defaults (object) is required');
        }

        return function capiLimits(req, res, next) {
            // Do nothing if we are not provisioning:
            if (!(/\/machines$/.test(req.url) &&
                        req.method.toUpperCase() === 'POST')) {
                return next();
            }

            assert.ok(req.account);

            var log = req.log;

            if (req.account.isAdmin()) {
                log.debug('capi_limits: account %s is an admin, allowing.',
                    req.account.login);
                return next();
            }

            if (!req.dataset) {
                log.debug('capi_limits: no dataset on req; skipping checks.');
                return next();
            }

            return req.account.listLimits(function (err, limits) {
                if (err) {
                    log.error({err: err},
                        'capi_limits: unable to list limits.');
                    return next(new restify.InternalError(
                            'capi_limits: unable to list limits.'));
                }

                if (!limits) {
                    limits = [];
                }

                req.limits = limits;
                req.limit = cfg.defaults[req.dataset.name] || 0;
                for (var i = 0; i < limits.length; i++) {
                    if (limits[i].datacenter !== cfg.datacenter) {
                        continue;
                    }

                    if (limits[i][req.dataset.name]) {
                        req.limit = parseInt(limits[i][req.dataset.name], 10);
                        break;
                    }
                }

                log.info({
                    dataset: req.dataset.name,
                    limit: req.limit,
                    owner_uuid: req.account.uuid,
                    params: req.params,
                    limits: req.limits,
                }, 'capi_limits: dataset limits');

                if (req.limit < 0) {
                    return next(new restify.NotAuthorizedError(
                                util.format('%s: %s', CODE, MESSAGE)));
                }

                if (req.limit === 0) {
                    log.debug('capi_limits: unlimited quota.');
                    return next();
                }

                // Note we have no way right now to filter customer machines
                // by dataset name, since that's not added at all to our VMs
                // representation on VMAPI, neither to vmadm itself.
                // In order to get a reasonably good filter, we need to query
                // IMGAPI for all the machines with a given name, then build a
                // VMAPI query including all those images UUIDs into an LDAP
                // search filter.
                return req.sdc.imgapi.listImages({
                    name: req.dataset.name,
                    state: 'all'
                }, function (err2, images, r) {
                    if (err2) {
                        log.error({err: err3},
                            'capi_limits: unable to list Images');
                    }

                    if (!images) {
                        log.info('No images found with name ' +
                            req.dataset.name);
                        return next();
                    }

                    var filter = '(&(owner_uuid=' + req.account.uuid +
                            ')(&(!(state=destroyed))(!(state=failed)))(|(' +
                    images.map(function (i) {
                        return ('image_uuid=' + i.uuid);
                    }).join(')(') + ')))';

                    log.debug({filter: filter}, 'VMAPI search machines filter');

                    return req.sdc.vmapi.client.head({
                        path: '/vms',
                        query: {query: filter}
                    }, function (err3, req3, res3) {
                        if (err3) {
                            log.error({err: err3},
                                'capi_limits: unable to count VMs.');
                            return next(new restify.InternalError(
                                    'capi_limits: unable to count VMs.'));
                        }

                        var count = Number(
                            res3.headers['x-joyent-resource-count']) || 0;

                        log.debug('capi_limits: limit=%d, count=%d',
                            req.limit, count);

                        if (count >= req.limit) {
                            return next(new restify.NotAuthorizedError(
                                    util.format('%s: %s', CODE, MESSAGE)));
                        }
                        return next();

                    });
                });
            });
        };
    }
};
<commit_msg>JPC-1539: When there is no limit for a given dataset, fallback to a given value (2)<commit_after>// Copyright 2012 Joyent, Inc.  All rights reserved.

var assert = require('assert');
var util = require('util');
var restify = require('restify');

// --- Globals

var CODE = 'QuotaExceeded';
var MESSAGE = 'To have your limits raised please contact Support.';

module.exports = {
    preProvision: function (cfg) {

        if (!cfg || typeof (cfg) !== 'object') {
            throw new TypeError('cfg (object) is required');
        }

        if (!cfg.datacenter) {
            throw new TypeError('cfg.datacenter is required');
        }

        if (!cfg.defaults || typeof (cfg.defaults) !== 'object') {
            throw new TypeError('cfg.defaults (object) is required');
        }

        return function capiLimits(req, res, next) {
            // Do nothing if we are not provisioning:
            if (!(/\/machines$/.test(req.url) &&
                        req.method.toUpperCase() === 'POST')) {
                return next();
            }

            assert.ok(req.account);

            var log = req.log;

            if (req.account.isAdmin()) {
                log.debug('capi_limits: account %s is an admin, allowing.',
                    req.account.login);
                return next();
            }

            if (!req.dataset) {
                log.debug('capi_limits: no dataset on req; skipping checks.');
                return next();
            }

            return req.account.listLimits(function (err, limits) {
                if (err) {
                    log.error({err: err},
                        'capi_limits: unable to list limits.');
                    return next(new restify.InternalError(
                            'capi_limits: unable to list limits.'));
                }

                if (!limits) {
                    limits = [];
                }

                req.limits = limits;
                req.limit = cfg.defaults[req.dataset.name] || 0;
                for (var i = 0; i < limits.length; i++) {
                    if (limits[i].datacenter !== cfg.datacenter) {
                        continue;
                    }

                    if (limits[i][req.dataset.name]) {
                        req.limit = parseInt(limits[i][req.dataset.name], 10);
                        break;
                    } else {
                        req.limit = 2;
                    }
                }

                log.info({
                    dataset: req.dataset.name,
                    limit: req.limit,
                    owner_uuid: req.account.uuid,
                    params: req.params,
                    limits: req.limits,
                }, 'capi_limits: dataset limits');

                if (req.limit < 0) {
                    return next(new restify.NotAuthorizedError(
                                util.format('%s: %s', CODE, MESSAGE)));
                }

                if (req.limit === 0) {
                    log.debug('capi_limits: unlimited quota.');
                    return next();
                }

                // Note we have no way right now to filter customer machines
                // by dataset name, since that's not added at all to our VMs
                // representation on VMAPI, neither to vmadm itself.
                // In order to get a reasonably good filter, we need to query
                // IMGAPI for all the machines with a given name, then build a
                // VMAPI query including all those images UUIDs into an LDAP
                // search filter.
                return req.sdc.imgapi.listImages({
                    name: req.dataset.name,
                    state: 'all'
                }, function (err2, images, r) {
                    if (err2) {
                        log.error({err: err3},
                            'capi_limits: unable to list Images');
                    }

                    if (!images) {
                        log.info('No images found with name ' +
                            req.dataset.name);
                        return next();
                    }

                    var filter = '(&(owner_uuid=' + req.account.uuid +
                            ')(&(!(state=destroyed))(!(state=failed)))(|(' +
                    images.map(function (i) {
                        return ('image_uuid=' + i.uuid);
                    }).join(')(') + ')))';

                    log.debug({filter: filter}, 'VMAPI search machines filter');

                    return req.sdc.vmapi.client.head({
                        path: '/vms',
                        query: {query: filter}
                    }, function (err3, req3, res3) {
                        if (err3) {
                            log.error({err: err3},
                                'capi_limits: unable to count VMs.');
                            return next(new restify.InternalError(
                                    'capi_limits: unable to count VMs.'));
                        }

                        var count = Number(
                            res3.headers['x-joyent-resource-count']) || 0;

                        log.debug('capi_limits: limit=%d, count=%d',
                            req.limit, count);

                        if (count >= req.limit) {
                            return next(new restify.NotAuthorizedError(
                                    util.format('%s: %s', CODE, MESSAGE)));
                        }
                        return next();

                    });
                });
            });
        };
    }
};
<|endoftext|>


<commit_before>/*
 * Copyright 2017 e-UCM, Universidad Complutense de Madrid
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * This project has received funding from the European Union’s Horizon
 * 2020 research and innovation programme under grant agreement No 644187.
 * 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.
 */

if(typeof TrackerPlugins === "undefined"){
  var TrackerPlugins = {};
}

TrackerPlugins.Geolocation = function(){
  this.interfaces = {

    Places:
      function(tracker){
        this.tracker = tracker;

        this.PlaceType = {
            Building: 0,
            GreenZone: 1,
            UrbanArea: 2,
            Water: 3,
            Place: 4,
            properties: ["building", "green-zone", "urban-area", "water", "place"]
        }

          this.Moved = function(placeId, latitude, longitude, type){
            if(typeof type === "undefined") {type = 4;}

            this.tracker.setLocation(latitude, longitude);

            return this.tracker.Trace("moved",this.PlaceType.properties[type],placeId);
          }

          this.Looked = function(placeId, type, orientation, latitude, longitude){
            if(typeof type === "undefined") {type = 4;}
            if(typeof orientation !== "undefined") {
              this.tracker.setVar("orientation", orientation);
            }
            if(typeof latitude !== "undefined") {
              this.tracker.setLocation(latitude, longitude);
            }

            return this.tracker.Trace("looked",this.PlaceType.properties[type],placeId);
          }

          this.Entered = function(placeId, type){
            if(typeof type === "undefined") {type = 4;}

            return this.tracker.Trace("entered",this.PlaceType.properties[type],placeId);
          }

          this.Exited = function(placeId, type){
            if(typeof type === "undefined") {type = 4;}

            return this.tracker.Trace("exited",this.PlaceType.properties[type],placeId);
          }
      },

    Directions:
      function(tracker){
        this.tracker = tracker;

        this.DirectionType = {
            Direction: 0,
            properties: ["direction"]
        }

          this.Followed = function(placeId, directions, type){
            if(typeof type === "undefined") {type = 0;}

            this.tracker.setLocation(location);

            return this.tracker.Trace("followed",this.DirectionType.properties[type],placeId);
          }
      }
  };
  this.functions = {
    setLocation: function(tracker){
        return function(latitude, longitude){
          tracker.setVar("location",{lat: latitude, lon: longitude});
        }
      }
  };
  this.verbs = {
      entered: "https://beaconing.e-ucm.es/xapi/geolocated/verbs/entered",
      exited: "https://beaconing.e-ucm.es/xapi/geolocated/verbs/exited",
      moved: "https://beaconing.e-ucm.es/xapi/geolocated/verbs/moved",
      looked: "https://beaconing.e-ucm.es/xapi/geolocated/verbs/looked",
      followed: "https://beaconing.e-ucm.es/xapi/geolocated/verbs/followed"
  };
  this.objects = {
      building: "https://beaconing.e-ucm.es/xapi/geolocated/activity-types/building",
      "green-zone": "https://beaconing.e-ucm.es/xapi/geolocated/activity-types/green-zone",
      "urban-area": "https://beaconing.e-ucm.es/xapi/geolocated/activity-types/urban-area",
      water: "https://beaconing.e-ucm.es/xapi/geolocated/activity-types/water",
      place: "https://beaconing.e-ucm.es/xapi/geolocated/activity-types/place",
      direction: "https://beaconing.e-ucm.es/xapi/geolocated/activity-types/direction"
  };
  this.extensions = {
      location: "https://beaconing.e-ucm.es/xapi/geolocated/extensions/location",
      orientation: "https://beaconing.e-ucm.es/xapi/geolocated/extensions/orientation",
      guide: "https://beaconing.e-ucm.es/xapi/geolocated/extensions/guide"
  };
}<commit_msg>Included Point of Interest into the plugin as PlaceType.POI<commit_after>/*
 * Copyright 2017 e-UCM, Universidad Complutense de Madrid
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * This project has received funding from the European Union’s Horizon
 * 2020 research and innovation programme under grant agreement No 644187.
 * 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.
 */

if(typeof TrackerPlugins === "undefined"){
  var TrackerPlugins = {};
}

TrackerPlugins.Geolocation = function(){
  this.interfaces = {

    Places:
      function(tracker){
        this.tracker = tracker;

        this.PlaceType = {
            Building: 0,
            GreenZone: 1,
            UrbanArea: 2,
            Water: 3,
            POI: 4,
            Place: 5,
            properties: ["building", "green-zone", "urban-area", "water", "point-of-interest", "place"]

        }

          this.Moved = function(placeId, latitude, longitude, type){
            if(typeof type === "undefined") {type = 5;}

            this.tracker.setLocation(latitude, longitude);

            return this.tracker.Trace("moved",this.PlaceType.properties[type],placeId);
          }

          this.Looked = function(placeId, type, orientation, latitude, longitude){
            if(typeof type === "undefined") {type = 5;}
            if(typeof orientation !== "undefined") {
              this.tracker.setVar("orientation", orientation);
            }
            if(typeof latitude !== "undefined") {
              this.tracker.setLocation(latitude, longitude);
            }

            return this.tracker.Trace("looked",this.PlaceType.properties[type],placeId);
          }

          this.Entered = function(placeId, type){
            if(typeof type === "undefined") {type = 5;}

            return this.tracker.Trace("entered",this.PlaceType.properties[type],placeId);
          }

          this.Exited = function(placeId, type){
            if(typeof type === "undefined") {type = 5;}

            return this.tracker.Trace("exited",this.PlaceType.properties[type],placeId);
          }
      },

    Directions:
      function(tracker){
        this.tracker = tracker;

        this.DirectionType = {
            Direction: 0,
            properties: ["direction"]
        }

          this.Followed = function(placeId, directions, type){
            if(typeof type === "undefined") {type = 0;}

            this.tracker.setLocation(location);

            return this.tracker.Trace("followed",this.DirectionType.properties[type],placeId);
          }
      }
  };
  this.functions = {
    setLocation: function(tracker){
        return function(latitude, longitude){
          tracker.setVar("location",{lat: latitude, lon: longitude});
        }
      }
  };
  this.verbs = {
      entered: "https://beaconing.e-ucm.es/xapi/geolocated/verbs/entered",
      exited: "https://beaconing.e-ucm.es/xapi/geolocated/verbs/exited",
      moved: "https://beaconing.e-ucm.es/xapi/geolocated/verbs/moved",
      looked: "https://beaconing.e-ucm.es/xapi/geolocated/verbs/looked",
      followed: "https://beaconing.e-ucm.es/xapi/geolocated/verbs/followed"
  };
  this.objects = {
      building: "https://beaconing.e-ucm.es/xapi/geolocated/activity-types/building",
      "green-zone": "https://beaconing.e-ucm.es/xapi/geolocated/activity-types/green-zone",
      "urban-area": "https://beaconing.e-ucm.es/xapi/geolocated/activity-types/urban-area",
      water: "https://beaconing.e-ucm.es/xapi/geolocated/activity-types/water",
      place: "https://beaconing.e-ucm.es/xapi/geolocated/activity-types/place",
      direction: "https://beaconing.e-ucm.es/xapi/geolocated/activity-types/direction",
      "point-of-interest": "https://beaconing.e-ucm.es/xapi/geolocated/activity-types/point-of-interest"
  };
  this.extensions = {
      location: "https://beaconing.e-ucm.es/xapi/geolocated/extensions/location",
      orientation: "https://beaconing.e-ucm.es/xapi/geolocated/extensions/orientation",
      guide: "https://beaconing.e-ucm.es/xapi/geolocated/extensions/guide"
  };
}<|endoftext|>


<commit_before>/*  jspsych-xab.js
 *	Josh de Leeuw
 *
 *  This plugin runs a single XAB trial, where X is an image presented in isolation, and A and B are choices, with A or B being equal to X.
 *	The subject's goal is to identify whether A or B is identical to X.
 *
 * documentation: https://github.com/jodeleeuw/jsPsych/wiki/jspsych-xab
 *
 */

(function($) {
		jsPsych.xab = (function() {

				var plugin = {};

				plugin.create = function(params) {

					params = jsPsych.pluginAPI.enforceArray(params, ['data']);

					// the number of trials is determined by how many entries the params.stimuli array has
					var trials = new Array(params.stimuli.length);

					for (var i = 0; i < trials.length; i++) {
						trials[i] = {};
						trials[i].x_path = params.stimuli[i][0];
						// if there is only a pair of stimuli, then the first is the target and is shown twice.
						// if there is a triplet, then the first is X, the second is the target, and the third is foil (useful for non-exact-match XAB).
						if (params.stimuli[i].length == 2) {
							trials[i].a_path = params.stimuli[i][0];
							trials[i].b_path = params.stimuli[i][1];
						} else {
							trials[i].a_path = params.stimuli[i][1];
							trials[i].b_path = params.stimuli[i][2];
						}
						trials[i].left_key = params.left_key || 81; // defaults to 'q'
						trials[i].right_key = params.right_key || 80; // defaults to 'p'
						// timing parameters
						trials[i].timing_x = params.timing_x || 1000; // defaults to 1000msec.
						trials[i].timing_xab_gap = params.timing_xab_gap || 1000; // defaults to 1000msec.
						trials[i].timing_ab = params.timing_ab || -1; // defaults to -1, meaning infinite time on AB. If a positive number is used, then AB will only be displayed for that length.
						// optional parameters
						trials[i].is_html = (typeof params.is_html === 'undefined') ? false : params.is_html;
						trials[i].prompt = (typeof params.prompt === 'undefined') ? "" : params.prompt;

					}
					return trials;
				};

				var xab_trial_complete = false;

				plugin.trial = function(display_element, trial) {

					// if any trial variables are functions
					// this evaluates the function and replaces
					// it with the output of the function
					trial = jsPsych.pluginAPI.normalizeTrialVariables(trial);

					xab_trial_complete = false;

					// how we display the content depends on whether the content is
					// HTML code or an image path.
					if (!trial.is_html) {
						display_element.append($('<img>', {
							src: trial.x_path,
							"class": 'jspsych-xab-stimulus'
						}));
					} else {
						display_element.append($('<div>', {
							"class": 'jspsych-xab-stimulus',
							html: trial.x_path
						}));
					}

					// start a timer of length trial.timing_x to move to the next part of the trial
					setTimeout(function() {
						showBlankScreen();
					}, trial.timing_x);
					break;

					// the second part of the trial is the gap between X and AB.

					function showBlankScreen() {
						// remove the x stimulus
						$('.jspsych-xab-stimulus').remove();

						// start timer
						setTimeout(function() {
							showSecondStimulus();
						}, trial.timing_xab_gap);
					}

					// the third part of the trial is to display A and B, and get the subject's response

					function showSecondStimulus() {

						// randomize whether the target is on the left or the right
						var images = [trial.a_path, trial.b_path];
						var target_left = (Math.floor(Math.random() * 2) === 0); // 50% chance target is on left.
						if (!target_left) {
							images = [trial.b_path, trial.a_path];
						}

						// show the options
						if (!trial.is_html) {
							display_element.append($('<img>', {
								"src": images[0],
								"class": 'jspsych-xab-stimulus left'
							}));
							display_element.append($('<img>', {
								"src": images[1],
								"class": 'jspsych-xab-stimulus right'
							}));
						} else {
							display_element.append($('<div>', {
								"class": 'jspsych-xab-stimulus left',
								html: images[0]
							}));
							display_element.append($('<div>', {
								"class": 'jspsych-xab-stimulus right',
								html: images[1]
							}));
						}

						if (trial.prompt !== "") {
							display_element.append(trial.prompt);
						}

						// if timing_ab is > 0, then we hide the stimuli after timing_ab milliseconds
						if (trial.timing_ab > 0) {
							setTimeout(function() {
								if (!xab_trial_complete) {
									$('.jspsych-xab-stimulus').css('visibility', 'hidden');
								}
							}, trial.timing_ab);
						}

						// create the function that triggers when a key is pressed.
						var after_response = function(info) {

							var correct = false; // true when the correct response is chosen

							if (info.key == trial.left_key) // 'q' key by default
							{
								if (target_left) {
									correct = true;
								}
							} else if (info.key == trial.right_key) // 'p' key by default
							{
								if (!target_left) {
									correct = true;
								}
							}

							// create object to store data from trial
							var trial_data = {
								"rt": info.rt,
								"correct": correct,
								"stimulus_x": trial.x_path,
								"stimulus_a": trial.a_path,
								"stimulus_b": trial.b_path,
								"key_press": info.key
							};
							jsPsych.data.write($.extend({}, trial_data, trial.data));

							display_element.html(''); // remove all

							xab_trial_complete = true;

							// move on to the next trial after timing_post_trial milliseconds
							if (trial.timing_post_trial > 0) {
								setTimeout(function() {
									jsPsych.finishTrial();
								}, trial.timing_post_trial);
							} else {
								jsPsych.finishTrial();
							}

						};

						jsPsych.pluginAPI.getKeyboardResponse(after_response, [trial.left_key, trial.right_key], 'date', false);

					}
				}
			};

			return plugin;
		})();
})(jQuery);
<commit_msg>fix xab bug and formatting<commit_after>/*  jspsych-xab.js
 *	Josh de Leeuw
 *
 *  This plugin runs a single XAB trial, where X is an image presented in isolation, and A and B are choices, with A or B being equal to X.
 *	The subject's goal is to identify whether A or B is identical to X.
 *
 * documentation: https://github.com/jodeleeuw/jsPsych/wiki/jspsych-xab
 *
 */

(function($) {
	jsPsych.xab = (function() {

		var plugin = {};

		plugin.create = function(params) {

			params = jsPsych.pluginAPI.enforceArray(params, ['data']);

			// the number of trials is determined by how many entries the params.stimuli array has
			var trials = new Array(params.stimuli.length);

			for (var i = 0; i < trials.length; i++) {
				trials[i] = {};
				trials[i].x_path = params.stimuli[i][0];
				// if there is only a pair of stimuli, then the first is the target and is shown twice.
				// if there is a triplet, then the first is X, the second is the target, and the third is foil (useful for non-exact-match XAB).
				if (params.stimuli[i].length == 2) {
					trials[i].a_path = params.stimuli[i][0];
					trials[i].b_path = params.stimuli[i][1];
				} else {
					trials[i].a_path = params.stimuli[i][1];
					trials[i].b_path = params.stimuli[i][2];
				}
				trials[i].left_key = params.left_key || 81; // defaults to 'q'
				trials[i].right_key = params.right_key || 80; // defaults to 'p'
				// timing parameters
				trials[i].timing_x = params.timing_x || 1000; // defaults to 1000msec.
				trials[i].timing_xab_gap = params.timing_xab_gap || 1000; // defaults to 1000msec.
				trials[i].timing_ab = params.timing_ab || -1; // defaults to -1, meaning infinite time on AB. If a positive number is used, then AB will only be displayed for that length.
				// optional parameters
				trials[i].is_html = (typeof params.is_html === 'undefined') ? false : params.is_html;
				trials[i].prompt = (typeof params.prompt === 'undefined') ? "" : params.prompt;

			}
			return trials;
		};

		var xab_trial_complete = false;

		plugin.trial = function(display_element, trial) {

			// if any trial variables are functions
			// this evaluates the function and replaces
			// it with the output of the function
			trial = jsPsych.pluginAPI.normalizeTrialVariables(trial);

			xab_trial_complete = false;

			// how we display the content depends on whether the content is
			// HTML code or an image path.
			if (!trial.is_html) {
				display_element.append($('<img>', {
					src: trial.x_path,
					"class": 'jspsych-xab-stimulus'
				}));
			} else {
				display_element.append($('<div>', {
					"class": 'jspsych-xab-stimulus',
					html: trial.x_path
				}));
			}

			// start a timer of length trial.timing_x to move to the next part of the trial
			setTimeout(function() {
				showBlankScreen();
			}, trial.timing_x);

			function showBlankScreen() {
				// remove the x stimulus
				$('.jspsych-xab-stimulus').remove();

				// start timer
				setTimeout(function() {
					showSecondStimulus();
				}, trial.timing_xab_gap);
			}

			function showSecondStimulus() {

				// randomize whether the target is on the left or the right
				var images = [trial.a_path, trial.b_path];
				var target_left = (Math.floor(Math.random() * 2) === 0); // 50% chance target is on left.
				if (!target_left) {
					images = [trial.b_path, trial.a_path];
				}

				// show the options
				if (!trial.is_html) {
					display_element.append($('<img>', {
						"src": images[0],
						"class": 'jspsych-xab-stimulus left'
					}));
					display_element.append($('<img>', {
						"src": images[1],
						"class": 'jspsych-xab-stimulus right'
					}));
				} else {
					display_element.append($('<div>', {
						"class": 'jspsych-xab-stimulus left',
						html: images[0]
					}));
					display_element.append($('<div>', {
						"class": 'jspsych-xab-stimulus right',
						html: images[1]
					}));
				}

				if (trial.prompt !== "") {
					display_element.append(trial.prompt);
				}

				// if timing_ab is > 0, then we hide the stimuli after timing_ab milliseconds
				if (trial.timing_ab > 0) {
					setTimeout(function() {
						if (!xab_trial_complete) {
							$('.jspsych-xab-stimulus').css('visibility', 'hidden');
						}
					}, trial.timing_ab);
				}

				// create the function that triggers when a key is pressed.
				var after_response = function(info) {

					var correct = false; // true when the correct response is chosen

					if (info.key == trial.left_key) // 'q' key by default
					{
						if (target_left) {
							correct = true;
						}
					} else if (info.key == trial.right_key) // 'p' key by default
					{
						if (!target_left) {
							correct = true;
						}
					}

					// create object to store data from trial
					var trial_data = {
						"rt": info.rt,
						"correct": correct,
						"stimulus_x": trial.x_path,
						"stimulus_a": trial.a_path,
						"stimulus_b": trial.b_path,
						"key_press": info.key
					};
					jsPsych.data.write($.extend({}, trial_data, trial.data));

					display_element.html(''); // remove all

					xab_trial_complete = true;

					// move on to the next trial after timing_post_trial milliseconds
					if (trial.timing_post_trial > 0) {
						setTimeout(function() {
							jsPsych.finishTrial();
						}, trial.timing_post_trial);
					} else {
						jsPsych.finishTrial();
					}

				};

				jsPsych.pluginAPI.getKeyboardResponse(after_response, [trial.left_key, trial.right_key], 'date', false);

			}
		};

		return plugin;
	})();
})(jQuery);
<|endoftext|>


<commit_before>define([], function() {
  'use strict';

  /**
   * This is used as the base class for all modules.
   * All modules/components should extend this class.
   *
   * Includes:
   *  event binding/triggering
   *  logging
   *  i18n library
   */

  function DoughBaseComponent($el, config) {
    if (!$el || !$el.length) {
      throw new Error('Element not supplied to DoughBaseComponent constructor');
    }
    this.config = config || {};
    this.componentName = this.config.componentName;
    this.setElement($el);
    /*
     Populate this array with the data attributes this module will use.
     Exclude 'data-dough-' prefix, as this is automatically added.

     For example: ['collapsible', 'only-first']
     */
    this.attrs = [];

    this._bindUiEvents(this.uiEvents || {});
    return this;
  }

  /**
   * Extend DoughBaseComponent class using the supplied constructor
   * @param {function} Subclass
   * @param {function} [Superclass] - if not supplied, defaults to DoughBaseComponent
   */
  DoughBaseComponent.extend = function(Subclass, Superclass) {
    var Super = Superclass || DoughBaseComponent;

    function TempConstructor() {
    }

    TempConstructor.prototype = Super.prototype;
    Subclass.prototype = new TempConstructor();
    Subclass.prototype.constructor = Subclass;
    Subclass.baseConstructor = Super;
    Subclass.superclass = Super.prototype;
  };

  var DoughBaseComponentProto = DoughBaseComponent.prototype;

  /**
   * Set the parent element for this context.
   * @param {[type]} $el [description]
   */
  DoughBaseComponentProto.setElement = function($el) {
    this.$el = $el;
    return this;
  };

  /**
   * All DoughBaseComponents (if applicable) should have this method,
   * which will unbind all events it attached when initialising itself.
   *
   * After this has been run, you can safely run 'delete [[instance]]' to remove it from memory.
   *
   * @return {[type]}
   */
  DoughBaseComponentProto.destroy = function() {
    this._unbindUiEvents();
    return this;
  };

  /**
   * Set callbacks, where `this.events` is a hash of
   *
   * {"event selector": "callback"}*
   *
   *     {
   *       'mousedown .title':  'edit',
   *       'click .button':     'save',
   *       'click .open':       function(e) { ... }
   *     }
   *
   * pairs. Callbacks will be bound to the view, with `this` set properly.
   * Uses event delegation for efficiency.
   * Omitting the selector binds the event to `this.el`.
   * This only works for delegate-able events: not `focus`, `blur`, and
   * not `change`, `submit`, and `reset` in Internet Explorer.
   *
   * Adapted from the equivalent function in BackboneJS - http://backbonejs.org/#View-delegateEvents
   *
   * @param events
   * @returns {DoughBaseComponent}
   */

  DoughBaseComponentProto._bindUiEvents = function(events) {
    var delegateEventSplitter = /^(\S+)\s*(.*)$/;

    if (!events) {
      return this;
    }

    this._unbindUiEvents();
    for (var key in events) {
      var method = this[events[key]];
      if (!method) {
        continue;
      }

      var match = key.match(delegateEventSplitter);
      var eventName = match[1], selector = match[2];
      method = $.proxy(method, this);
      eventName += '.boundUiEvents';
      if (selector === '') {
        this.$el.on(eventName, method);
      } else {
        this.$el.on(eventName, selector, method);
      }
    }
    return this;
  };

  /**
   * Clears all callbacks previously bound to the component with `delegateEvents`.
   * @returns {DoughBaseComponent}
   */

  DoughBaseComponentProto._unbindUiEvents = function() {
    this.$el.off('.boundUiEvents');
    return this;
  };

  /**
   * Indicate that the component initialised successfully, passing its component name. The resolved
   * promise will be fed back to the component loader
   * @private
   */
  DoughBaseComponentProto._initialisedSuccess = function(initialised) {
    this.$el.attr('data-dough-' + this.componentName + '-initialised', 'yes');
    initialised && initialised.resolve(this.componentName);
  };

  /**
   * Indicate that the component failed to initialise, passing its component name. The rejected
   * promise will be fed back to the component loader
   * @private
   */
  DoughBaseComponentProto._initialisedFailure = function(initialised) {
    initialised && initialised.reject(this.componentName);
  };

  return DoughBaseComponent;

});
<commit_msg>Namespace bound UI events with component name<commit_after>define([], function() {
  'use strict';

  /**
   * This is used as the base class for all modules.
   * All modules/components should extend this class.
   *
   * Includes:
   *  event binding/triggering
   *  logging
   *  i18n library
   */

  function DoughBaseComponent($el, config) {
    if (!$el || !$el.length) {
      throw new Error('Element not supplied to DoughBaseComponent constructor');
    }
    this.config = config || {};
    this.componentName = this.config.componentName;
    this.setElement($el);
    /*
     Populate this array with the data attributes this module will use.
     Exclude 'data-dough-' prefix, as this is automatically added.

     For example: ['collapsible', 'only-first']
     */
    this.attrs = [];

    this._bindUiEvents(this.uiEvents || {});
    return this;
  }

  /**
   * Extend DoughBaseComponent class using the supplied constructor
   * @param {function} Subclass
   * @param {function} [Superclass] - if not supplied, defaults to DoughBaseComponent
   */
  DoughBaseComponent.extend = function(Subclass, Superclass) {
    var Super = Superclass || DoughBaseComponent;

    function TempConstructor() {
    }

    TempConstructor.prototype = Super.prototype;
    Subclass.prototype = new TempConstructor();
    Subclass.prototype.constructor = Subclass;
    Subclass.baseConstructor = Super;
    Subclass.superclass = Super.prototype;
  };

  var DoughBaseComponentProto = DoughBaseComponent.prototype;

  /**
   * Set the parent element for this context.
   * @param {[type]} $el [description]
   */
  DoughBaseComponentProto.setElement = function($el) {
    this.$el = $el;
    return this;
  };

  /**
   * All DoughBaseComponents (if applicable) should have this method,
   * which will unbind all events it attached when initialising itself.
   *
   * After this has been run, you can safely run 'delete [[instance]]' to remove it from memory.
   *
   * @return {[type]}
   */
  DoughBaseComponentProto.destroy = function() {
    this._unbindUiEvents();
    return this;
  };

  /**
   * Set callbacks, where `this.events` is a hash of
   *
   * {"event selector": "callback"}*
   *
   *     {
   *       'mousedown .title':  'edit',
   *       'click .button':     'save',
   *       'click .open':       function(e) { ... }
   *     }
   *
   * pairs. Callbacks will be bound to the view, with `this` set properly.
   * Uses event delegation for efficiency.
   * Omitting the selector binds the event to `this.el`.
   * This only works for delegate-able events: not `focus`, `blur`, and
   * not `change`, `submit`, and `reset` in Internet Explorer.
   *
   * Adapted from the equivalent function in BackboneJS - http://backbonejs.org/#View-delegateEvents
   *
   * @param events
   * @returns {DoughBaseComponent}
   */

  DoughBaseComponentProto._bindUiEvents = function(events) {
    var delegateEventSplitter = /^(\S+)\s*(.*)$/;

    if (!events) {
      return this;
    }

    this._unbindUiEvents();
    for (var key in events) {
      var method = this[events[key]];
      if (!method) {
        continue;
      }

      var match = key.match(delegateEventSplitter);
      var eventName = match[1], selector = match[2];
      method = $.proxy(method, this);
      eventName += '.' + this.componentName + '-boundUiEvents';
      if (selector === '') {
        this.$el.on(eventName, method);
      } else {
        this.$el.on(eventName, selector, method);
      }
    }
    return this;
  };

  /**
   * Clears all callbacks previously bound to the component with `delegateEvents`.
   * @returns {DoughBaseComponent}
   */

  DoughBaseComponentProto._unbindUiEvents = function() {
    this.$el.off('.' + this.componentName + '-boundUiEvents');
    return this;
  };

  /**
   * Indicate that the component initialised successfully, passing its component name. The resolved
   * promise will be fed back to the component loader
   * @private
   */
  DoughBaseComponentProto._initialisedSuccess = function(initialised) {
    this.$el.attr('data-dough-' + this.componentName + '-initialised', 'yes');
    initialised && initialised.resolve(this.componentName);
  };

  /**
   * Indicate that the component failed to initialise, passing its component name. The rejected
   * promise will be fed back to the component loader
   * @private
   */
  DoughBaseComponentProto._initialisedFailure = function(initialised) {
    initialised && initialised.reject(this.componentName);
  };

  return DoughBaseComponent;

});
<|endoftext|>


<commit_before>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2012 Google Inc.
 * https://developers.google.com/blockly/
 *
 * 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.
 */

/**
 * @fileoverview Text input field.
 * @author fraser@google.com (Neil Fraser)
 */
'use strict';

goog.provide('Blockly.FieldVarInput');

goog.require('Blockly.Field');
goog.require('Blockly.Msg');
goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.userAgent');

/**
 * Class for an editable text field.
 * @param {string} text The initial content of the field.
 * @param {Function=} opt_validator An optional function that is called
 *     to validate any constraints on what the user entered.  Takes the new
 *     text as an argument and returns either the accepted text, a replacement
 *     text, or null to abort the change.
 * @extends {Blockly.Field}
 * @constructor
 */
Blockly.FieldVarInput = function(text, opt_validator, typeExpr) {
  Blockly.FieldVarInput.superClass_.constructor.call(this, text,
      opt_validator);

  this.typeExpr = typeExpr;
  this.size_.height += 4;
};
goog.inherits(Blockly.FieldVarInput, Blockly.Field);

Blockly.FieldVarInput.prototype.updateEditable = function() {
  Blockly.addClass_(/** @type {!Element} */ (this.fieldGroup_),
                      'blocklyFieldVarInput');

};

Blockly.FieldVarInput.prototype.getPath = function(width)
{
  var width_ = width+4;

  var inlineSteps = [];
  if(this.typeExpr)
  {
    inlineSteps.push('M 0,-2');

    Blockly.BlockSvg.renderTypeExpr(this.typeExpr, inlineSteps, 'down');

    var height = Blockly.BlockSvg.getTypeExprHeight(this.typeExpr);
    this.size_.height = height + 10;
    if(height < 23)
      height = 23;

    inlineSteps.push('M 0,' + (height - 6) ) ;

    inlineSteps.push('l 0 4 l ' + width_ + ' 0 l 0 -' +height + ' l -' + width_ + ' 0');
  }
  else
  {
      inlineSteps.push('M 0,4');
      inlineSteps.push('a 6,6,0,0,0,0,12');
      inlineSteps.push('l 0 4 l '+ width_ + ' 0 l 0 -20 l -' + width_ + ' 0 z');
  }

  return inlineSteps.join(' ');
};

Blockly.FieldVarInput.prototype.init = function() {
  if (this.fieldGroup_) {
    // Field has already been initialized once.
    return;
  }
  // Build the DOM.
  this.fieldGroup_ = Blockly.createSvgElement('g', {}, null);
  if (!this.visible_) {
    this.fieldGroup_.style.display = 'none';
  }

  this.borderRect_ = Blockly.createSvgElement('path',
       {'class': 'blocklyFieldVarInput',
       'd': this.getPath(this.size_.width)},
       this.fieldGroup_);

  /** @type {!Element} */
  this.textElement_ = Blockly.createSvgElement('text',
      {'class': 'blocklyText', 'y': 15, 'x':6},
      this.fieldGroup_);

    this.updateEditable();
  this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_);
  this.mouseUpWrapper_ =
      Blockly.bindEvent_(this.fieldGroup_, 'mouseup', this, this.onMouseUp_);
  this.mouseDownWrapper_ =
      Blockly.bindEvent_(this.fieldGroup_, 'mousedown', this, this.onMouseDown_);

  // Force a render.
  this.updateTextNode_();
};

Blockly.FieldVarInput.prototype.render_ = function() {
  if (this.visible_ && this.textElement_) {
    var key = this.textElement_.textContent + '\n' +
        this.textElement_.className.baseVal;
    if (Blockly.Field.cacheWidths_ && Blockly.Field.cacheWidths_[key]) {
      var width = Blockly.Field.cacheWidths_[key];
    } else {
      try {
        var width = this.textElement_.getComputedTextLength();
      } catch (e) {
        // MSIE 11 is known to throw "Unexpected call to method or property
        // access." if Blockly is hidden.
        var width = this.textElement_.textContent.length * 8;
      }
      if (Blockly.Field.cacheWidths_) {
        Blockly.Field.cacheWidths_[key] = width;
      }
    }
    if (this.borderRect_) {
      this.borderRect_.setAttribute('d', this.getPath(width + Blockly.BlockSvg.SEP_SPACE_X));
    }
  } else {
    var width = 0;
  }
  this.size_.width = width;
};

Blockly.FieldVarInput.prototype.render_ = function() {
  if (this.visible_ && this.textElement_) {
    var key = this.textElement_.textContent + '\n' +
        this.textElement_.className.baseVal;
    if (Blockly.Field.cacheWidths_ && Blockly.Field.cacheWidths_[key]) {
      var width = Blockly.Field.cacheWidths_[key];
    } else {
      try {
        var width = this.textElement_.getComputedTextLength();
      } catch (e) {
        // MSIE 11 is known to throw "Unexpected call to method or property
        // access." if Blockly is hidden.
        var width = this.textElement_.textContent.length * 8;
      }
      if (Blockly.Field.cacheWidths_) {
        Blockly.Field.cacheWidths_[key] = width;
      }
    }
    if (this.borderRect_) {
      this.borderRect_.setAttribute('width',
          width + Blockly.BlockSvg.SEP_SPACE_X);
      this.borderRect_.setAttribute('d',this.getPath(width + Blockly.BlockSvg.SEP_SPACE_X));
    }
  } else {
    var width = 0;
  }
  this.size_.width = width+10;
};

/**
 * Point size of text.  Should match blocklyText's font-size in CSS.
 */
Blockly.FieldVarInput.FONTSIZE = 11;

/**
 * Close the input widget if this input is being deleted.
 */
Blockly.FieldVarInput.prototype.dispose = function() {
  Blockly.WidgetDiv.hideIfOwner(this);
  Blockly.FieldVarInput.superClass_.dispose.call(this);
};

/**
 * Set the text in this field.
 * @param {?string} text New text.
 * @override
 */
Blockly.FieldVarInput.prototype.setValue = function(text) {
  if (text === null) {
    return;  // No change if null.
  }
  Blockly.Field.prototype.setValue.call(this, text);
};

Blockly.FieldVarInput.prototype.showEditor_ = function(){};

Blockly.FieldVarInput.prototype.onMouseDown_ = function(e){
  if(this.sourceBlock_.isInFlyout )
    return;
  var name = this.getValue();
  Blockly.dragMode_ = Blockly.DRAG_NONE;
  this.sourceBlock_.setDragging_(false);
  this.sourceBlock_.onMouseUp_(e);
  this.sourceBlock_.unselect();

  var mutation = goog.dom.createDom('mutation');

  if(this.typeExpr){
    var typeDom = this.typeExpr.toDom();
    mutation.appendChild(typeDom);
  }

  var container = goog.dom.createDom('block');
  container.setAttribute('type','vars_local');
  container.appendChild(mutation);

  var curBlock = Blockly.Xml.domToBlock(container, Blockly.getMainWorkspace());
  curBlock.parent_ = this.sourceBlock_;

  if(this.typeExpr)
    curBlock.setOutputTypeExpr(this.typeExpr);
  curBlock.render();

  var targetWorkspace = Blockly.getMainWorkspace();
  this.workspace_ = Blockly.getMainWorkspace();

  var svgRootOld = this.sourceBlock_.getSvgRoot();
  var xyOld = Blockly.getSvgXY_(svgRootOld, targetWorkspace);

  var element = document.getElementById('blocklyDiv');
  var rect = element.getBoundingClientRect();

  var mouseX = e.clientX - rect.left;
  var mouseY = e.clientY - rect.top;

  var scale = this.workspace_.scale;

  var svgRootNew = curBlock.getSvgRoot();
  var xyNew = Blockly.getSvgXY_(svgRootNew, targetWorkspace);

  var blockOffsetX = xyNew.x;
  var blockOffsetY = xyNew.y;

  var offsetX = mouseX - blockOffsetX;
  var offsetY = mouseY - blockOffsetY;

  offsetX /= scale;
  offsetY /= scale;

  curBlock.moveBy(offsetX, offsetY);
  curBlock.moveBy(-curBlock.getHeightWidth().width/2, -curBlock.getHeightWidth().height/2);

  curBlock.onMouseDown_(e);
  Blockly.dragMode_ = Blockly.DRAG_FREE;
  curBlock.setDragging_(true);

};

<commit_msg>Fix local variable name not being set<commit_after>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2012 Google Inc.
 * https://developers.google.com/blockly/
 *
 * 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.
 */

/**
 * @fileoverview Text input field.
 * @author fraser@google.com (Neil Fraser)
 */
'use strict';

goog.provide('Blockly.FieldVarInput');

goog.require('Blockly.Field');
goog.require('Blockly.Msg');
goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.userAgent');

/**
 * Class for an editable text field.
 * @param {string} text The initial content of the field.
 * @param {Function=} opt_validator An optional function that is called
 *     to validate any constraints on what the user entered.  Takes the new
 *     text as an argument and returns either the accepted text, a replacement
 *     text, or null to abort the change.
 * @extends {Blockly.Field}
 * @constructor
 */
Blockly.FieldVarInput = function(text, opt_validator, typeExpr) {
  Blockly.FieldVarInput.superClass_.constructor.call(this, text,
      opt_validator);

  this.typeExpr = typeExpr;
  this.size_.height += 4;
};
goog.inherits(Blockly.FieldVarInput, Blockly.Field);

Blockly.FieldVarInput.prototype.updateEditable = function() {
  Blockly.addClass_(/** @type {!Element} */ (this.fieldGroup_),
                      'blocklyFieldVarInput');

};

Blockly.FieldVarInput.prototype.getPath = function(width)
{
  var width_ = width+4;

  var inlineSteps = [];
  if(this.typeExpr)
  {
    inlineSteps.push('M 0,-2');

    Blockly.BlockSvg.renderTypeExpr(this.typeExpr, inlineSteps, 'down');

    var height = Blockly.BlockSvg.getTypeExprHeight(this.typeExpr);
    this.size_.height = height + 10;
    if(height < 23)
      height = 23;

    inlineSteps.push('M 0,' + (height - 6) ) ;

    inlineSteps.push('l 0 4 l ' + width_ + ' 0 l 0 -' +height + ' l -' + width_ + ' 0');
  }
  else
  {
      inlineSteps.push('M 0,4');
      inlineSteps.push('a 6,6,0,0,0,0,12');
      inlineSteps.push('l 0 4 l '+ width_ + ' 0 l 0 -20 l -' + width_ + ' 0 z');
  }

  return inlineSteps.join(' ');
};

Blockly.FieldVarInput.prototype.init = function() {
  if (this.fieldGroup_) {
    // Field has already been initialized once.
    return;
  }
  // Build the DOM.
  this.fieldGroup_ = Blockly.createSvgElement('g', {}, null);
  if (!this.visible_) {
    this.fieldGroup_.style.display = 'none';
  }

  this.borderRect_ = Blockly.createSvgElement('path',
       {'class': 'blocklyFieldVarInput',
       'd': this.getPath(this.size_.width)},
       this.fieldGroup_);

  /** @type {!Element} */
  this.textElement_ = Blockly.createSvgElement('text',
      {'class': 'blocklyText', 'y': 15, 'x':6},
      this.fieldGroup_);

    this.updateEditable();
  this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_);
  this.mouseUpWrapper_ =
      Blockly.bindEvent_(this.fieldGroup_, 'mouseup', this, this.onMouseUp_);
  this.mouseDownWrapper_ =
      Blockly.bindEvent_(this.fieldGroup_, 'mousedown', this, this.onMouseDown_);

  // Force a render.
  this.updateTextNode_();
};

Blockly.FieldVarInput.prototype.render_ = function() {
  if (this.visible_ && this.textElement_) {
    var key = this.textElement_.textContent + '\n' +
        this.textElement_.className.baseVal;
    if (Blockly.Field.cacheWidths_ && Blockly.Field.cacheWidths_[key]) {
      var width = Blockly.Field.cacheWidths_[key];
    } else {
      try {
        var width = this.textElement_.getComputedTextLength();
      } catch (e) {
        // MSIE 11 is known to throw "Unexpected call to method or property
        // access." if Blockly is hidden.
        var width = this.textElement_.textContent.length * 8;
      }
      if (Blockly.Field.cacheWidths_) {
        Blockly.Field.cacheWidths_[key] = width;
      }
    }
    if (this.borderRect_) {
      this.borderRect_.setAttribute('d', this.getPath(width + Blockly.BlockSvg.SEP_SPACE_X));
    }
  } else {
    var width = 0;
  }
  this.size_.width = width;
};

Blockly.FieldVarInput.prototype.render_ = function() {
  if (this.visible_ && this.textElement_) {
    var key = this.textElement_.textContent + '\n' +
        this.textElement_.className.baseVal;
    if (Blockly.Field.cacheWidths_ && Blockly.Field.cacheWidths_[key]) {
      var width = Blockly.Field.cacheWidths_[key];
    } else {
      try {
        var width = this.textElement_.getComputedTextLength();
      } catch (e) {
        // MSIE 11 is known to throw "Unexpected call to method or property
        // access." if Blockly is hidden.
        var width = this.textElement_.textContent.length * 8;
      }
      if (Blockly.Field.cacheWidths_) {
        Blockly.Field.cacheWidths_[key] = width;
      }
    }
    if (this.borderRect_) {
      this.borderRect_.setAttribute('width',
          width + Blockly.BlockSvg.SEP_SPACE_X);
      this.borderRect_.setAttribute('d',this.getPath(width + Blockly.BlockSvg.SEP_SPACE_X));
    }
  } else {
    var width = 0;
  }
  this.size_.width = width+10;
};

/**
 * Point size of text.  Should match blocklyText's font-size in CSS.
 */
Blockly.FieldVarInput.FONTSIZE = 11;

/**
 * Close the input widget if this input is being deleted.
 */
Blockly.FieldVarInput.prototype.dispose = function() {
  Blockly.WidgetDiv.hideIfOwner(this);
  Blockly.FieldVarInput.superClass_.dispose.call(this);
};

/**
 * Set the text in this field.
 * @param {?string} text New text.
 * @override
 */
Blockly.FieldVarInput.prototype.setValue = function(text) {
  if (text === null) {
    return;  // No change if null.
  }
  Blockly.Field.prototype.setValue.call(this, text);
};

Blockly.FieldVarInput.prototype.showEditor_ = function(){};

Blockly.FieldVarInput.prototype.onMouseDown_ = function(e){
  if(this.sourceBlock_.isInFlyout )
    return;
  var name = this.getValue();
  Blockly.dragMode_ = Blockly.DRAG_NONE;
  this.sourceBlock_.setDragging_(false);
  this.sourceBlock_.onMouseUp_(e);
  this.sourceBlock_.unselect();

  var container = goog.dom.createDom('block');
  container.setAttribute('type','vars_local');

  var field = goog.dom.createDom('field',null,name);
  field.setAttribute('name','NAME');
  container.appendChild(field);

  var mutation = goog.dom.createDom('mutation');
  if(this.typeExpr){
    var typeDom = this.typeExpr.toDom();
    mutation.appendChild(typeDom);
  }
  container.appendChild(mutation);

  var curBlock = Blockly.Xml.domToBlock(container, Blockly.getMainWorkspace());
  curBlock.parent_ = this.sourceBlock_;

  if(this.typeExpr)
    curBlock.setOutputTypeExpr(this.typeExpr);
  curBlock.render();

  var targetWorkspace = Blockly.getMainWorkspace();
  this.workspace_ = Blockly.getMainWorkspace();

  var svgRootOld = this.sourceBlock_.getSvgRoot();
  var xyOld = Blockly.getSvgXY_(svgRootOld, targetWorkspace);

  var element = document.getElementById('blocklyDiv');
  var rect = element.getBoundingClientRect();

  var mouseX = e.clientX - rect.left;
  var mouseY = e.clientY - rect.top;

  var scale = this.workspace_.scale;

  var svgRootNew = curBlock.getSvgRoot();
  var xyNew = Blockly.getSvgXY_(svgRootNew, targetWorkspace);

  var blockOffsetX = xyNew.x;
  var blockOffsetY = xyNew.y;

  var offsetX = mouseX - blockOffsetX;
  var offsetY = mouseY - blockOffsetY;

  offsetX /= scale;
  offsetY /= scale;

  curBlock.moveBy(offsetX, offsetY);
  curBlock.moveBy(-curBlock.getHeightWidth().width/2, -curBlock.getHeightWidth().height/2);

  curBlock.onMouseDown_(e);
  Blockly.dragMode_ = Blockly.DRAG_FREE;
  curBlock.setDragging_(true);

};

<|endoftext|>