<commit_before>
import Ember from 'ember';
import config from '../config/environment';

var modelReservedKeyword = ['default', 'basic', 'application', 'widgets', 'object', 'collection', 'model', 'outlet'];

var defaultViewConfiguration = {
    empty: {
        new: {
            widgets: [
                {type: 'model-form'}
            ]
        }
    },
    model: {
        index: {
            widgets: [
                {type: 'model-display'}
            ]
        },

        edit: {
            widgets: [
                {type: 'model-form'}
            ]
        }
    },
    collection: {
        index: {
            widgets: [
                {type: 'collection-list'}
            ]
        }
    }
};

/** check reserved keywords and fill
 *  'auto' views with default configuration
 */
export function initialize(container, application) {

    var models = config.APP.structure.models;

    var modelViews, views;

    Ember.keys(models).forEach(function(modelType) {

        // check reserved model keywords
        if (modelReservedKeyword.indexOf(modelType.toLowerCase()) > -1) {
            throw("Eureka: '"+modelType+"' is a reserved keyword. Don't use it as model name");
        }

        modelViews = models[modelType].views;

        if (modelViews === undefined) {
            return;
        }

        // iterate over view type: <modelType>.views.{collection, model, empty}
        Ember.keys(modelViews).forEach(function(viewType) {

            views = Ember.get(modelViews, viewType);

            if (views === undefined) {
                return ;
            }

            // iterate over views : <modelType>.views.{colleciton, model, empty}.<viewName>
            Ember.keys(views).forEach(function(viewName) {

                // fill 'auto' views with default configuration
                if (Ember.get(views, viewName) === 'auto') {
                    config.APP.structure.models[modelType].views[viewType][viewName] = defaultViewConfiguration[viewType][viewName];
                }
            });
        });
    });

    var appConfig = Ember.Object.create(config.APP);

    application.register('appConfig:main', appConfig, {instantiate: false, singleton: true});
    application.inject('route', 'appConfig', 'appConfig:main');
    application.inject('controller', 'appConfig', 'appConfig:main');
    application.inject('model', 'appConfig', 'appConfig:main');
}

export default {
  name: 'eureka-structure',
  initialize: initialize
};
<commit_msg>update to take the renamed collection-list widget<commit_after>
import Ember from 'ember';
import config from '../config/environment';

var modelReservedKeyword = ['default', 'basic', 'application', 'widgets', 'object', 'collection', 'model', 'outlet'];

var defaultViewConfiguration = {
    empty: {
        new: {
            widgets: [
                {type: 'model-form'}
            ]
        }
    },
    model: {
        index: {
            widgets: [
                {type: 'model-display'}
            ]
        },

        edit: {
            widgets: [
                {type: 'model-form'}
            ]
        }
    },
    collection: {
        index: {
            widgets: [
                {type: 'collection-display'}
            ]
        }
    }
};

/** check reserved keywords and fill
 *  'auto' views with default configuration
 */
export function initialize(container, application) {

    var models = config.APP.structure.models;

    var modelViews, views;

    Ember.keys(models).forEach(function(modelType) {

        // check reserved model keywords
        if (modelReservedKeyword.indexOf(modelType.toLowerCase()) > -1) {
            throw("Eureka: '"+modelType+"' is a reserved keyword. Don't use it as model name");
        }

        modelViews = models[modelType].views;

        if (modelViews === undefined) {
            return;
        }

        // iterate over view type: <modelType>.views.{collection, model, empty}
        Ember.keys(modelViews).forEach(function(viewType) {

            views = Ember.get(modelViews, viewType);

            if (views === undefined) {
                return ;
            }

            // iterate over views : <modelType>.views.{colleciton, model, empty}.<viewName>
            Ember.keys(views).forEach(function(viewName) {

                // fill 'auto' views with default configuration
                if (Ember.get(views, viewName) === 'auto') {
                    config.APP.structure.models[modelType].views[viewType][viewName] = defaultViewConfiguration[viewType][viewName];
                }
            });
        });
    });

    var appConfig = Ember.Object.create(config.APP);

    application.register('appConfig:main', appConfig, {instantiate: false, singleton: true});
    application.inject('route', 'appConfig', 'appConfig:main');
    application.inject('controller', 'appConfig', 'appConfig:main');
    application.inject('model', 'appConfig', 'appConfig:main');
}

export default {
  name: 'eureka-structure',
  initialize: initialize
};
<|endoftext|>


<commit_before>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: See license.txt

frappe.provide("frappe.activity");

frappe.pages['activity'].on_page_load = function(wrapper) {
	var me = this;

	frappe.ui.make_app_page({
		parent: wrapper,
		single_column: true
	});

	me.page = wrapper.page;

	me.page.set_title(__("Activity"));

	frappe.model.with_doctype("Communication", function() {
		me.page.list = new frappe.ui.Listing({
			hide_refresh: true,
			page: me.page,
			method: 'frappe.desk.page.activity.activity.get_feed',
			parent: $("

").appendTo(me.page.main),
			render_row: function(row, data) {
				new frappe.activity.Feed(row, data);
			},
			show_filters: true,
			doctype: "Communication",
 			get_args: function() {
				if (frappe.route_options && frappe.route_options.show_likes) {
					delete frappe.route_options.show_likes;
					return {
						show_likes: true
					}
				} else {
					return {}
				}
			}
		});

		me.page.list.run();

		me.page.set_primary_action(__("Refresh"), function() {
			me.page.list.filter_list.clear_filters();
			me.page.list.run();
		}, "octicon octicon-sync");
	});

	frappe.activity.render_heatmap(me.page);

	me.page.main.on("click", ".activity-message", function() {
		var link_doctype = $(this).attr("data-link-doctype"),
			link_name = $(this).attr("data-link-name"),
			doctype = $(this).attr("data-doctype"),
			docname = $(this).attr("data-docname");

		if (doctype && docname) {
			if (link_doctype && link_name) {
				frappe.route_options = {
					scroll_to: { "doctype": doctype, "name": docname }
				}
			}

			frappe.set_route(["Form", link_doctype || doctype, link_name || docname]);
		}
	});

	// Build Report Button
	if(frappe.boot.user.can_get_report.indexOf("Feed")!=-1) {
		this.page.add_menu_item(__('Build Report'), function() {
			frappe.set_route('Report', "Feed");
		}, 'icon-th')
	}

	this.page.add_menu_item(__('Show Likes'), function() {
		frappe.route_options = {
			show_likes: true
		};
		me.page.list.run();
	}, 'octicon octicon-heart');
};

frappe.pages['activity'].on_page_show = function() {
	frappe.breadcrumbs.add("Desk");
}

frappe.activity.last_feed_date = false;
frappe.activity.Feed = Class.extend({
	init: function(row, data) {
		this.scrub_data(data);
		this.add_date_separator(row, data);
		if(!data.add_class)
			data.add_class = "label-default";

		data.link = "";
		if (data.link_doctype && data.link_name) {
			data.link = frappe.format(data.link_name, {fieldtype: "Link", options: data.link_doctype},
				{label: __(data.link_doctype) + " " + __(data.link_name)});

		} else if (data.feed_type==="Comment" && data.comment_type==="Comment") {
			// hack for backward compatiblity
			data.link_doctype = data.reference_doctype;
			data.link_name = data.reference_name;
			data.reference_doctype = "Communication";
			data.reference_name = data.name;

			data.link = frappe.format(data.link_name, {fieldtype: "Link", options: data.link_doctype},
				{label: __(data.link_doctype) + " " + __(data.link_name)});

		} else if (data.reference_doctype && data.reference_name) {
			data.link = frappe.format(data.reference_name, {fieldtype: "Link", options: data.reference_doctype},
				{label: __(data.reference_doctype) + " " + __(data.reference_name)});
		}

		$(row)
			.append(frappe.render_template("activity_row", data))
			.find("a").addClass("grey");
	},
	scrub_data: function(data) {
		data.by = frappe.user.full_name(data.owner);
		data.avatar = frappe.avatar(data.owner);

		data.icon = "icon-flag";

		// color for comment
		data.add_class = {
			"Comment": "label-danger",
			"Assignment": "label-warning",
			"Login": "label-default"
		}[data.comment_type || data.communication_medium] || "label-info"

		data.when = comment_when(data.creation);
		data.feed_type = data.comment_type || data.communication_medium;
	},
	add_date_separator: function(row, data) {
		var date = dateutil.str_to_obj(data.creation);
		var last = frappe.activity.last_feed_date;

		if((last && dateutil.obj_to_str(last) != dateutil.obj_to_str(date)) || (!last)) {
			var diff = dateutil.get_day_diff(dateutil.get_today(), dateutil.obj_to_str(date));
			if(diff < 1) {
				pdate = 'Today';
			} else if(diff < 2) {
				pdate = 'Yesterday';
			} else {
				pdate = dateutil.global_date_format(date);
			}
			data.date_sep = pdate;
			data.date_class = pdate=='Today' ? "date-indicator blue" : "date-indicator";
		} else {
			data.date_sep = null;
			data.date_class = "";
		}
		frappe.activity.last_feed_date = date;
	}
});

frappe.activity.render_heatmap = function(page) {
	var me = this;
	$('

').prependTo(page.main);

	frappe.call({
		method: "frappe.desk.page.activity.activity.get_heatmap_data",
		callback: function(r) {
			if(r.message) {
				var legend = [];
				var max = Math.max.apply(this, $.map(r.message, function(v) { return v }));
				var legend = [cint(max/5), cint(max*2/5), cint(max*3/5), cint(max*4/5)];
				heatmap = new CalHeatMap();
				heatmap.init({
					itemSelector: ".heatmap",
					domain: "month",
					subDomain: "day",
					start: moment().subtract(1, 'year').add(1, 'month').toDate(),
					cellSize: 9,
					cellPadding: 2,
					domainGutter: 2,
					range: 12,
					domainLabelFormat: function(date) {
						return moment(date).format("MMM").toUpperCase();
					},
					displayLegend: false,
					legend: legend,
					tooltip: true,
					subDomainTitleFormat: {
						empty: "{date}",
						filled: "{count} actions on {date}"
					},
					subDomainDateFormat: "%d-%b"
				});

				heatmap.update(r.message);
			}
		}
	})
}<commit_msg>[ui] fix activity heatmap popover<commit_after>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: See license.txt

frappe.provide("frappe.activity");

frappe.pages['activity'].on_page_load = function(wrapper) {
	var me = this;

	frappe.ui.make_app_page({
		parent: wrapper,
		single_column: true
	});

	me.page = wrapper.page;

	me.page.set_title(__("Activity"));

	frappe.model.with_doctype("Communication", function() {
		me.page.list = new frappe.ui.Listing({
			hide_refresh: true,
			page: me.page,
			method: 'frappe.desk.page.activity.activity.get_feed',
			parent: $("

").appendTo(me.page.main),
			render_row: function(row, data) {
				new frappe.activity.Feed(row, data);
			},
			show_filters: true,
			doctype: "Communication",
 			get_args: function() {
				if (frappe.route_options && frappe.route_options.show_likes) {
					delete frappe.route_options.show_likes;
					return {
						show_likes: true
					}
				} else {
					return {}
				}
			}
		});

		me.page.list.run();

		me.page.set_primary_action(__("Refresh"), function() {
			me.page.list.filter_list.clear_filters();
			me.page.list.run();
		}, "octicon octicon-sync");
	});

	frappe.activity.render_heatmap(me.page);

	me.page.main.on("click", ".activity-message", function() {
		var link_doctype = $(this).attr("data-link-doctype"),
			link_name = $(this).attr("data-link-name"),
			doctype = $(this).attr("data-doctype"),
			docname = $(this).attr("data-docname");

		if (doctype && docname) {
			if (link_doctype && link_name) {
				frappe.route_options = {
					scroll_to: { "doctype": doctype, "name": docname }
				}
			}

			frappe.set_route(["Form", link_doctype || doctype, link_name || docname]);
		}
	});

	// Build Report Button
	if(frappe.boot.user.can_get_report.indexOf("Feed")!=-1) {
		this.page.add_menu_item(__('Build Report'), function() {
			frappe.set_route('Report', "Feed");
		}, 'icon-th')
	}

	this.page.add_menu_item(__('Show Likes'), function() {
		frappe.route_options = {
			show_likes: true
		};
		me.page.list.run();
	}, 'octicon octicon-heart');
};

frappe.pages['activity'].on_page_show = function() {
	frappe.breadcrumbs.add("Desk");
}

frappe.activity.last_feed_date = false;
frappe.activity.Feed = Class.extend({
	init: function(row, data) {
		this.scrub_data(data);
		this.add_date_separator(row, data);
		if(!data.add_class)
			data.add_class = "label-default";

		data.link = "";
		if (data.link_doctype && data.link_name) {
			data.link = frappe.format(data.link_name, {fieldtype: "Link", options: data.link_doctype},
				{label: __(data.link_doctype) + " " + __(data.link_name)});

		} else if (data.feed_type==="Comment" && data.comment_type==="Comment") {
			// hack for backward compatiblity
			data.link_doctype = data.reference_doctype;
			data.link_name = data.reference_name;
			data.reference_doctype = "Communication";
			data.reference_name = data.name;

			data.link = frappe.format(data.link_name, {fieldtype: "Link", options: data.link_doctype},
				{label: __(data.link_doctype) + " " + __(data.link_name)});

		} else if (data.reference_doctype && data.reference_name) {
			data.link = frappe.format(data.reference_name, {fieldtype: "Link", options: data.reference_doctype},
				{label: __(data.reference_doctype) + " " + __(data.reference_name)});
		}

		$(row)
			.append(frappe.render_template("activity_row", data))
			.find("a").addClass("grey");
	},
	scrub_data: function(data) {
		data.by = frappe.user.full_name(data.owner);
		data.avatar = frappe.avatar(data.owner);

		data.icon = "icon-flag";

		// color for comment
		data.add_class = {
			"Comment": "label-danger",
			"Assignment": "label-warning",
			"Login": "label-default"
		}[data.comment_type || data.communication_medium] || "label-info"

		data.when = comment_when(data.creation);
		data.feed_type = data.comment_type || data.communication_medium;
	},
	add_date_separator: function(row, data) {
		var date = dateutil.str_to_obj(data.creation);
		var last = frappe.activity.last_feed_date;

		if((last && dateutil.obj_to_str(last) != dateutil.obj_to_str(date)) || (!last)) {
			var diff = dateutil.get_day_diff(dateutil.get_today(), dateutil.obj_to_str(date));
			if(diff < 1) {
				pdate = 'Today';
			} else if(diff < 2) {
				pdate = 'Yesterday';
			} else {
				pdate = dateutil.global_date_format(date);
			}
			data.date_sep = pdate;
			data.date_class = pdate=='Today' ? "date-indicator blue" : "date-indicator";
		} else {
			data.date_sep = null;
			data.date_class = "";
		}
		frappe.activity.last_feed_date = date;
	}
});

frappe.activity.render_heatmap = function(page) {
	var me = this;
	$('
\

\

').prependTo(page.main);

	frappe.call({
		method: "frappe.desk.page.activity.activity.get_heatmap_data",
		callback: function(r) {
			if(r.message) {
				var legend = [];
				var max = Math.max.apply(this, $.map(r.message, function(v) { return v }));
				var legend = [cint(max/5), cint(max*2/5), cint(max*3/5), cint(max*4/5)];
				heatmap = new CalHeatMap();
				heatmap.init({
					itemSelector: ".heatmap",
					domain: "month",
					subDomain: "day",
					start: moment().subtract(1, 'year').add(1, 'month').toDate(),
					cellSize: 9,
					cellPadding: 2,
					domainGutter: 2,
					range: 12,
					domainLabelFormat: function(date) {
						return moment(date).format("MMM").toUpperCase();
					},
					displayLegend: false,
					legend: legend,
					tooltip: true,
					subDomainTitleFormat: {
						empty: "{date}",
						filled: "{count} actions on {date}"
					},
					subDomainDateFormat: "%d-%b"
				});

				heatmap.update(r.message);
			}
		}
	})
}<|endoftext|>


<commit_before>/*jshint node:true */
var express = require('express');
var u = require('underscore');
var JSON3 = require('json3');
var snippets = require('./snippets');
var proxy = require('./proxy-request');
var cloudflare = require('./cloudflare');
var contentHelper = require('./content-helper');

var router = express.Router();

var serveLandingPage = function(req, res) {
  res.render('index.ejs', {
    layout: false,
    host: req.headers.host,
    nodeVersion: process.version,
    snippets: snippets
  });
};

var passBackHeaders = function(incomingHeaders) {
  // remove those that node should generate
  var resultHeaders = u.omit(incomingHeaders,
    'connection',
    'content-length',
    'server',
    'x-frame-options'
  );

  return cloudflare.filterHeaders(resultHeaders);
};

var errorToJson = function(error) {
  var body = JSON3.stringify({ error: error.message });
  return {
    status: 502, // bad gateway
    body: body
  };
};

var respond = function(res, result) {
  res.status(result.status);

  if (!res.get('content-type')){
    if (contentHelper.isValidJson(result.body)){
      res.set('content-type', 'application/json');
    } else {
      res.set('content-type', 'text/plain');
    }
  }

  res.send(result.body);
};

router.get('/', function(req, res) {
  var query = req.query;
  var apiUrl = query.url || query.src;

  if (!apiUrl){
    // serve landing page
    serveLandingPage(req, res);
  } else {
    // do proxy

    var promise = proxy(apiUrl, req.headers);
    promise.then(
      function(response) {
        var responseHeaders = passBackHeaders(response.headers);
        res.set(responseHeaders);

        return {
          status: response.statusCode,
          body: response.body
        };
      }
    ).fail(
      // keep this right before respond() to handle errors from any previous steps
      errorToJson
    ).then(
      u.partial(respond, res)
    ).done();
  }
});

module.exports = router;
<commit_msg>refactor router<commit_after>/*jshint node:true */
var express = require('express');
var u = require('underscore');
var JSON3 = require('json3');
var snippets = require('./snippets');
var proxy = require('./proxy-request');
var cloudflare = require('./cloudflare');
var contentHelper = require('./content-helper');

var router = express.Router();

var serveLandingPage = function(req, res) {
  res.render('index.ejs', {
    layout: false,
    host: req.headers.host,
    nodeVersion: process.version,
    snippets: snippets
  });
};

var passBackHeaders = function(incomingHeaders) {
  // remove those that node should generate
  var resultHeaders = u.omit(incomingHeaders,
    'connection',
    'content-length',
    'server',
    'x-frame-options'
  );

  return cloudflare.filterHeaders(resultHeaders);
};

var errorToJson = function(error) {
  var body = JSON3.stringify({ error: error.message });
  return {
    status: 502, // bad gateway
    body: body
  };
};

var respond = function(res, result) {
  res.status(result.status);

  if (!res.get('content-type')){
    if (contentHelper.isValidJson(result.body)){
      res.set('content-type', 'application/json');
    } else {
      res.set('content-type', 'text/plain');
    }
  }

  res.send(result.body);
};

var getApiUrl = function(req) {
  var query = req.query;
  return query.url || query.src;
};

var doProxy = function(apiUrl, req, res) {
  var promise = proxy(apiUrl, req.headers);
  promise.then(
    function(response) {
      var responseHeaders = passBackHeaders(response.headers);
      res.set(responseHeaders);

      return {
        status: response.statusCode,
        body: response.body
      };
    }
  ).fail(
    // keep this right before respond() to handle errors from any previous steps
    errorToJson
  ).then(
    u.partial(respond, res)
  ).done();
};

router.get('/', function(req, res) {
  var apiUrl = getApiUrl(req);
  if (apiUrl){
    doProxy(apiUrl, req, res);
  } else {
    serveLandingPage(req, res);
  }
});

module.exports = router;
<|endoftext|>


<commit_before>var sequences;
(function (sequences) {
    'use strict';

    Object.defineProperties(sequences, {
        numbers: {
            writable: true,
            value: function numbers(initialValue) {
                return function* () {
                    var n = initialValue || 0;
                    while (true) {
                        yield n++;
                    }
                };
            }
        },
        isGenerator: {
            writable: true,
            value: function (candidate) {
                return typeof candidate === 'function' && Object.getPrototypeOf(candidate) === proto;
            }
        },
        toGenerator: {
            writable: true,
            value: function toGenerator(source, initialValue) {
                if (typeof source === 'function') {
                    return function* generatorFromFunction() {
                        var r = initialValue;
                        while (true) {
                            r = source(r);
                            if (r && ('value' in r) && ('done' in r)) {
                                if (r.done) {
                                    break;
                                }
                                yield r.value;
                            } else {
                                yield r;
                            }
                        }
                    };
                }
                if (typeof source.length === 'number') {
                    return function* generatorFromCollection() {
                        var i = initialValue || 0;
                        for (; i < source.length; ++i) {
                            yield source[i];
                        }
                    };
                }
                if (source && typeof source === 'object') {
                    return function* generatorFromObject() {
                        for (var p in source) {
                            yield [p, source[p]];
                        }
                    };
                }
                return function* generatorFromValue() {
                    yield source;
                };
            }
        }
    });

    var proto = Object.getPrototypeOf(sequences.numbers());

    function filterFunction(value, thisArg) {
        return typeof value === 'function' ?
            value.bind(thisArg) :
            Array.isArray(value) ?
                function (v) { return value.indexOf(v) !== -1; } :
                Object.is.bind(Object, value);
    }
    function not(func) {
        return function () {
            return !func.apply(this, arguments);
        }
    }

    Object.defineProperties(Object.getPrototypeOf(proto), {
        forEach: {
            writable: true,
            value: function forEach(callback, thisArg) {
                for (var i of this()) {
                    callback.call(thisArg, i);
                }
            }
        },
        until: {
            writable: true,
            value: function until(callback, thisArg) {
                callback = filterFunction(callback, thisArg);
                var self = this;
                return function* () {
                    for (var i of self()) {
                        if (callback(i) === true) {
                            break;
                        }
                        yield i;
                    }
                };
            }
        },
        asLongAs: {
            writable: true,
            value: function asLongAs(callback, thisArg) {
                callback = filterFunction(callback, thisArg);
                return this.until(not(callback));
            }
        },
        head: {
            writable: true,
            value: function head(length) {
                length || (length = 1);
                var self = this;
                return function* () {
                    var counter = 0;
                    for (var i of self()) {
                        if (++counter > length) {
                            break;
                        }
                        yield i;
                    }
                };
            }
        },
        filter: {
            writable: true,
            value: function filter(callback, thisArg) {
                callback = filterFunction(callback, thisArg);
                var self = this;
                return function* () {
                    for (var i of self()) {
                        if (callback(i)) {
                            yield i;
                        }
                    }
                };
            }
        },
        exclude: {
            writable: true,
            value: function exclude(callback, thisArg) {
                callback = filterFunction(callback, thisArg);
                return this.filter(not(callback));
            }
        },
        skip: {
            writable: true,
            value: function skip(number) {
                number || (number = 1);
                var self = this;
                return function* () {
                    var iter = self();
                    var counter = 0;
                    for (var i of iter) {
                        if (++counter > number) {
                            yield i;
                        }
                    }
                };
            }
        },
        map: {
            writable: true,
            value: function map(callback, thisArg) {
                var self = this;
                return function* () {
                    for (var i of self()) {
                        yield callback.call(thisArg, i);
                    }
                };
            }
        },
        flatten: {
            writable: true,
            value: function flatten() {
                var self = this();
                return function* () {
                    for (var i of self()) {
                        if (sequences.isGenerator(i)) {
                            yield* i.flatten()();
                        } else {
                            yield i;
                        }
                    }
                };
            }
        },
        loop: {
            writable: true,
            value: function loop(times) {
                times || (times = Infinity);
                var self = this;
                return function* () {
                    for (var i = 0; i < times; ++i) {
                        yield* self();
                    }
                };
            }
        },
        concat: {
            writable: true,
            value: function concat() {
                var args = Array.prototype.slice.apply(arguments).filter(sequences.isGenerator);
                var self = this;
                return function* () {
                    yield* self();
                    for (var i = 0; i < args.length; ++i) {
                        yield* args[i]();
                    }
                };
            }
        },
        reduce: {
            writable: true,
            value: function reduce(callback, initialValue) {
                var r = initialValue;
                for (var i of this()) {
                    r = callback(r, i);
                }
                return r;
            }
        },
        tee: {
            writable: true,
            value: function tee() {
                sequences.toGenerator(arguments).filter(function (arg) {
                    return typeof arg === 'function';
                }).forEach(function (arg) {
                    arg(this);
                }.bind(this));
                return this;
            }
        },
        toArray: {
            writable: true,
            value: function toArray() {
                return this.reduce(function (a, v) {
                    return a.push(v), a;
                }, []);
            }
        }
    });
}(sequences || (sequences = {})));
<commit_msg>typeo<commit_after>var sequences;
(function (sequences) {
    'use strict';

    Object.defineProperties(sequences, {
        numbers: {
            writable: true,
            value: function numbers(initialValue) {
                return function* () {
                    var n = initialValue || 0;
                    while (true) {
                        yield n++;
                    }
                };
            }
        },
        isGenerator: {
            writable: true,
            value: function (candidate) {
                return typeof candidate === 'function' && Object.getPrototypeOf(candidate) === proto;
            }
        },
        toGenerator: {
            writable: true,
            value: function toGenerator(source, initialValue) {
                if (typeof source === 'function') {
                    return function* generatorFromFunction() {
                        var r = initialValue;
                        while (true) {
                            r = source(r);
                            if (r && ('value' in r) && ('done' in r)) {
                                if (r.done) {
                                    break;
                                }
                                yield r.value;
                            } else {
                                yield r;
                            }
                        }
                    };
                }
                if (typeof source.length === 'number') {
                    return function* generatorFromCollection() {
                        var i = initialValue || 0;
                        for (; i < source.length; ++i) {
                            yield source[i];
                        }
                    };
                }
                if (source && typeof source === 'object') {
                    return function* generatorFromObject() {
                        for (var p in source) {
                            yield [p, source[p]];
                        }
                    };
                }
                return function* generatorFromValue() {
                    yield source;
                };
            }
        }
    });

    var proto = Object.getPrototypeOf(sequences.numbers());

    function filterFunction(value, thisArg) {
        return typeof value === 'function' ?
            value.bind(thisArg) :
            Array.isArray(value) ?
                function (v) { return value.indexOf(v) !== -1; } :
                Object.is.bind(Object, value);
    }
    function not(func) {
        return function () {
            return !func.apply(this, arguments);
        }
    }

    Object.defineProperties(proto, {
        forEach: {
            writable: true,
            value: function forEach(callback, thisArg) {
                for (var i of this()) {
                    callback.call(thisArg, i);
                }
            }
        },
        until: {
            writable: true,
            value: function until(callback, thisArg) {
                callback = filterFunction(callback, thisArg);
                var self = this;
                return function* () {
                    for (var i of self()) {
                        if (callback(i) === true) {
                            break;
                        }
                        yield i;
                    }
                };
            }
        },
        asLongAs: {
            writable: true,
            value: function asLongAs(callback, thisArg) {
                callback = filterFunction(callback, thisArg);
                return this.until(not(callback));
            }
        },
        head: {
            writable: true,
            value: function head(length) {
                length || (length = 1);
                var self = this;
                return function* () {
                    var counter = 0;
                    for (var i of self()) {
                        if (++counter > length) {
                            break;
                        }
                        yield i;
                    }
                };
            }
        },
        filter: {
            writable: true,
            value: function filter(callback, thisArg) {
                callback = filterFunction(callback, thisArg);
                var self = this;
                return function* () {
                    for (var i of self()) {
                        if (callback(i)) {
                            yield i;
                        }
                    }
                };
            }
        },
        exclude: {
            writable: true,
            value: function exclude(callback, thisArg) {
                callback = filterFunction(callback, thisArg);
                return this.filter(not(callback));
            }
        },
        skip: {
            writable: true,
            value: function skip(number) {
                number || (number = 1);
                var self = this;
                return function* () {
                    var iter = self();
                    var counter = 0;
                    for (var i of iter) {
                        if (++counter > number) {
                            yield i;
                        }
                    }
                };
            }
        },
        map: {
            writable: true,
            value: function map(callback, thisArg) {
                var self = this;
                return function* () {
                    for (var i of self()) {
                        yield callback.call(thisArg, i);
                    }
                };
            }
        },
        flatten: {
            writable: true,
            value: function flatten() {
                var self = this();
                return function* () {
                    for (var i of self()) {
                        if (sequences.isGenerator(i)) {
                            yield* i.flatten()();
                        } else {
                            yield i;
                        }
                    }
                };
            }
        },
        loop: {
            writable: true,
            value: function loop(times) {
                times || (times = Infinity);
                var self = this;
                return function* () {
                    for (var i = 0; i < times; ++i) {
                        yield* self();
                    }
                };
            }
        },
        concat: {
            writable: true,
            value: function concat() {
                var args = Array.prototype.slice.apply(arguments).filter(sequences.isGenerator);
                var self = this;
                return function* () {
                    yield* self();
                    for (var i = 0; i < args.length; ++i) {
                        yield* args[i]();
                    }
                };
            }
        },
        reduce: {
            writable: true,
            value: function reduce(callback, initialValue) {
                var r = initialValue;
                for (var i of this()) {
                    r = callback(r, i);
                }
                return r;
            }
        },
        tee: {
            writable: true,
            value: function tee() {
                sequences.toGenerator(arguments).filter(function (arg) {
                    return typeof arg === 'function';
                }).forEach(function (arg) {
                    arg(this);
                }.bind(this));
                return this;
            }
        },
        toArray: {
            writable: true,
            value: function toArray() {
                return this.reduce(function (a, v) {
                    return a.push(v), a;
                }, []);
            }
        }
    });
}(sequences || (sequences = {})));
<|endoftext|>


<commit_before>function toggles() {
	// Variables:
    var Button = $('#toggleButton')
	var theDiv = $('.theDiv')
    var currentState = sessionStorage.getItem('savedState')

	// Load previous state:
	if (currentState == 'false') { // Checks if the currentState of theDiv is True or False.
		Button.html('Toggle (The div is hidden)')
        theDiv.hide()
	} else {
		Button.html('Toggle (The div is visible)')
        theDiv.show()
	}

	// Toggle the div:
	Button.click(function(){
		theDiv.slideToggle('2000', 'easeInOutQuint').promise().done(function() {
			if (theDiv.css('display') == 'none') {
				Button.html('Toggle (The div is hidden)'), sessionStorage.setItem('savedState', 'false');
			} else {
				Button.html('Toggle (The div is visible)'), sessionStorage.setItem('savedState', 'true');
			}
		});
	});
}

window.onload = function () {
	toggles();
}<commit_msg>Update script-nodebug.js<commit_after>function toggles() {
	// Variables:
    var Button = $('#toggleButton')
	var theDiv = $('.theDiv')
    var currentState = sessionStorage.getItem('savedState')

	// Load previous state:
	if (currentState == 'false') { // Checks if the currentState of theDiv is True or False.
		Button.html('Toggle (The div is hidden)')
        theDiv.hide()
	} else {
		Button.html('Toggle (The div is visible)')
        theDiv.show()
	}

	// Toggle the div:
	Button.click(function(){
		theDiv.slideToggle(200, 'easeInOutQuint').promise().done(function() {
			if (theDiv.css('display') == 'none') {
				Button.html('Toggle (The div is hidden)'), sessionStorage.setItem('savedState', 'false');
			} else {
				Button.html('Toggle (The div is visible)'), sessionStorage.setItem('savedState', 'true');
			}
		});
	});
}

window.onload = function () {
	toggles();
}
<|endoftext|>


<commit_before>import $ from 'jquery';
import 'select2';
import { isNumeric } from '@utils';

const { api_geo_url, api_adresse_url } = gon.autocomplete || {};

const language = {
  errorLoading: function() {
    return 'Les résultats ne peuvent pas être chargés.';
  },
  inputTooLong: function(args) {
    var overChars = args.input.length - args.maximum;

    return 'Supprimez ' + overChars + ' caractère' + (overChars > 1 ? 's' : '');
  },
  inputTooShort: function(args) {
    var remainingChars = args.minimum - args.input.length;

    return (
      'Saisissez au moins ' +
      remainingChars +
      ' caractère' +
      (remainingChars > 1 ? 's' : '')
    );
  },
  loadingMore: function() {
    return 'Chargement de résultats supplémentaires…';
  },
  maximumSelected: function(args) {
    return (
      'Vous pouvez seulement sélectionner ' +
      args.maximum +
      ' élément' +
      (args.maximum > 1 ? 's' : '')
    );
  },
  noResults: function() {
    return 'Aucun résultat trouvé';
  },
  searching: function() {
    return 'Recherche en cours…';
  },
  removeAllItems: function() {
    return 'Supprimer tous les éléments';
  }
};

const baseOptions = {
  language,
  width: '100%'
};

const baseAjaxOptions = {
  delay: 250,
  cache: true,
  data({ term: nom }) {
    return {
      nom,
      fields: 'nom,code'
    };
  },
  processResults(data) {
    return {
      results: data.map(({ nom }) => ({ id: nom, text: nom }))
    };
  }
};

const regionsOptions = {
  ...baseOptions,
  minimumInputLength: 2,
  ajax: { url: `${api_geo_url}/regions`, ...baseAjaxOptions }
};

const communesOptions = {
  ...baseOptions,
  minimumInputLength: 2,
  ajax: { url: `${api_geo_url}/communes`, ...baseAjaxOptions }
};

const etranger99 = { id: '99 - Étranger', text: '99 - Étranger' };
const departementsOptions = {
  ...baseOptions,
  minimumInputLength: 1,
  ajax: {
    ...baseAjaxOptions,
    url: `${api_geo_url}/departements`,
    data({ term }) {
      const data = { fields: 'nom,code' };

      if (isNumeric(term)) {
        data.code = term.trim().padStart(2, '0');
      } else {
        data.nom = term;
      }

      return data;
    },
    processResults(data) {
      return {
        results: data
          .map(({ nom, code }) => ({
            id: `${code} - ${nom}`,
            text: `${code} - ${nom}`
          }))
          .concat([etranger99])
      };
    }
  }
};

const adresseOptions = {
  ...baseOptions,
  minimumInputLength: 2,
  ajax: {
    ...baseAjaxOptions,
    url: `${api_adresse_url}/search`,
    data({ term: q }) {
      return {
        q,
        limit: 5
      };
    },
    processResults(data) {
      return {
        results: data.features.map(({ properties: { label }, geometry }) => ({
          id: label,
          text: label,
          geometry
        }))
      };
    }
  }
};

const templateOption = ({ text }) =>
  $(
    `<span class="custom-select2-option"><span class="icon person"></span>${text}</span>`
  );

addEventListener('ds:page:update', () => {
  $('select.select2').select2(baseOptions);
  $('select.select2.departements').select2(departementsOptions);
  $('select.select2.regions').select2(regionsOptions);
  $('select.select2.communes').select2(communesOptions);
  $('select.select2.adresse').select2(adresseOptions);

  $('.columns-form select.select2-limited').select2({
    width: '300px',
    placeholder: 'Sélectionnez des colonnes',
    maximumSelectionLength: '5'
  });

  $('.recipients-form select.select2-limited').select2({
    language,
    width: '300px',
    placeholder: 'Sélectionnez des instructeurs',
    maximumSelectionLength: '30'
  });

  $('select.select2-limited.select-instructeurs').select2({
    language,
    dropdownParent: $('.instructeur-wrapper'),
    placeholder: 'Saisir l’adresse email de l’instructeur',
    tags: true,
    tokenSeparators: [',', ' '],
    templateResult: templateOption,
    templateSelection: templateOption
  });
});
<commit_msg>possibilite de selectionner un resultat quand il n'y a rien dans le champ adresse<commit_after>import $ from 'jquery';
import 'select2';
import { isNumeric } from '@utils';

const { api_geo_url, api_adresse_url } = gon.autocomplete || {};

const language = {
  errorLoading: function() {
    return 'Les résultats ne peuvent pas être chargés.';
  },
  inputTooLong: function(args) {
    var overChars = args.input.length - args.maximum;

    return 'Supprimez ' + overChars + ' caractère' + (overChars > 1 ? 's' : '');
  },
  inputTooShort: function(args) {
    var remainingChars = args.minimum - args.input.length;

    return (
      'Saisissez au moins ' +
      remainingChars +
      ' caractère' +
      (remainingChars > 1 ? 's' : '')
    );
  },
  loadingMore: function() {
    return 'Chargement de résultats supplémentaires…';
  },
  maximumSelected: function(args) {
    return (
      'Vous pouvez seulement sélectionner ' +
      args.maximum +
      ' élément' +
      (args.maximum > 1 ? 's' : '')
    );
  },
  noResults: function() {
    return 'Aucun résultat trouvé';
  },
  searching: function() {
    return 'Recherche en cours…';
  },
  removeAllItems: function() {
    return 'Supprimer tous les éléments';
  }
};

const baseOptions = {
  language,
  width: '100%'
};

const baseAjaxOptions = {
  delay: 250,
  cache: true,
  data({ term: nom }) {
    return {
      nom,
      fields: 'nom,code'
    };
  },
  processResults(data) {
    return {
      results: data.map(({ nom }) => ({ id: nom, text: nom }))
    };
  }
};

const regionsOptions = {
  ...baseOptions,
  minimumInputLength: 2,
  ajax: { url: `${api_geo_url}/regions`, ...baseAjaxOptions }
};

const communesOptions = {
  ...baseOptions,
  minimumInputLength: 2,
  ajax: { url: `${api_geo_url}/communes`, ...baseAjaxOptions }
};

const etranger99 = { id: '99 - Étranger', text: '99 - Étranger' };
const departementsOptions = {
  ...baseOptions,
  minimumInputLength: 1,
  ajax: {
    ...baseAjaxOptions,
    url: `${api_geo_url}/departements`,
    data({ term }) {
      const data = { fields: 'nom,code' };

      if (isNumeric(term)) {
        data.code = term.trim().padStart(2, '0');
      } else {
        data.nom = term;
      }

      return data;
    },
    processResults(data) {
      return {
        results: data
          .map(({ nom, code }) => ({
            id: `${code} - ${nom}`,
            text: `${code} - ${nom}`
          }))
          .concat([etranger99])
      };
    }
  }
};

const adresseOptions = {
  ...baseOptions,
  minimumInputLength: 2,
  ajax: {
    ...baseAjaxOptions,
    url: `${api_adresse_url}/search`,
    data({ term: q }) {
      return {
        q,
        limit: 5
      };
    },
    processResults(data) {
      let r = data.features.map(({ properties: { label }, geometry }) => ({
        id: label,
        text: label,
        geometry
      }));
      r.unshift({ id: data.query, text: data.query });
      return {
        results: r
      };
    }
  }
};

const templateOption = ({ text }) =>
  $(
    `<span class="custom-select2-option"><span class="icon person"></span>${text}</span>`
  );

addEventListener('ds:page:update', () => {
  $('select.select2').select2(baseOptions);
  $('select.select2.departements').select2(departementsOptions);
  $('select.select2.regions').select2(regionsOptions);
  $('select.select2.communes').select2(communesOptions);
  $('select.select2.adresse').select2(adresseOptions);

  $('.columns-form select.select2-limited').select2({
    width: '300px',
    placeholder: 'Sélectionnez des colonnes',
    maximumSelectionLength: '5'
  });

  $('.recipients-form select.select2-limited').select2({
    language,
    width: '300px',
    placeholder: 'Sélectionnez des instructeurs',
    maximumSelectionLength: '30'
  });

  $('select.select2-limited.select-instructeurs').select2({
    language,
    dropdownParent: $('.instructeur-wrapper'),
    placeholder: 'Saisir l’adresse email de l’instructeur',
    tags: true,
    tokenSeparators: [',', ' '],
    templateResult: templateOption,
    templateSelection: templateOption
  });
});
<|endoftext|>


<commit_before>const github = require('./lib/github')
const view = require('./lib/view')
const fail = require('./lib/fail')
const webdevquiz = require('./lib/webdevquiz')

var feeds

// Feed cache
require('./lib/feeds')
  .then(res => feeds = res)

module.exports = {
  '/api/github/xhr/:command': context => new Promise((res, rej) => {
    if (github.xhr[context.params.command]) {
      github.xhr[context.params.command]()
        .then(json => {
          context.body = json
          res()
        })
        .catch(err => fail(err))
    } else {
      rej()
    }
  }),
  '/api/view/xhr/:name': context => new Promise((res, rej) => {
    view.xhr(context.params.name)
      .then(html => {
        context.response = html
        context.response.type = 'text/plain'
        res()
      })
      .catch(e => {
        console.error(e)
        rej()
      })
  }),
  '/feed/:type': context => new Promise((res, rej) => {
    if (context.params.type === 'atom') {
      context.body = feeds[0]
      res()
    } else if (context.params.type === 'rss') {
      context.body = feeds[1]
      res()
    } else {
      rej()
    }
  }),
  '/webdevquiz': context => new Promise ((res, rej) => {
    webdevquiz(context)
    res()
  }),
  '/:p': context => new Promise((res, rej) => {
    // TODO Render 404
    context.response.status = 404
    res()
  })
}

<commit_msg>Fix the routes to the Atom/RSS feeds<commit_after>const github = require('./lib/github')
const view = require('./lib/view')
const fail = require('./lib/fail')
const webdevquiz = require('./lib/webdevquiz')

var feeds

// Feed cache
require('./lib/feeds')
  .then(res => feeds = res)

module.exports = {
  '/api/github/xhr/:command': context => new Promise((res, rej) => {
    if (github.xhr[context.params.command]) {
      github.xhr[context.params.command]()
        .then(json => {
          context.body = json
          res()
        })
        .catch(err => fail(err))
    } else {
      rej()
    }
  }),
  '/api/view/xhr/:name': context => new Promise((res, rej) => {
    view.xhr(context.params.name)
      .then(html => {
        context.response = html
        context.response.type = 'text/plain'
        res()
      })
      .catch(e => {
        console.error(e)
        rej()
      })
  }),
  '/feed/:type': context => new Promise((res, rej) => {
    if (context.params.type === 'atom.xml') {
      context.body = feeds[0]
      res()
    } else if (context.params.type === 'rss.xml') {
      context.body = feeds[1]
      res()
    } else {
      rej()
    }
  }),
  '/webdevquiz': context => new Promise ((res, rej) => {
    webdevquiz(context)
    res()
  }),
  '/:p': context => new Promise((res, rej) => {
    // TODO Render 404
    context.response.status = 404
    res()
  })
}

<|endoftext|>


<commit_before>var SnapChart = function(domId, options){
	var that = this,
		snap = Snap(domId),
		extremes = {},
		axis = {},
		plots = [],
		yLabelTransform = options.yLabelTransform || function(y){return y.toString();};

	this.types = {
		bar: 'bar',
		line: 'line',
		pie: 'pie',
		area: 'area'
	}

	var implemetations = {
		'bar': drawBar,
		'line': drawLine,
		'area': drawArea
	}

	function init(){
		populateExtremes();
		drawAxis();
		drawChart();
	};

	function populateExtremes(){

		extremes = {
			positions:{
				axis:{
					min:{
						x:40,
						y:10
					},
					max:{
						x:400,
						y:240
					}
				}
			},
			data:{
				limits: {
					min:0,
					max: _.reduce(options.data,function(memo,num){return num > memo ?num : memo;},0)
				}
			}
		};

		// adding values calulcated from initial dataset
		extremes.plots = {
			width: ((extremes.positions.axis.max.x - extremes.positions.axis.min.x) / options.data.length)
		};

		extremes.yLabels = calculateYaxisSteps();
		console.log(extremes);

	};

	function calculateYaxisSteps(){

		var numSteps,
			min,
			max,
			steps = [];

		var dataLimitMaxString = extremes.data.limits.max.toString();
		if(extremes.data.limits.max > 1){
			var mostSignificantDigit = parseInt(dataLimitMaxString[0]);
			var numSteps = mostSignificantDigit + 1;
			// var exponent = dataLimitMaxString.length == 1 ? 1 : dataLimitMaxString.length - 1;
			var exponent = Math.floor(Math.log(extremes.data.limits.max)/Math.log(10))
			var significantMagnitude = Math.pow(10, exponent);
			steps = [];
			for (var i = 0; i <= numSteps; i++){
				var step = i*significantMagnitude;
				steps.push(step);
			}
			min = steps[0];
			max = steps[steps.length-1];
		} else if (extremes.data.limits.max>0){
			var significantIndex = 2,
				digit = '';
			for(; significantIndex < dataLimitMaxString.length; significantIndex++){
				digit = dataLimitMaxString[significantIndex];
				if(dataLimitMaxString !== '0'){
					break;
				}
			}
			var significantMagnitude = Math.pow(10,significantIndex-1);
			var numSteps = parseInt(digit)+1;
			for (var i = 0; i <= numSteps; i++){
				var step = i/significantMagnitude;
				steps.push(step);
			}
			min = steps[0];
			max = steps[steps.length-1];
		}
		return {
			numberOfSteps: numSteps,
			steps: steps,
			min: min,
			max: max
		}
	}

	function calculteScaledY(y){
		var ratio = y / extremes.yLabels.max;
		return (extremes.positions.axis.max.y - extremes.positions.axis.min.y)*ratio;
	}

	function drawAxis(){
		var axisLineOptions = {stroke:'rgba(0,0,0,.5)', strokeWidth:1}

		axis.y = snap.line(
			extremes.positions.axis.min.x,
			extremes.positions.axis.min.y,
			extremes.positions.axis.min.x,
			extremes.positions.axis.max.y);
		axis.y.attr(axisLineOptions);

		axis.x = snap.line(
			extremes.positions.axis.min.x,
			extremes.positions.axis.max.y,
			extremes.positions.axis.max.x,
			extremes.positions.axis.max.y);
		axis.x.attr(axisLineOptions);

		// xaxis lables
		var xOffset = extremes.plots.width/2;
		axis.xLables = _.map(options.labels, function(label, i){
			var x = extremes.positions.axis.min.x + xOffset + (extremes.plots.width*i);
			var y = extremes.positions.axis.max.y + 15;
			var text = snap.text(x, y, label);
			text.attr({'text-anchor':'middle'})
			return text;
		});

		// yaxis labels
		axis.yLabels = _.map(extremes.yLabels.steps, function(step, i){
			console.log(step);
			var x = extremes.positions.axis.min.x - 5;
			var y = extremes.positions.axis.max.y - calculteScaledY(step);
			var label = yLabelTransform(step);
			var text = snap.text(x, y, label);
			text.attr({'text-anchor':'end', 'dominant-baseline':'middle'});
			return text;
		});

		// yaxis gridlines
		var axisGridLineOptions = {stroke:'rgba(0,0,0,.1)', strokeWidth:1}

		axis.yGridLines = _.map(extremes.yLabels.steps, function(step, i){
			if(step === 0) return;
			var y = extremes.positions.axis.max.y - calculteScaledY(step);
			var line = snap.line(extremes.positions.axis.min.x, y, extremes.positions.axis.max.x, y);
			line.attr(axisGridLineOptions);
		})

	};

	function drawChart(){
		var type = options.type || that.types.bar;
		implemetations[type]();
	};

	function drawBar(){
		var barWidthRatio = .9;
		var barMarginRatio = .05;

		var barWidth = extremes.plots.width*barWidthRatio;
		var barMarginWidth = extremes.plots.width*barMarginRatio;

		plots = _.map(options.data, function(value, key){
			var x = extremes.positions.axis.min.x + (key*barWidth) + (key*2*barMarginWidth) + barMarginWidth;
			var y = extremes.positions.axis.max.y
			var width = barWidth;
			var height = (calculteScaledY(value));
			// var bar = snap.rect(x, y - height, width, height);
			var bar = snap.rect(x, y, width, 0);
			bar.attr({fill:'rgba(0,175,255,.5)'});
			bar.animate({y:y-height,height:height}, 350, mina.easeout);
			return bar;
		});
	};

	function drawLine(){
		var plotPointWidth = extremes.plots.width;
		var path = '';
		var first = true;
		var preAnimationPlots = [];
		var dataPlots = [];
		var yMaxString = extremes.positions.axis.max.y;
		_.each(options.data, function(value, key){
			var pathLetter = 'L';
			if(first){
				pathLetter = 'M';
				first = false;
			}
			var x = plotPointWidth/2 + (plotPointWidth*key) + extremes.positions.axis.min.x;
			var y = calculteScaledY(value);
			dataPlots.push(pathLetter + x.toString() + ',' + y.toString());
			preAnimationPlots.push(pathLetter + x.toString() + ',' + yMaxString);
		});
		var path = snap.path(preAnimationPlots.join(','))
		path.attr({fill:'transparent', stroke:'rgba(0,175,255,.5)',strokeWidth:3})
		path.animate({d: dataPlots.join(',')}, 350, mina.easeout);

	};

	function drawArea(){
		var plotPointWidth = extremes.plots.width;
		var path = '';
		var preAnimationPlots = [];
		var dataPlots = [];
		var yMaxString = extremes.positions.axis.max.y;
		_.each(options.data, function(value, key){
			var pathLetter = 'L';
			var x = plotPointWidth/2 + (plotPointWidth*key) + extremes.positions.axis.min.x;
			var y = calculteScaledY(value);
			dataPlots.push(pathLetter + x.toString() + ',' + y.toString());
			preAnimationPlots.push(pathLetter + x.toString() + ',' + yMaxString);
		});
		var firstPoint = (
			'M'+
			(plotPointWidth/2 + extremes.positions.axis.min.x).toString() +
			','  +
			yMaxString
		);
		dataPlots.unshift(firstPoint);
		preAnimationPlots.unshift(firstPoint);

		var lastPoint = (
			'L'+
			(plotPointWidth/2 + (plotPointWidth * (options.data.length -1)) + extremes.positions.axis.min.x).toString() +
			',' +
			 yMaxString
		);
		dataPlots.push(lastPoint);
		var path = snap.path(preAnimationPlots.join(','))
		path.attr({fill:'rgba(0,175,255,.5)'})
		path.animate({d: dataPlots.join(',')}, 350, mina.easeout);

	};
	function drawPie(){
		console.log('pie chart not implemented yet');
	};

	this.update = function(options){
		console.log('not implemeted yet');
	}

	init();
	return that;
}<commit_msg>Fixed issue #12, line and area charts are no longer up-side-down<commit_after>var SnapChart = function(domId, options){
	var that = this,
		snap = Snap(domId),
		extremes = {},
		axis = {},
		plots = [],
		yLabelTransform = options.yLabelTransform || function(y){return y.toString();};

	this.types = {
		bar: 'bar',
		line: 'line',
		pie: 'pie',
		area: 'area'
	}

	var implemetations = {
		'bar': drawBar,
		'line': drawLine,
		'area': drawArea
	}

	function init(){
		populateExtremes();
		drawAxis();
		drawChart();
	};

	function populateExtremes(){

		extremes = {
			positions:{
				axis:{
					min:{
						x:40,
						y:10
					},
					max:{
						x:400,
						y:240
					}
				}
			},
			data:{
				limits: {
					min:0,
					max: _.reduce(options.data,function(memo,num){return num > memo ?num : memo;},0)
				}
			}
		};

		// adding values calulcated from initial dataset
		extremes.plots = {
			width: ((extremes.positions.axis.max.x - extremes.positions.axis.min.x) / options.data.length)
		};

		extremes.yLabels = calculateYaxisSteps();
		console.log(extremes);

	};

	function calculateYaxisSteps(){

		var numSteps,
			min,
			max,
			steps = [];

		var dataLimitMaxString = extremes.data.limits.max.toString();
		if(extremes.data.limits.max > 1){
			var mostSignificantDigit = parseInt(dataLimitMaxString[0]);
			var numSteps = mostSignificantDigit + 1;
			// var exponent = dataLimitMaxString.length == 1 ? 1 : dataLimitMaxString.length - 1;
			var exponent = Math.floor(Math.log(extremes.data.limits.max)/Math.log(10))
			var significantMagnitude = Math.pow(10, exponent);
			steps = [];
			for (var i = 0; i <= numSteps; i++){
				var step = i*significantMagnitude;
				steps.push(step);
			}
			min = steps[0];
			max = steps[steps.length-1];
		} else if (extremes.data.limits.max>0){
			var significantIndex = 2,
				digit = '';
			for(; significantIndex < dataLimitMaxString.length; significantIndex++){
				digit = dataLimitMaxString[significantIndex];
				if(dataLimitMaxString !== '0'){
					break;
				}
			}
			var significantMagnitude = Math.pow(10,significantIndex-1);
			var numSteps = parseInt(digit)+1;
			for (var i = 0; i <= numSteps; i++){
				var step = i/significantMagnitude;
				steps.push(step);
			}
			min = steps[0];
			max = steps[steps.length-1];
		}
		return {
			numberOfSteps: numSteps,
			steps: steps,
			min: min,
			max: max
		}
	}

	function calculteScaledY(y){
		var ratio = y / extremes.yLabels.max;
		return (extremes.positions.axis.max.y - extremes.positions.axis.min.y)*ratio;
	}

	function drawAxis(){
		var axisLineOptions = {stroke:'rgba(0,0,0,.5)', strokeWidth:1}

		axis.y = snap.line(
			extremes.positions.axis.min.x,
			extremes.positions.axis.min.y,
			extremes.positions.axis.min.x,
			extremes.positions.axis.max.y);
		axis.y.attr(axisLineOptions);

		axis.x = snap.line(
			extremes.positions.axis.min.x,
			extremes.positions.axis.max.y,
			extremes.positions.axis.max.x,
			extremes.positions.axis.max.y);
		axis.x.attr(axisLineOptions);

		// xaxis lables
		var xOffset = extremes.plots.width/2;
		axis.xLables = _.map(options.labels, function(label, i){
			var x = extremes.positions.axis.min.x + xOffset + (extremes.plots.width*i);
			var y = extremes.positions.axis.max.y + 15;
			var text = snap.text(x, y, label);
			text.attr({'text-anchor':'middle'})
			return text;
		});

		// yaxis labels
		axis.yLabels = _.map(extremes.yLabels.steps, function(step, i){
			console.log(step);
			var x = extremes.positions.axis.min.x - 5;
			var y = extremes.positions.axis.max.y - calculteScaledY(step);
			var label = yLabelTransform(step);
			var text = snap.text(x, y, label);
			text.attr({'text-anchor':'end', 'dominant-baseline':'middle'});
			return text;
		});

		// yaxis gridlines
		var axisGridLineOptions = {stroke:'rgba(0,0,0,.1)', strokeWidth:1}

		axis.yGridLines = _.map(extremes.yLabels.steps, function(step, i){
			if(step === 0) return;
			var y = extremes.positions.axis.max.y - calculteScaledY(step);
			var line = snap.line(extremes.positions.axis.min.x, y, extremes.positions.axis.max.x, y);
			line.attr(axisGridLineOptions);
		})

	};

	function drawChart(){
		var type = options.type || that.types.bar;
		implemetations[type]();
	};

	function drawBar(){
		var barWidthRatio = .9;
		var barMarginRatio = .05;

		var barWidth = extremes.plots.width*barWidthRatio;
		var barMarginWidth = extremes.plots.width*barMarginRatio;

		plots = _.map(options.data, function(value, key){
			var x = extremes.positions.axis.min.x + (key*barWidth) + (key*2*barMarginWidth) + barMarginWidth;
			var y = extremes.positions.axis.max.y
			var width = barWidth;
			var height = (calculteScaledY(value));
			// var bar = snap.rect(x, y - height, width, height);
			var bar = snap.rect(x, y, width, 0);
			bar.attr({fill:'rgba(0,175,255,.5)'});
			bar.animate({y:y-height,height:height}, 350, mina.easeout);
			return bar;
		});
	};

	function drawLine(){
		var plotPointWidth = extremes.plots.width;
		var path = '';
		var first = true;
		var preAnimationPlots = [];
		var dataPlots = [];
		var yMaxString = extremes.positions.axis.max.y;
		_.each(options.data, function(value, key){
			var pathLetter = 'L';
			if(first){
				pathLetter = 'M';
				first = false;
			}
			var x = plotPointWidth/2 + (plotPointWidth*key) + extremes.positions.axis.min.x;
			var y = extremes.positions.axis.max.y - calculteScaledY(value);
			dataPlots.push(pathLetter + x.toString() + ',' + y.toString());
			preAnimationPlots.push(pathLetter + x.toString() + ',' + yMaxString);
		});
		var path = snap.path(preAnimationPlots.join(','))
		path.attr({fill:'transparent', stroke:'rgba(0,175,255,.5)',strokeWidth:3})
		path.animate({d: dataPlots.join(',')}, 350, mina.easeout);

	};

	function drawArea(){
		var plotPointWidth = extremes.plots.width;
		var path = '';
		var preAnimationPlots = [];
		var dataPlots = [];
		var yMaxString = extremes.positions.axis.max.y;
		_.each(options.data, function(value, key){
			var pathLetter = 'L';
			var x = plotPointWidth/2 + (plotPointWidth*key) + extremes.positions.axis.min.x;
			var y = extremes.positions.axis.max.y - calculteScaledY(value);
			dataPlots.push(pathLetter + x.toString() + ',' + y.toString());
			preAnimationPlots.push(pathLetter + x.toString() + ',' + yMaxString);
		});
		var firstPoint = (
			'M'+
			(plotPointWidth/2 + extremes.positions.axis.min.x).toString() +
			','  +
			yMaxString
		);
		dataPlots.unshift(firstPoint);
		preAnimationPlots.unshift(firstPoint);

		var lastPoint = (
			'L'+
			(plotPointWidth/2 + (plotPointWidth * (options.data.length -1)) + extremes.positions.axis.min.x).toString() +
			',' +
			 yMaxString
		);
		dataPlots.push(lastPoint);
		var path = snap.path(preAnimationPlots.join(','))
		path.attr({fill:'rgba(0,175,255,.5)'})
		path.animate({d: dataPlots.join(',')}, 350, mina.easeout);

	};
	function drawPie(){
		console.log('pie chart not implemented yet');
	};

	this.update = function(options){
		console.log('not implemeted yet');
	}

	init();
	return that;
}<|endoftext|>


<commit_before>'use strict';

function draw_body(body){
    // Calculate offset.
    var offset_x = 0;
    var offset_y = 0;
    if(body['parent'] !== void 0){
        offset_x += bodies[body['parent']]['x'];
        offset_y += bodies[body['parent']]['y'];
    }

    // Bodies orbit around their parent.
    body['rotation'] += body['speed'];
    if(body['rotation'] > 360){
        body['rotation'] -= 360;
    }else if(body['rotation'] < 0){
        body['rotation'] += 360;
    }
    body['x'] = body['orbit'] * Math.cos(body['rotation']) + offset_x;
    body['y'] = body['orbit'] * Math.sin(body['rotation']) + offset_y;

    // Draw body.
    canvas_draw_path(
      [
        {
          'endAngle': math_tau,
          'radius': body['radius'],
          'startAngle': 0,
          'type': 'arc',
          'x': body['x'],
          'y': body['y'],
        },
      ],
      {
        'fillStyle': body['color'],
      }
    );

    // Draw orbit path and line to parent, if player allows it.
    if(settings_settings['line-orbit']
      || settings_settings['line-parent']){
        var vertices = [];
        if(settings_settings['line-orbit']){
            vertices.push({
              'endAngle': math_tau,
              'radius': body['orbit'],
              'startAngle': 0,
              'type': 'arc',
              'x': offset_x,
              'y': offset_y,
            });
        }
        if(settings_settings['line-parent']){
            vertices.push({
              'type': 'moveTo',
              'x': body['x'],
              'y': body['y'],
            });
            vertices.push({
              'x': offset_x,
              'y': offset_y,
            });
        }

        canvas_draw_path(
          vertices,
          {
            'strokeStyle': body['color'],
            'lineWidth': Math.ceil(body['radius'] / 10) / zoom,
          },
          'stroke'
        );
    }

    // If no moons, we're done here.
    if(body['moons'] == void 0){
        return;
    }

    // Draw moons.
    var moonloop_counter = body['moons'].length - 1;
    do{
        draw_body(body['moons'][moonloop_counter]);
    }while(moonloop_counter--);
}

function draw_logic(){
    // Save the current buffer state.
    canvas_buffer.save();

    // Setup camera offset.
    canvas_buffer.translate(
      canvas_x,
      canvas_y
    );
    canvas_buffer.scale(
      zoom,
      zoom
    );
    canvas_buffer.translate(
      camera_x,
      camera_y
    );

    // Draw bodies.
    var loop_counter = bodies.length - 1;
    if(loop_counter >= 0){
        do{
            draw_body(bodies[loop_counter]);
        }while(loop_counter--);
    }

    // Draw the star.
    canvas_draw_path(
      [
        {
          'endAngle': math_tau,
          'radius': settings_settings['solar-radius'],
          'startAngle': 0,
          'type': 'arc',
          'x': 0,
          'y': 0,
        },
      ],
      {
        'fillStyle': settings_settings['solar-color'],
      }
    );

    // Restore the buffer state.
    canvas_buffer.restore();

    // Draw zoom.
    canvas_buffer.fillStyle = '#fff';
    canvas_buffer.fillText(
      zoom,
      0,
      25
    );
}

function generate_solarsystem(){
    bodies.length = 0;

    var bodyloop_counter = random_integer({
      'max': 5,
    }) + 1;
    var moonloop_counter = 0;
    var radius = 0;
    do{
        radius = random_integer({
          'max': 10,
        }) + 3;

        // Create body.
        bodies.push({
          'color': random_hex(),
          'orbit': random_integer({
            'max': 2323,
          }) + 232,
          'radius': radius,
          'rotation': random_integer({
            'max': 360,
          }),
          'speed': Math.random() / 100,
          'x': 0,
          'y': 0,
        });

        // Should this new body have moons?
        if(random_boolean()){
            continue;
        }

        bodies[bodies.length - 1]['moons'] = [];

        moonloop_counter = random_integer({
          'max': 2,
        }) + 1;
        do{
            radius = random_integer({
              'max': 5,
            }) + 2;

            // Create moon for this new body.
            bodies[bodies.length - 1]['moons'].push({
              'color': random_hex(),
              'orbit': random_integer({
                'max': 100,
              }) + 15,
              'parent': bodyloop_counter,
              'radius': radius,
              'rotation': random_integer({
                'max': 360,
              }),
              'speed': (Math.random() - .5) / 5,
              'x': 0,
              'y': 0,
            });
        }while(moonloop_counter--);
    }while(bodyloop_counter--);

    settings_settings['solar-color'] = random_hex();
    settings_settings['solar-radius'] = random_integer({
      'max': 99,
    }) + 5;
}

function logic(){
    // Update camera position.
    if(key_down){
        camera_y -= settings_settings['camera-speed'] / zoom;
    }
    if(key_left){
        camera_x += settings_settings['camera-speed'] / zoom;
    }
    if(key_right){
        camera_x -= settings_settings['camera-speed'] / zoom;
    }
    if(key_up){
        camera_y += settings_settings['camera-speed'] / zoom;
    }
}

function mouse_wheel(e){
    zoom += (e.wheelDelta || -e.detail) > 0
      ? .05
      : -.05;

    if(zoom < .1){
        zoom = .1;

    }else if(zoom > 3){
        zoom = 3;
    }

    zoom = parseFloat(zoom.toFixed(2));
}

var bodies = [];
var camera_x = 0;
var camera_y = 0;
var drag = false;
var drag_x = 0;
var drag_y = 0;
var key_down = false;
var key_left = false;
var key_right = false;
var key_up = false;
var zoom = 1;

window.onkeydown = function(e){
    var key = String.fromCharCode(e.keyCode || e.which);

    if(key === settings_settings['movement-keys'][1]){
        key_left = true;

    }else if(key === settings_settings['movement-keys'][3]){
        key_right = true;

    }else if(key === settings_settings['movement-keys'][2]){
        key_down = true;

    }else if(key === settings_settings['movement-keys'][0]){
        key_up = true;

    }else if(key === settings_settings['line-keys'][0]){
        settings_settings['line-parent'] = !settings_settings['line-parent'];

    }else if(key === settings_settings['line-keys'][1]){
        settings_settings['line-orbit'] = !settings_settings['line-orbit'];

    }else if(key === settings_settings['restart-key']){
        generate_solarsystem();
    }
};

window.onkeyup = function(e){
    var key = String.fromCharCode(e.keyCode || e.which);

    if(key === settings_settings['movement-keys'][1]){
        key_left = false;

    }else if(key === settings_settings['movement-keys'][3]){
        key_right = false;

    }else if(key === settings_settings['movement-keys'][2]){
        key_down = false;

    }else if(key === settings_settings['movement-keys'][0]){
        key_up = false;
    }
};

window.onload = function(){
    canvas_init();
    settings_init({
      'prefix': 'SolarSystem-2D.htm-',
      'settings': {
        'camera-speed': 10,
        'line-keys': 'LO',
        'line-orbit': true,
        'line-parent': true,
        'movement-keys': 'WASD',
        'restart-key': 'H',
        'solar-color': '#fff',
        'solar-radius': 1,
      },
    });
    generate_solarsystem();

    if('onmousewheel' in window){
        window.onmousewheel = mouse_wheel;

    }else{
        document.addEventListener(
          'DOMMouseScroll',
          mouse_wheel,
          false
        );
    }
};

window.onmousedown =
  window.ontouchstart = function(e){
    drag = true;
    drag_x = e.pageX;
    drag_y = e.pageY;
};

window.onmousemove =
  window.ontouchmove = function(e){
    if(!drag){
        return;
    }

    camera_x -= (drag_x - e.pageX) / zoom;
    camera_y -= (drag_y - e.pageY) / zoom;
    drag_x = e.pageX;
    drag_y = e.pageY;
};

window.onmouseup =
  window.ontouchend = function(e){
    drag = false;
};
<commit_msg>switched canvas.js to args<commit_after>'use strict';

function draw_body(body){
    // Calculate offset.
    var offset_x = 0;
    var offset_y = 0;
    if(body['parent'] !== void 0){
        offset_x += bodies[body['parent']]['x'];
        offset_y += bodies[body['parent']]['y'];
    }

    // Bodies orbit around their parent.
    body['rotation'] += body['speed'];
    if(body['rotation'] > 360){
        body['rotation'] -= 360;
    }else if(body['rotation'] < 0){
        body['rotation'] += 360;
    }
    body['x'] = body['orbit'] * Math.cos(body['rotation']) + offset_x;
    body['y'] = body['orbit'] * Math.sin(body['rotation']) + offset_y;

    // Draw body.
    canvas_draw_path({
      'properties': {
        'fillStyle': body['color'],
      },
      'vertices': [
        {
          'endAngle': math_tau,
          'radius': body['radius'],
          'startAngle': 0,
          'type': 'arc',
          'x': body['x'],
          'y': body['y'],
        },
      ],
    });

    // Draw orbit path and line to parent, if player allows it.
    if(settings_settings['line-orbit']
      || settings_settings['line-parent']){
        var vertices = [];
        if(settings_settings['line-orbit']){
            vertices.push({
              'endAngle': math_tau,
              'radius': body['orbit'],
              'startAngle': 0,
              'type': 'arc',
              'x': offset_x,
              'y': offset_y,
            });
        }
        if(settings_settings['line-parent']){
            vertices.push({
              'type': 'moveTo',
              'x': body['x'],
              'y': body['y'],
            });
            vertices.push({
              'x': offset_x,
              'y': offset_y,
            });
        }

        canvas_draw_path({
          'properties': {
            'strokeStyle': body['color'],
            'lineWidth': Math.ceil(body['radius'] / 10) / zoom,
          },
          'style': 'stroke',
          'vertices': vertices,
        });
    }

    // If no moons, we're done here.
    if(body['moons'] == void 0){
        return;
    }

    // Draw moons.
    var moonloop_counter = body['moons'].length - 1;
    do{
        draw_body(body['moons'][moonloop_counter]);
    }while(moonloop_counter--);
}

function draw_logic(){
    // Save the current buffer state.
    canvas_buffer.save();

    // Setup camera offset.
    canvas_buffer.translate(
      canvas_x,
      canvas_y
    );
    canvas_buffer.scale(
      zoom,
      zoom
    );
    canvas_buffer.translate(
      camera_x,
      camera_y
    );

    // Draw bodies.
    var loop_counter = bodies.length - 1;
    if(loop_counter >= 0){
        do{
            draw_body(bodies[loop_counter]);
        }while(loop_counter--);
    }

    // Draw the star.
    canvas_draw_path({
      'properties': {
        'fillStyle': settings_settings['solar-color'],
      },
      'vertices': [
        {
          'endAngle': math_tau,
          'radius': settings_settings['solar-radius'],
          'startAngle': 0,
          'type': 'arc',
          'x': 0,
          'y': 0,
        },
      ],
    });

    // Restore the buffer state.
    canvas_buffer.restore();

    // Draw zoom.
    canvas_buffer.fillStyle = '#fff';
    canvas_buffer.fillText(
      zoom,
      0,
      25
    );
}

function generate_solarsystem(){
    bodies.length = 0;

    var bodyloop_counter = random_integer({
      'max': 5,
    }) + 1;
    var moonloop_counter = 0;
    var radius = 0;
    do{
        radius = random_integer({
          'max': 10,
        }) + 3;

        // Create body.
        bodies.push({
          'color': random_hex(),
          'orbit': random_integer({
            'max': 2323,
          }) + 232,
          'radius': radius,
          'rotation': random_integer({
            'max': 360,
          }),
          'speed': Math.random() / 100,
          'x': 0,
          'y': 0,
        });

        // Should this new body have moons?
        if(random_boolean()){
            continue;
        }

        bodies[bodies.length - 1]['moons'] = [];

        moonloop_counter = random_integer({
          'max': 2,
        }) + 1;
        do{
            radius = random_integer({
              'max': 5,
            }) + 2;

            // Create moon for this new body.
            bodies[bodies.length - 1]['moons'].push({
              'color': random_hex(),
              'orbit': random_integer({
                'max': 100,
              }) + 15,
              'parent': bodyloop_counter,
              'radius': radius,
              'rotation': random_integer({
                'max': 360,
              }),
              'speed': (Math.random() - .5) / 5,
              'x': 0,
              'y': 0,
            });
        }while(moonloop_counter--);
    }while(bodyloop_counter--);

    settings_settings['solar-color'] = random_hex();
    settings_settings['solar-radius'] = random_integer({
      'max': 99,
    }) + 5;
}

function logic(){
    // Update camera position.
    if(key_down){
        camera_y -= settings_settings['camera-speed'] / zoom;
    }
    if(key_left){
        camera_x += settings_settings['camera-speed'] / zoom;
    }
    if(key_right){
        camera_x -= settings_settings['camera-speed'] / zoom;
    }
    if(key_up){
        camera_y += settings_settings['camera-speed'] / zoom;
    }
}

function mouse_wheel(e){
    zoom += (e.wheelDelta || -e.detail) > 0
      ? .05
      : -.05;

    if(zoom < .1){
        zoom = .1;

    }else if(zoom > 3){
        zoom = 3;
    }

    zoom = parseFloat(zoom.toFixed(2));
}

var bodies = [];
var camera_x = 0;
var camera_y = 0;
var drag = false;
var drag_x = 0;
var drag_y = 0;
var key_down = false;
var key_left = false;
var key_right = false;
var key_up = false;
var zoom = 1;

window.onkeydown = function(e){
    var key = String.fromCharCode(e.keyCode || e.which);

    if(key === settings_settings['movement-keys'][1]){
        key_left = true;

    }else if(key === settings_settings['movement-keys'][3]){
        key_right = true;

    }else if(key === settings_settings['movement-keys'][2]){
        key_down = true;

    }else if(key === settings_settings['movement-keys'][0]){
        key_up = true;

    }else if(key === settings_settings['line-keys'][0]){
        settings_settings['line-parent'] = !settings_settings['line-parent'];

    }else if(key === settings_settings['line-keys'][1]){
        settings_settings['line-orbit'] = !settings_settings['line-orbit'];

    }else if(key === settings_settings['restart-key']){
        generate_solarsystem();
    }
};

window.onkeyup = function(e){
    var key = String.fromCharCode(e.keyCode || e.which);

    if(key === settings_settings['movement-keys'][1]){
        key_left = false;

    }else if(key === settings_settings['movement-keys'][3]){
        key_right = false;

    }else if(key === settings_settings['movement-keys'][2]){
        key_down = false;

    }else if(key === settings_settings['movement-keys'][0]){
        key_up = false;
    }
};

window.onload = function(){
    canvas_init();
    settings_init({
      'prefix': 'SolarSystem-2D.htm-',
      'settings': {
        'camera-speed': 10,
        'line-keys': 'LO',
        'line-orbit': true,
        'line-parent': true,
        'movement-keys': 'WASD',
        'restart-key': 'H',
        'solar-color': '#fff',
        'solar-radius': 1,
      },
    });
    generate_solarsystem();

    if('onmousewheel' in window){
        window.onmousewheel = mouse_wheel;

    }else{
        document.addEventListener(
          'DOMMouseScroll',
          mouse_wheel,
          false
        );
    }
};

window.onmousedown =
  window.ontouchstart = function(e){
    drag = true;
    drag_x = e.pageX;
    drag_y = e.pageY;
};

window.onmousemove =
  window.ontouchmove = function(e){
    if(!drag){
        return;
    }

    camera_x -= (drag_x - e.pageX) / zoom;
    camera_y -= (drag_y - e.pageY) / zoom;
    drag_x = e.pageX;
    drag_y = e.pageY;
};

window.onmouseup =
  window.ontouchend = function(e){
    drag = false;
};
<|endoftext|>


<commit_before>// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.provide("frappe.perm");

// backward compatibilty
var READ = "read", WRITE = "write", CREATE = "create", DELETE = "delete";
var SUBMIT = "submit", CANCEL = "cancel", AMEND = "amend";

$.extend(frappe.perm, {
	rights: ["read", "write", "create", "submit", "cancel", "amend",
		"report", "import", "export", "print", "email", "restrict", "delete", "restricted"],

	doctype_perm: {},

	has_perm: function(doctype, permlevel, ptype, docname) {
		if(!permlevel) permlevel = 0;

		if(docname) {
			var perms = frappe.perm.get_perm(doctype, docname);
		} else {
			if(!frappe.perm.doctype_perm[doctype]) {
				frappe.perm.doctype_perm[doctype] = frappe.perm.get_perm(doctype);
			}
			var perms = frappe.perm.doctype_perm[doctype];
		}

		if(!perms)
			return false;

		if(!perms[permlevel])
			return false;

		return !!perms[permlevel][ptype];
	},

	get_perm: function(doctype, docname) {
		var perm = [{read: 0}];

		var meta = frappe.model.get_doc("DocType", doctype);
		if(!meta) {
			return perm;
		} else if(meta.istable) {
			// if a child table, use permissions of parent form
			var parent_df = frappe.model.get("DocField", {fieldtype: "Table", options: doctype});
			if(parent_df.length) {
				if(docname) {
					docname = frappe.model.get_doc(doctype, docname).parent;
				}
				doctype = parent_df[0].parent;
			}
		}

		if(user==="Administrator" || user_roles.indexOf("Administrator")!==-1) {
			perm[0].read = 1;
		}

		if(docname && !frappe.perm.has_unrestricted_access(doctype, docname, perm[0].restricted)) {
			// if has restricted data, return not permitted
			return perm;
		}

		var docperms = frappe.model.get("DocPerm", {parent: doctype});
		$.each(docperms, function(i, p) {
			// if user has this role
			if(user_roles.indexOf(p.role)!==-1) {
				var permlevel = cint(p.permlevel);
				if(!perm[permlevel]) {
					perm[permlevel] = {};
				}
				$.each(frappe.perm.rights, function(i, key) {
					if(key=="restricted") {
						perm[permlevel][key] = (perm[permlevel][key] || 1) && (p[key] || 0);
					} else {
						perm[permlevel][key] = perm[permlevel][key] || (p[key] || 0);
					}
				});
			}
		});

		return perm;
	},

	has_unrestricted_access: function(doctype, docname, restricted) {
		var restrictions = frappe.defaults.get_restrictions();
		var doc = frappe.model.get_doc(doctype, docname);

		if(restricted) {
			if(doc.owner==user) return true;
			if(!restrictions || $.isEmptyObject(restrictions)) {
				return false;
			}
		} else {
			if(!restrictions || $.isEmptyObject(restrictions)) {
				return true;
			}
		}

		// prepare restricted fields
		var fields_to_check = frappe.perm.get_restricted_fields(doctype, docname, restrictions);

		// loop and find if has restricted data
		var has_restricted_data = false;
		var doc = frappe.model.get_doc(doctype, docname);
		$.each(fields_to_check, function(i, df) {
			if(doc[df.fieldname] && restrictions[df.options].indexOf(doc[df.fieldname])===-1) {
				has_restricted_data = true;
				return false;
			}
		});

		return !has_restricted_data;
	},

	get_restricted_fields: function(doctype, docname, restrictions) {
		var fields_to_check = frappe.meta.get_restricted_fields(doctype, docname,
			Object.keys(restrictions));
		if(Object.keys(restrictions).indexOf(doctype)!==-1) {
			fields_to_check = fields_to_check.concat(
				{label: "Name", fieldname: name, options: doctype});
		}
		return fields_to_check;
	},

	get_match_rules: function(doctype) {
		var match_rules = {};

		// Rule for restrictions
		var restrictions = frappe.defaults.get_restrictions();
		if(restrictions && !$.isEmptyObject(restrictions)) {
			$.each(frappe.perm.get_restricted_fields(doctype, null, restrictions), function(i, df) {
				match_rules[df.label] = restrictions[df.options];
			});
		}

		return match_rules;
	},

	get_field_display_status: function(df, doc, perm, explain) {
		if(!doc) return "Write";

		perm = perm || frappe.perm.get_perm(doc.doctype, doc.name);
		if(!df.permlevel) df.permlevel = 0;
		var p = perm[df.permlevel];
		var status = "None";

		// permission
		if(p) {
			if(p.write && !df.disabled) {
				status = "Write";
			} else if(p.read) {
				status = "Read";
			}
		}
		if(explain) console.log("By Permission:" + status);

		// hidden
		if(cint(df.hidden)) status = "None";
		if(explain) console.log("By Hidden:" + status);

		// hidden due to dependency
		if(cint(df.hidden_due_to_dependency)) status = "None";
		if(explain) console.log("By Hidden Due To Dependency:" + status);

		// submit
		if(status==="Write" && cint(doc.docstatus) > 0) status = "Read";
		if(explain) console.log("By Submit:" + status);

		// allow on submit
		var allow_on_submit = df.fieldtype==="Table" ? 0 : cint(df.allow_on_submit);
		if(status==="Read" && allow_on_submit && cint(doc.docstatus)===1 && p.write) {
			status = "Write";
		}
		if(explain) console.log("By Allow on Submit:" + status);

		// workflow state
		if(status==="Read" && cur_frm && cur_frm.state_fieldname) {
			// fields updated by workflow must be read-only
			if(cint(cur_frm.read_only) ||
				in_list(cur_frm.states.update_fields, df.fieldname) ||
				df.fieldname==cur_frm.state_fieldname) {
				status = "Read";
			}
		}
		if(explain) console.log("By Workflow:" + status);

		// read only field is checked
		if(status==="Write" && cint(df.read_only)) {
			status = "Read";
		}
		if(explain) console.log("By Read Only:" + status);

		return status;
	},
});<commit_msg>added set_only_once property in docfield<commit_after>// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.provide("frappe.perm");

// backward compatibilty
var READ = "read", WRITE = "write", CREATE = "create", DELETE = "delete";
var SUBMIT = "submit", CANCEL = "cancel", AMEND = "amend";

$.extend(frappe.perm, {
	rights: ["read", "write", "create", "submit", "cancel", "amend",
		"report", "import", "export", "print", "email", "restrict", "delete", "restricted"],

	doctype_perm: {},

	has_perm: function(doctype, permlevel, ptype, docname) {
		if(!permlevel) permlevel = 0;

		if(docname) {
			var perms = frappe.perm.get_perm(doctype, docname);
		} else {
			if(!frappe.perm.doctype_perm[doctype]) {
				frappe.perm.doctype_perm[doctype] = frappe.perm.get_perm(doctype);
			}
			var perms = frappe.perm.doctype_perm[doctype];
		}

		if(!perms)
			return false;

		if(!perms[permlevel])
			return false;

		return !!perms[permlevel][ptype];
	},

	get_perm: function(doctype, docname) {
		var perm = [{read: 0}];

		var meta = frappe.model.get_doc("DocType", doctype);
		if(!meta) {
			return perm;
		} else if(meta.istable) {
			// if a child table, use permissions of parent form
			var parent_df = frappe.model.get("DocField", {fieldtype: "Table", options: doctype});
			if(parent_df.length) {
				if(docname) {
					docname = frappe.model.get_doc(doctype, docname).parent;
				}
				doctype = parent_df[0].parent;
			}
		}

		if(user==="Administrator" || user_roles.indexOf("Administrator")!==-1) {
			perm[0].read = 1;
		}

		if(docname && !frappe.perm.has_unrestricted_access(doctype, docname, perm[0].restricted)) {
			// if has restricted data, return not permitted
			return perm;
		}

		var docperms = frappe.model.get("DocPerm", {parent: doctype});
		$.each(docperms, function(i, p) {
			// if user has this role
			if(user_roles.indexOf(p.role)!==-1) {
				var permlevel = cint(p.permlevel);
				if(!perm[permlevel]) {
					perm[permlevel] = {};
				}
				$.each(frappe.perm.rights, function(i, key) {
					if(key=="restricted") {
						perm[permlevel][key] = (perm[permlevel][key] || 1) && (p[key] || 0);
					} else {
						perm[permlevel][key] = perm[permlevel][key] || (p[key] || 0);
					}
				});
			}
		});

		return perm;
	},

	has_unrestricted_access: function(doctype, docname, restricted) {
		var restrictions = frappe.defaults.get_restrictions();
		var doc = frappe.model.get_doc(doctype, docname);

		if(restricted) {
			if(doc.owner==user) return true;
			if(!restrictions || $.isEmptyObject(restrictions)) {
				return false;
			}
		} else {
			if(!restrictions || $.isEmptyObject(restrictions)) {
				return true;
			}
		}

		// prepare restricted fields
		var fields_to_check = frappe.perm.get_restricted_fields(doctype, docname, restrictions);

		// loop and find if has restricted data
		var has_restricted_data = false;
		var doc = frappe.model.get_doc(doctype, docname);
		$.each(fields_to_check, function(i, df) {
			if(doc[df.fieldname] && restrictions[df.options].indexOf(doc[df.fieldname])===-1) {
				has_restricted_data = true;
				return false;
			}
		});

		return !has_restricted_data;
	},

	get_restricted_fields: function(doctype, docname, restrictions) {
		var fields_to_check = frappe.meta.get_restricted_fields(doctype, docname,
			Object.keys(restrictions));
		if(Object.keys(restrictions).indexOf(doctype)!==-1) {
			fields_to_check = fields_to_check.concat(
				{label: "Name", fieldname: name, options: doctype});
		}
		return fields_to_check;
	},

	get_match_rules: function(doctype) {
		var match_rules = {};

		// Rule for restrictions
		var restrictions = frappe.defaults.get_restrictions();
		if(restrictions && !$.isEmptyObject(restrictions)) {
			$.each(frappe.perm.get_restricted_fields(doctype, null, restrictions), function(i, df) {
				match_rules[df.label] = restrictions[df.options];
			});
		}

		return match_rules;
	},

	get_field_display_status: function(df, doc, perm, explain) {
		if(!doc) return "Write";

		perm = perm || frappe.perm.get_perm(doc.doctype, doc.name);
		if(!df.permlevel) df.permlevel = 0;
		var p = perm[df.permlevel];
		var status = "None";

		// permission
		if(p) {
			if(p.write && !df.disabled) {
				status = "Write";
			} else if(p.read) {
				status = "Read";
			}
		}
		if(explain) console.log("By Permission:" + status);

		// hidden
		if(cint(df.hidden)) status = "None";
		if(explain) console.log("By Hidden:" + status);

		// hidden due to dependency
		if(cint(df.hidden_due_to_dependency)) status = "None";
		if(explain) console.log("By Hidden Due To Dependency:" + status);

		// submit
		if(status==="Write" && cint(doc.docstatus) > 0) status = "Read";
		if(explain) console.log("By Submit:" + status);

		// allow on submit
		var allow_on_submit = df.fieldtype==="Table" ? 0 : cint(df.allow_on_submit);
		if(status==="Read" && allow_on_submit && cint(doc.docstatus)===1 && p.write) {
			status = "Write";
		}
		if(explain) console.log("By Allow on Submit:" + status);

		// workflow state
		if(status==="Read" && cur_frm && cur_frm.state_fieldname) {
			// fields updated by workflow must be read-only
			if(cint(cur_frm.read_only) ||
				in_list(cur_frm.states.update_fields, df.fieldname) ||
				df.fieldname==cur_frm.state_fieldname) {
				status = "Read";
			}
		}
		if(explain) console.log("By Workflow:" + status);

		// read only field is checked
		if(status==="Write" && cint(df.read_only)) {
			status = "Read";
		}
		if(explain) console.log("By Read Only:" + status);

		if(status==="Write" && df.set_only_once && !doc.__islocal) {
			status = "Read";
		}
		if(explain) console.log("By Set Only Once:" + status);

		return status;
	},
});<|endoftext|>