<commit_before>var containerScroller = null;
var navScroller = null;

function onDOMChange() {
  if (containerScroller) {
    setContainerWrapperHeight();
    containerScroller.refresh();
  }
}

// Update the nav slide indicators
function updateNavSlider() {
  var current = Math.abs(navScroller.x);
  var max = Math.abs(navScroller.maxScrollX);

  var canScrollLeft = (current > 0);
  var canScrollRight = (current < max-1);

  document.getElementById('slideleft').style.display  = canScrollLeft  ? 'block' : 'none';
  document.getElementById('slideright').style.display = canScrollRight ? 'block' : 'none';
}

// Change wrapper height based on device orientation.
function setContainerWrapperHeight() {
  document.getElementById('container').style.height = 'auto';

	var navbarHeight = document.getElementById('navbar').offsetHeight;
  var footerNavHeight = document.getElementById('footernav').offsetHeight;
	var wrapperHeight = window.innerHeight - navbarHeight - footerNavHeight;
	var containerHeight = document.getElementById('container').offsetHeight;

	document.getElementById('wrapper').style.height = wrapperHeight + 'px';

	if (containerHeight < wrapperHeight) {
	  document.getElementById('container').style.height = wrapperHeight + 'px';
	}

	// when this exists, make it fill the screen
	var fillscreen = document.getElementById('fillscreen');
	if (fillscreen) {
	  fillscreen.style.height = wrapperHeight + 'px';
	}
}

function handleWindowResize(e) {
    if (!('orientation' in window)) {
        rotateScreen();
    }
    setContainerWrapperHeight();

  setTimeout(updateNavSlider, 0);

  if (typeof moduleHandleWindowResize != 'undefined') {
    moduleHandleWindowResize(e);
  }
}

function tabletInit() {
   setOrientation(getOrientation());
    if(!document.getElementById('navbar')) {
        // page has no footer so do not attempt
        // to use fancy tablet container
        return;
    }

  setContainerWrapperHeight();

  // Adjust wrapper height on orientation change or resize
  var resizeEvent = 'onorientationchange' in window ? 'orientationchange' : 'resize';
  window.addEventListener(resizeEvent, handleWindowResize, false);

  document.addEventListener('touchmove', function(e) { e.preventDefault(); });

  containerScroller = new iScroll('wrapper', {
    checkDOMChanges: false,
    hScrollbar: false,
    desktopCompatibility: true,
    bounce: false,
    bounceLock: true
  });

  navScroller = new iScroll('navsliderwrapper', {
    checkDOMChanges: false,
    hScrollbar: false,
    vScrollbar: false,
    desktopCompatibility: true,
    bounce: false,
    bounceLock: true,
    onScrollStart: updateNavSlider,
    onScrollEnd: updateNavSlider
  });

    handleWindowResize();
    updateNavSlider();

  //run module init if present
  if (typeof moduleInit != 'undefined') {
    moduleInit();
  }
}

function scrollToTop() {
  if (containerScroller) {
  	containerScroller.scrollTo(0,0,0);
  }
}

(function(window) {

    function splitView (options) {
      // set caller options
        if (typeof options == 'object') {
            for (var i in options) {
                switch (i) {
                    case 'linkSelect':
                    case 'actionForLink':
                        this[i] = options[i];
                        break;
                    default:
                        this.options[i] = options[i];
                        break;
                }
            }
        }

        if (window.addEventListener) {
          window.addEventListener(RESIZE_EVENT, this, false);
        } else if (window.attachEvent) {
          window.attachEvent(RESIZE_EVENT, this);
        }

        if (!document.getElementById(this.options.list) || !document.getElementById(this.options.detail)) {
            return;
        }

        this.orientation = getOrientation();
        this.list = document.getElementById(this.options.list);
        this.detail = document.getElementById(this.options.detail);
        this.detailScroller = new iScroll(this.options.detail, {checkDOMChange: true});

        if ('content' in this.options) {
            this.content = document.getElementById(this.options.content);
        } else {
            this.options.content = this.options.detail;
            this.content = this.detail;
        }

        var self = this;

        var links = this.list.getElementsByTagName('a');
        var first = true;
        for (var i=0;i<links.length;i++) {
            links[i].onclick = function(e) {
                var action = self.actionForLink(this);
                self[action](e, this);
            }

            if (first && this.options.selectFirst && this.actionForLink(links[i])=='linkSelect') {
                links[i].onclick();
                first = false;
            }
        }

        this.updateListScroller();
    }

    splitView.prototype = {
        orientation: '',
        options: {
            selectFirst: true
        },
        baseActionForLink: function(link) {
            if (link.parentNode.className.match(/pagerlink/)) {
                return 'linkFollow';
            }

            return 'linkSelect';
        },
        actionForLink: function(link) {
            return this.baseActionForLink(link);
        },
        linkFollow: function(e, link) {
            //just follow the link
        },
        linkSelect: function(e, link) {
            //ajax fun
            hideShare();
            var self = this;
            var selected = this.list.getElementsByTagName('a');
            for (var j=0;j<selected.length;j++) {
                removeClass(selected[j],'listSelected');
            }
            addClass(link,'listSelected');
            this.detailScroller.scrollTo(0,0);
            var httpRequest = new XMLHttpRequest();
            httpRequest.open("GET", link.href+'&ajax=1', true);
            httpRequest.onreadystatechange = function() {
                if (httpRequest.readyState == 4 && httpRequest.status == 200) {
                    self.content.innerHTML = httpRequest.responseText;
                    self.detailScroller.refresh();
                    moduleHandleWindowResize();
                }
            }
            showLoadingMsg(this.options.content);
            httpRequest.send(null);
            e && e.preventDefault();
            return false;
        },
        listScroller: null,
        detailScroller: null,
        handleEvent: function (e) {
            switch (e.type) {
                case 'orientationchange':
                case 'resize':
                    if (this.orientation != getOrientation()) {
                        this.orientation = getOrientation();
                        this.updateListScroller();
                    }
                    break;
            }
        },
        updateListScroller: function() {
            var self = this, options={};
            switch (getOrientation()) {
                case 'portrait':
                    options.vScrollbar = false;
                    options.hScrollbar = true;
                    options.vScroll = false;
                    options.hScroll = true;
                    break;
                case 'landscape':
                    options.vScrollbar = true;
                    options.hScrollbar = false;
                    options.hScroll = false;
                    options.vScroll = true;
                    break;
            }

            if (this.listScroller) {
                for (var i in options) {
                    this.listScroller.options[i] = options[i];
                }

                setTimeout(function() {
                    self.listScroller.refresh();
                    var items = self.list.getElementsByTagName('a');
                    for (var i=0;i<items.length; i++) {
                        if (hasClass(items[i],'listSelected')) {
                            self.listScroller.scrollToElement(items[i].parentNode,0);
                        }
                    }
                },0);
                return;
            }

            this.listScroller = new iScroll(this.options.list, options);
        }
    }

    var RESIZE_EVENT = window.addEventListener ?
    ('onorientationchange' in window ?
    'orientationchange' :  // touch device
    'resize')              // desktop browser
    : ('onresize');          // IE

    window.splitView = splitView;

})(window)
<commit_msg>add a setTimeout when orientation/resize happens<commit_after>var containerScroller = null;
var navScroller = null;

function onDOMChange() {
  if (containerScroller) {
    setContainerWrapperHeight();
    containerScroller.refresh();
  }
}

// Update the nav slide indicators
function updateNavSlider() {
  var current = Math.abs(navScroller.x);
  var max = Math.abs(navScroller.maxScrollX);

  var canScrollLeft = (current > 0);
  var canScrollRight = (current < max-1);

  document.getElementById('slideleft').style.display  = canScrollLeft  ? 'block' : 'none';
  document.getElementById('slideright').style.display = canScrollRight ? 'block' : 'none';
}

// Change wrapper height based on device orientation.
function setContainerWrapperHeight() {
  document.getElementById('container').style.height = 'auto';

	var navbarHeight = document.getElementById('navbar').offsetHeight;
  var footerNavHeight = document.getElementById('footernav').offsetHeight;
	var wrapperHeight = window.innerHeight - navbarHeight - footerNavHeight;
	var containerHeight = document.getElementById('container').offsetHeight;

	document.getElementById('wrapper').style.height = wrapperHeight + 'px';

	if (containerHeight < wrapperHeight) {
	  document.getElementById('container').style.height = wrapperHeight + 'px';
	}

	// when this exists, make it fill the screen
	var fillscreen = document.getElementById('fillscreen');
	if (fillscreen) {
	  fillscreen.style.height = wrapperHeight + 'px';
	}
}

function handleWindowResize(e) {
    if (!('orientation' in window)) {
        rotateScreen();
    }
    setContainerWrapperHeight();

  setTimeout(updateNavSlider, 0);

  if (typeof moduleHandleWindowResize != 'undefined') {
    moduleHandleWindowResize(e);
  }
}

function tabletInit() {
   setOrientation(getOrientation());
    if(!document.getElementById('navbar')) {
        // page has no footer so do not attempt
        // to use fancy tablet container
        return;
    }

  setContainerWrapperHeight();

  // Adjust wrapper height on orientation change or resize
  var resizeEvent = 'onorientationchange' in window ? 'orientationchange' : 'resize';
  window.addEventListener(resizeEvent, function() {setTimeout(handleWindowResize,0)}, false);

  document.addEventListener('touchmove', function(e) { e.preventDefault(); });

  containerScroller = new iScroll('wrapper', {
    checkDOMChanges: false,
    hScrollbar: false,
    desktopCompatibility: true,
    bounce: false,
    bounceLock: true
  });

  navScroller = new iScroll('navsliderwrapper', {
    checkDOMChanges: false,
    hScrollbar: false,
    vScrollbar: false,
    desktopCompatibility: true,
    bounce: false,
    bounceLock: true,
    onScrollStart: updateNavSlider,
    onScrollEnd: updateNavSlider
  });

    handleWindowResize();
    updateNavSlider();

  //run module init if present
  if (typeof moduleInit != 'undefined') {
    moduleInit();
  }
}

function scrollToTop() {
  if (containerScroller) {
  	containerScroller.scrollTo(0,0,0);
  }
}

(function(window) {

    function splitView (options) {
      // set caller options
        if (typeof options == 'object') {
            for (var i in options) {
                switch (i) {
                    case 'linkSelect':
                    case 'actionForLink':
                        this[i] = options[i];
                        break;
                    default:
                        this.options[i] = options[i];
                        break;
                }
            }
        }

        if (window.addEventListener) {
          window.addEventListener(RESIZE_EVENT, this, false);
        } else if (window.attachEvent) {
          window.attachEvent(RESIZE_EVENT, this);
        }

        if (!document.getElementById(this.options.list) || !document.getElementById(this.options.detail)) {
            return;
        }

        this.orientation = getOrientation();
        this.list = document.getElementById(this.options.list);
        this.detail = document.getElementById(this.options.detail);
        this.detailScroller = new iScroll(this.options.detail, {checkDOMChange: true});

        if ('content' in this.options) {
            this.content = document.getElementById(this.options.content);
        } else {
            this.options.content = this.options.detail;
            this.content = this.detail;
        }

        var self = this;

        var links = this.list.getElementsByTagName('a');
        var first = true;
        for (var i=0;i<links.length;i++) {
            links[i].onclick = function(e) {
                var action = self.actionForLink(this);
                self[action](e, this);
            }

            if (first && this.options.selectFirst && this.actionForLink(links[i])=='linkSelect') {
                links[i].onclick();
                first = false;
            }
        }

        this.updateListScroller();
    }

    splitView.prototype = {
        orientation: '',
        options: {
            selectFirst: true
        },
        baseActionForLink: function(link) {
            if (link.parentNode.className.match(/pagerlink/)) {
                return 'linkFollow';
            }

            return 'linkSelect';
        },
        actionForLink: function(link) {
            return this.baseActionForLink(link);
        },
        linkFollow: function(e, link) {
            //just follow the link
        },
        linkSelect: function(e, link) {
            //ajax fun
            hideShare();
            var self = this;
            var selected = this.list.getElementsByTagName('a');
            for (var j=0;j<selected.length;j++) {
                removeClass(selected[j],'listSelected');
            }
            addClass(link,'listSelected');
            this.detailScroller.scrollTo(0,0);
            var httpRequest = new XMLHttpRequest();
            httpRequest.open("GET", link.href+'&ajax=1', true);
            httpRequest.onreadystatechange = function() {
                if (httpRequest.readyState == 4 && httpRequest.status == 200) {
                    self.content.innerHTML = httpRequest.responseText;
                    self.detailScroller.refresh();
                    moduleHandleWindowResize();
                }
            }
            showLoadingMsg(this.options.content);
            httpRequest.send(null);
            e && e.preventDefault();
            return false;
        },
        listScroller: null,
        detailScroller: null,
        handleEvent: function (e) {
            switch (e.type) {
                case 'orientationchange':
                case 'resize':
                    if (this.orientation != getOrientation()) {
                        this.orientation = getOrientation();
                        this.updateListScroller();
                    }
                    break;
            }
        },
        updateListScroller: function() {
            var self = this, options={};
            switch (getOrientation()) {
                case 'portrait':
                    options.vScrollbar = false;
                    options.hScrollbar = true;
                    options.vScroll = false;
                    options.hScroll = true;
                    break;
                case 'landscape':
                    options.vScrollbar = true;
                    options.hScrollbar = false;
                    options.hScroll = false;
                    options.vScroll = true;
                    break;
            }

            if (this.listScroller) {
                for (var i in options) {
                    this.listScroller.options[i] = options[i];
                }

                setTimeout(function() {
                    self.listScroller.refresh();
                    var items = self.list.getElementsByTagName('a');
                    for (var i=0;i<items.length; i++) {
                        if (hasClass(items[i],'listSelected')) {
                            self.listScroller.scrollToElement(items[i].parentNode,0);
                        }
                    }
                },0);
                return;
            }

            this.listScroller = new iScroll(this.options.list, options);
        }
    }

    var RESIZE_EVENT = window.addEventListener ?
    ('onorientationchange' in window ?
    'orientationchange' :  // touch device
    'resize')              // desktop browser
    : ('onresize');          // IE

    window.splitView = splitView;

})(window)
<|endoftext|>


<commit_before>define(
  'ephox.alloy.behaviour.common.Behaviour',

  [
    'ephox.alloy.alien.EventRoot',
    'ephox.alloy.api.events.SystemEvents',
    'ephox.alloy.behaviour.common.NoState',
    'ephox.alloy.construct.EventHandler',
    'ephox.alloy.dom.DomModification',
    'ephox.boulder.api.FieldSchema',
    'ephox.boulder.api.Objects',
    'ephox.boulder.api.ValueSchema',
    'ephox.katamari.api.Fun',
    'ephox.katamari.api.Merger',
    'ephox.katamari.api.Obj',
    'ephox.katamari.api.Option',
    'ephox.katamari.api.Thunk',
    'global!Array',
    'global!console',
    'global!Error'
  ],

  function (EventRoot, SystemEvents, NoState, EventHandler, DomModification, FieldSchema, Objects, ValueSchema, Fun, Merger, Obj, Option, Thunk, Array, console, Error) {
    var executeEvent = function (bConfig, bState, executor) {
      return {
        key: SystemEvents.execute(),
        value: EventHandler.nu({
          run: function (component) {
            executor(component, bConfig, bState);
          }
        })
      };
    };

    var loadEvent = function (bConfig, bState, f) {
      return {
        key: SystemEvents.systemInit(),
        value: EventHandler.nu({
          run: function (component, simulatedEvent) {
            if (EventRoot.isSource(component, simulatedEvent)) {
              f(component, bConfig, bState);
            }
          }
        })
      };
    };

    var create = function (schema, name, active, apis, extra, state) {
      var configSchema = ValueSchema.objOf(schema);
      var schemaSchema = FieldSchema.optionObjOf(name, [
        FieldSchema.optionObjOfOnly('config', schema)
      ]);
      return doCreate(configSchema, schemaSchema, name, active, apis, extra, state);
    };

    var createModes = function (modes, name, active, apis, extra, state) {
      var configSchema = modes;
      var schemaSchema = FieldSchema.optionObjOf(name, [
        FieldSchema.optionOf('config', modes)
      ]);
      return doCreate(configSchema, schemaSchema, name, active, apis, extra, state);
    };

    var doCreate = function (configSchema, schemaSchema, name, active, apis, extra, _state) {
      var state = _state !== undefined ? _state : NoState;
      var getConfig = function (info) {
        return Objects.hasKey(info, name) ? info[name]() : Option.none();
      };

      return Merger.deepMerge(
        extra !== undefined ? extra : { },
        Obj.map(apis, function (apiF, apiName) {
          return function (component) {
            var args = arguments;
            return component.config({
              name: Fun.constant(name)
            }).fold(
              function () {
                throw new Error('We could not find any behaviour configuration for: ' + name + '. Using API: ' + apiName);
              },
              function (info) {
                var rest = Array.prototype.slice.call(args, 1);
                return apiF.apply(undefined, [ component, info.config, info.state ].concat(rest));
              }
            );
          };
        }),
        {
          delegation: function (component, cConfig, cState) {
            return Obj.map(apis, function (apiF, apiName) {
              return function (/* */) {
                var rest = Array.prototype.slice.call(arguments, 1);
                return apiF.apply(undefined, [ component, cConfig, cState ].concat(rest));
              };
            });
          }
        },
        {
          revoke: function () {
            return {
              key: name,
              value: undefined
            };
          },

          config: function (spec) {
            if (spec === undefined) return { key: name, value: undefined };

            var prepared = ValueSchema.asStructOrDie(name + '-config', configSchema, spec);

            return {
              key: name,
              value: {
                config: prepared,
                configAsRaw: Thunk.cached(function () {
                  return ValueSchema.asRawOrDie(name + '-config', configSchema, spec);
                }),
                initialConfig: spec,
                state: state
              }
            };
          },

          schema: function () {
            return schemaSchema;
          },

          exhibit: function (info, base) {
            return getConfig(info).bind(function (behaviourInfo) {
              return Objects.readOptFrom(active, 'exhibit').map(function (exhibitor) {
                return exhibitor(base, behaviourInfo.config, behaviourInfo.state);
              });
            }).getOr(DomModification.nu({ }));
          },

          name: function () {
            return name;
          },

          handlers: function (info) {
            console.log(name, 'handlers', info);
            return getConfig(info).bind(function (behaviourInfo) {
              return Objects.readOptFrom(active, 'events').map(function (events) {
                return events(behaviourInfo.config, behaviourInfo.state);
              });
            }).getOr({ });
          }
        }
      );
    };

    return {
      executeEvent: executeEvent,
      loadEvent: loadEvent,
      create: create,
      createModes: createModes
    };
  }
);<commit_msg>VAN-81: removing delegation<commit_after>define(
  'ephox.alloy.behaviour.common.Behaviour',

  [
    'ephox.alloy.alien.EventRoot',
    'ephox.alloy.api.events.SystemEvents',
    'ephox.alloy.construct.EventHandler',
    'ephox.alloy.dom.DomModification',
    'ephox.boulder.api.FieldSchema',
    'ephox.boulder.api.Objects',
    'ephox.boulder.api.ValueSchema',
    'ephox.katamari.api.Fun',
    'ephox.katamari.api.Merger',
    'ephox.katamari.api.Obj',
    'ephox.katamari.api.Option',
    'ephox.katamari.api.Thunk',
    'global!Array',
    'global!console',
    'global!Error'
  ],

  function (EventRoot, SystemEvents, EventHandler, DomModification, FieldSchema, Objects, ValueSchema, Fun, Merger, Obj, Option, Thunk, Array, console, Error) {
    var executeEvent = function (bConfig, bState, executor) {
      return {
        key: SystemEvents.execute(),
        value: EventHandler.nu({
          run: function (component) {
            executor(component, bConfig, bState);
          }
        })
      };
    };

    var loadEvent = function (bConfig, bState, f) {
      return {
        key: SystemEvents.systemInit(),
        value: EventHandler.nu({
          run: function (component, simulatedEvent) {
            if (EventRoot.isSource(component, simulatedEvent)) {
              f(component, bConfig, bState);
            }
          }
        })
      };
    };

    var create = function (schema, name, active, apis, extra, state) {
      var configSchema = ValueSchema.objOf(schema);
      var schemaSchema = FieldSchema.optionObjOf(name, [
        FieldSchema.optionObjOfOnly('config', schema)
      ]);
      return doCreate(configSchema, schemaSchema, name, active, apis, extra, state);
    };

    var createModes = function (modes, name, active, apis, extra, state) {
      var configSchema = modes;
      var schemaSchema = FieldSchema.optionObjOf(name, [
        FieldSchema.optionOf('config', modes)
      ]);
      return doCreate(configSchema, schemaSchema, name, active, apis, extra, state);
    };

    var doCreate = function (configSchema, schemaSchema, name, active, apis, extra, state) {
      var getConfig = function (info) {
        return Objects.hasKey(info, name) ? info[name]() : Option.none();
      };

      return Merger.deepMerge(
        extra !== undefined ? extra : { },
        Obj.map(apis, function (apiF, apiName) {
          return function (component) {
            var args = arguments;
            return component.config({
              name: Fun.constant(name)
            }).fold(
              function () {
                throw new Error('We could not find any behaviour configuration for: ' + name + '. Using API: ' + apiName);
              },
              function (info) {
                var rest = Array.prototype.slice.call(args, 1);
                return apiF.apply(undefined, [ component, info.config, info.state ].concat(rest));
              }
            );
          };
        }),
        {
          revoke: function () {
            return {
              key: name,
              value: undefined
            };
          },

          config: function (spec) {
            if (spec === undefined) return { key: name, value: undefined };

            var prepared = ValueSchema.asStructOrDie(name + '-config', configSchema, spec);

            return {
              key: name,
              value: {
                config: prepared,
                configAsRaw: Thunk.cached(function () {
                  return ValueSchema.asRawOrDie(name + '-config', configSchema, spec);
                }),
                initialConfig: spec,
                state: state
              }
            };
          },

          schema: function () {
            return schemaSchema;
          },

          exhibit: function (info, base) {
            return getConfig(info).bind(function (behaviourInfo) {
              return Objects.readOptFrom(active, 'exhibit').map(function (exhibitor) {
                return exhibitor(base, behaviourInfo.config, behaviourInfo.state);
              });
            }).getOr(DomModification.nu({ }));
          },

          name: function () {
            return name;
          },

          handlers: function (info) {
            console.log(name, 'handlers', info);
            return getConfig(info).bind(function (behaviourInfo) {
              return Objects.readOptFrom(active, 'events').map(function (events) {
                return events(behaviourInfo.config, behaviourInfo.state);
              });
            }).getOr({ });
          }
        }
      );
    };

    return {
      executeEvent: executeEvent,
      loadEvent: loadEvent,
      create: create,
      createModes: createModes
    };
  }
);<|endoftext|>


<commit_before>"use strict";

function SaveChangesButton() {

    var _map = null;
    var _this = this;
    _this.el = null;

    var sendDataToServer = function () {

        // новые полигоны площадей и зданий
        var areas;
        var buildings;

        // удаляемые полигоны площадей
        var deleted_areas = [];

        var i, len;

        // собираем новые полигоны площадей
        len = _map.drawn_areas.length;
        if (len > 0) {
            areas = [];
            for (i = 0; i < len; i++) {
                areas.push(_map.drawn_areas[i].to_json());
            }
        }

        // собираем новые полигоны зданий
        len = _map.drawn_buildings.length;
        if (len > 0) {
            buildings = [];
            for (i = 0; i < len; i++) {
                buildings.push(_map.drawn_buildings[i].to_json());
            }
        }

        // собираем удаляемые площади
        len = _map.areas_for_delete.length;
        if (len > 0) {
            for (i = 0; i < len; i ++) {
                deleted_areas.push(_map.areas_for_delete[i].id);
            }
        }
        console.log('<ButtonSave.sendDataToServer> deleted_areas: ' + deleted_areas.join(', '));

        $.ajax({
            url: '/save_map_data',
            type: 'POST',
            data: {
                areas: areas,
                buildings: buildings,
                deleted_areas: deleted_areas
            },
            dataType: 'json'
        }).done(sendDataToServerDone);
    };

    var sendDataToServerDone = function (data, result) {

        //console.log("<ButtonSave.sendDataToServerDone> data,result:");
        //console.log(data);
        // => Object
        //      areas: Array[1]
        //          0: Object:
        //                  id: 16,
        //                  old_temp_id: "76400",
        //      buildings: Array,
        //      updated_locations_json: null
        //console.log(result);
        // => success

        _map.save_preloader_klass.hide();

        _map.data = data["updated_locations_json"];

        //var i;
        //var iarea_resp_params;
        //var idrawn_area;
        //for (i = 0; i< data["areas"].length; i++) {
        //    iarea_resp_params = data["areas"][i];
        //    найдем в массиве drawn_areas область, данные о которой сохранили на сервере
            //idrawn_area = utils.getById(iarea["old_temp_id"], _map.drawn_areas);
            //idrawn_area["id"] = iarea["id"];
        //
        //}

        _map.drawn_areas = [];
        _map.drawn_buildings = [];
        _this.check_and_enable();

    };

    _this.onClick = function (e) {
        if (_this.el.hasClass('mapplic-disabled')) return;
        e.preventDefault();
        _map.save_preloader_klass.show();
        sendDataToServer();
    };

    _this.init = function (button_css_selector, link_to_map) {
        _map = link_to_map;
        _this.el = $(button_css_selector);
        _this.el.on('click', _this.onClick);
    };

    _this.check_and_enable = function () {

        //check
        var mark_dirty = _map.drawn_areas.length || _map.drawn_buildings.length || _map.areas_for_delete;

        // enable
        if (mark_dirty) {
            _this.el.removeClass('mapplic-disabled');
        } else {
            _this.el.addClass('mapplic-disabled');
        }

    };

    _this.hide = function () {
        _this.el.css('display','none');
    };

    _this.show = function () {
        _this.el.css('display','block');
    };
}
<commit_msg>feature_remove_polygon: minor: защитился от null.<commit_after>"use strict";

function SaveChangesButton() {

    var _map = null;
    var _this = this;
    _this.el = null;

    var sendDataToServer = function () {

        // новые полигоны площадей и зданий
        var areas;
        var buildings;

        // удаляемые полигоны площадей
        var deleted_areas = [];

        var i, len, iarea;

        // собираем новые полигоны площадей
        len = _map.drawn_areas.length;
        if (len > 0) {
            areas = [];
            for (i = 0; i < len; i++) {
                areas.push(_map.drawn_areas[i].to_json());
            }
        }

        // собираем новые полигоны зданий
        len = _map.drawn_buildings.length;
        if (len > 0) {
            buildings = [];
            for (i = 0; i < len; i++) {
                buildings.push(_map.drawn_buildings[i].to_json());
            }
        }

        // собираем удаляемые площади
        len = _map.areas_for_delete.length;
        if (len > 0) {
            for (i = 0; i < len; i ++) {
                iarea = _map.areas_for_delete[i];
                if (iarea == null) continue;
                deleted_areas.push(iarea.id);
            }
        }
        console.log('<ButtonSave.sendDataToServer> deleted_areas: ' + deleted_areas.join(', '));

        $.ajax({
            url: '/save_map_data',
            type: 'POST',
            data: {
                areas: areas,
                buildings: buildings,
                deleted_areas: deleted_areas
            },
            dataType: 'json'
        }).done(sendDataToServerDone);
    };

    var sendDataToServerDone = function (data, result) {

        //console.log("<ButtonSave.sendDataToServerDone> data,result:");
        //console.log(data);
        // => Object
        //      areas: Array[1]
        //          0: Object:
        //                  id: 16,
        //                  old_temp_id: "76400",
        //      buildings: Array,
        //      updated_locations_json: null
        //console.log(result);
        // => success

        _map.save_preloader_klass.hide();

        _map.data = data["updated_locations_json"];

        //var i;
        //var iarea_resp_params;
        //var idrawn_area;
        //for (i = 0; i< data["areas"].length; i++) {
        //    iarea_resp_params = data["areas"][i];
        //    найдем в массиве drawn_areas область, данные о которой сохранили на сервере
            //idrawn_area = utils.getById(iarea["old_temp_id"], _map.drawn_areas);
            //idrawn_area["id"] = iarea["id"];
        //
        //}

        _map.drawn_areas = [];
        _map.drawn_buildings = [];
        _this.check_and_enable();

    };

    _this.onClick = function (e) {
        if (_this.el.hasClass('mapplic-disabled')) return;
        e.preventDefault();
        _map.save_preloader_klass.show();
        sendDataToServer();
    };

    _this.init = function (button_css_selector, link_to_map) {
        _map = link_to_map;
        _this.el = $(button_css_selector);
        _this.el.on('click', _this.onClick);
    };

    _this.check_and_enable = function () {

        //check
        var mark_dirty = _map.drawn_areas.length || _map.drawn_buildings.length || _map.areas_for_delete;

        // enable
        if (mark_dirty) {
            _this.el.removeClass('mapplic-disabled');
        } else {
            _this.el.addClass('mapplic-disabled');
        }

    };

    _this.hide = function () {
        _this.el.css('display','none');
    };

    _this.show = function () {
        _this.el.css('display','block');
    };
}
<|endoftext|>


<commit_before>/*
 * This file is part of TbSync.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

 "use strict";

//derived from https://dxr.mozilla.org/comm-central/source/mozilla/accessible/tests/mochitest/autocomplete.js
var abAutoComplete = {

  tbSyncAutoCompleteSearch : null,

  /**
   * Register 'tbSyncAutoCompleteSearch' AutoCompleteSearch.
   */
  load : function () {
    abAutoComplete.tbSyncAutoCompleteSearch = new abAutoComplete.Search("tbSyncAutoCompleteSearch");
    abAutoComplete.register(abAutoComplete.tbSyncAutoCompleteSearch, "AutoCompleteSearch");
  },

  /**
   * Unregister 'tbSyncAutoCompleteSearch' AutoCompleteSearch.
   */
  unload : function () {
    abAutoComplete.unregister(abAutoComplete.tbSyncAutoCompleteSearch);
    abAutoComplete.tbSyncAutoCompleteSearch.cid = null;
    abAutoComplete.tbSyncAutoCompleteSearch = null;
  },

  /**
   * Register the given AutoCompleteSearch.
   *
   * @param aSearch       [in] AutoCompleteSearch object
   * @param aDescription  [in] description of the search object
   */
  register : function (aSearch, aDescription) {
    var name = "@mozilla.org/autocomplete/search;1?name=" + aSearch.name;

    var uuidGenerator = Components.classes["@mozilla.org/uuid-generator;1"].getService(Components.interfaces.nsIUUIDGenerator);
    var cid = uuidGenerator.generateUUID();

    var componentManager = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
    componentManager.registerFactory(cid, aDescription, name, aSearch);

    // Keep the id on the object so we can unregister later.
    aSearch.cid = cid;
  },

  /**
   * Unregister the given AutoCompleteSearch.
   */
  unregister : function (aSearch) {
    var componentManager = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
    componentManager.unregisterFactory(aSearch.cid, aSearch);
  },

  /**
   * nsIAutoCompleteSearch implementation.
   *
   * @param aName       [in] the name of autocomplete search
   */
  Search : function (aName) {
    this.name = aName;
  },

  /**
   * nsIAutoCompleteResult implementation.
   */
  Result : function (aValues, aComments, aStyles, aIcons) {
    this.values = aValues;
    this.comments = aComments;
    this.styles = aStyles;
    this.icons = aIcons;

    if (this.values.length > 0)
    this.searchResult = Components.interfaces.nsIAutoCompleteResult.RESULT_SUCCESS;
    else
    this.searchResult = Components.interfaces.nsIAutoCompleteResult.NOMATCH;
  },

  Request: async function(accountData, aSearchString) {
    let entries = await TbSync.providers[accountData.getAccountProperty("provider")].Base.abAutoComplete(accountData, aSearchString);
    return entries.map(entry => ({ ...entry, id: accountData.accountID }));
  },
}

abAutoComplete.Search.prototype = {
  constructor: abAutoComplete.Search,

  // nsIAutoCompleteSearch implementation
  startSearch : function (aSearchString, aSearchParam, aPreviousResult, aListener) {
    this.getAutoCompleteResultFor(aSearchString).then(result => aListener.onSearchResult(this, result));
  },

  stopSearch() {},

  // nsISupports implementation
  QueryInterface: ChromeUtils.generateQI(["nsIFactory", "nsIAutoCompleteSearch"]),

  // nsIFactory implementation
  createInstance(outer, iid) {
    return this.QueryInterface(iid);
  },

  // Search name. Used by AutoCompleteController.
  name: null,

  /**
   * Return AutoCompleteResult for the given search string.
   */
  getAutoCompleteResultFor : async function (aSearchString) {
    //check each account and init server request
    let accounts = TbSync.db.getAccounts();
    let requests = [];
    let values = [];
    let comments = [];
    let styles = [];
    let icons = [];

    for (let i=0; i<accounts.IDs.length; i++) {
      let accountID = accounts.IDs[i];

      let accountData = new TbSync.AccountData(accountID);
      let provider = accountData.getAccountProperty("provider");
      let status = accountData.getAccountProperty("status");

      if (status == "disabled") continue;
      //start all requests parallel (do not wait till done here, push the promise)
      if (TbSync.providers[provider].Base.abAutoComplete) {
        try {
          requests.push(TbSync.abAutoComplete.Request(accountData, aSearchString));
        } catch (e) {}
      }
    }

    //wait for all requests to finish (only have to wait for the slowest, all others are done)
    for (let r=0; r < requests.length; r++) {
      try {
        let result = await requests[r];
        for (let count=0; count < result.length; count++) {
          values.push(result[count].value);
          comments.push(result[count].comment);
          styles.push(result[count].style);
          icons.push(result[count].icon);
        }
      } catch (e) {};
    }

    return new abAutoComplete.Result(values, comments, styles, icons);
  }
}

abAutoComplete.Result.prototype = {
  constructor: abAutoComplete.Result,

  searchString: "",
  searchResult: null,

  defaultIndex: 0,

  get matchCount() {
    return this.values.length;
  },

  getValueAt(aIndex) {
    return this.values[aIndex];
  },

  /**
   * This returns the string that is displayed in the dropdown
   */
  getLabelAt(aIndex) {
    return "  " + this.getValueAt(aIndex);
  },

  /**
   * Get the comment of the result at the given index
   */
  getCommentAt(aIndex) {
    return " " + this.comments[aIndex];
  },

  /**
   * Get the style hint for the result at the given index
   */
  getStyleAt(aIndex) {
    return this.styles[aIndex] ? this.styles[aIndex] : null;
  },

  /**
   * Get the image of the result at the given index
   */
  getImageAt(aIndex) {
    return this.icons[aIndex] ?  this.icons[aIndex] : null;
  },

  /**
   * Get the final value that should be completed when the user confirms
   * the match at the given index.
   */
  getFinalCompleteValueAt(aIndex) {
    return this.getValueAt(aIndex);
  },

  removeValueAt(aRowIndex, aRemoveFromDb) {},

  // nsISupports implementation
  QueryInterface: ChromeUtils.generateQI(["nsIAutoCompleteResult"]),

  // Data
  values: null,
  comments: null,
  styles: null,
  icons: null,
}
<commit_msg>only trigger auto complete for connected accounts<commit_after>/*
 * This file is part of TbSync.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

 "use strict";

//derived from https://dxr.mozilla.org/comm-central/source/mozilla/accessible/tests/mochitest/autocomplete.js
var abAutoComplete = {

  tbSyncAutoCompleteSearch : null,

  /**
   * Register 'tbSyncAutoCompleteSearch' AutoCompleteSearch.
   */
  load : function () {
    abAutoComplete.tbSyncAutoCompleteSearch = new abAutoComplete.Search("tbSyncAutoCompleteSearch");
    abAutoComplete.register(abAutoComplete.tbSyncAutoCompleteSearch, "AutoCompleteSearch");
  },

  /**
   * Unregister 'tbSyncAutoCompleteSearch' AutoCompleteSearch.
   */
  unload : function () {
    abAutoComplete.unregister(abAutoComplete.tbSyncAutoCompleteSearch);
    abAutoComplete.tbSyncAutoCompleteSearch.cid = null;
    abAutoComplete.tbSyncAutoCompleteSearch = null;
  },

  /**
   * Register the given AutoCompleteSearch.
   *
   * @param aSearch       [in] AutoCompleteSearch object
   * @param aDescription  [in] description of the search object
   */
  register : function (aSearch, aDescription) {
    var name = "@mozilla.org/autocomplete/search;1?name=" + aSearch.name;

    var uuidGenerator = Components.classes["@mozilla.org/uuid-generator;1"].getService(Components.interfaces.nsIUUIDGenerator);
    var cid = uuidGenerator.generateUUID();

    var componentManager = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
    componentManager.registerFactory(cid, aDescription, name, aSearch);

    // Keep the id on the object so we can unregister later.
    aSearch.cid = cid;
  },

  /**
   * Unregister the given AutoCompleteSearch.
   */
  unregister : function (aSearch) {
    var componentManager = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
    componentManager.unregisterFactory(aSearch.cid, aSearch);
  },

  /**
   * nsIAutoCompleteSearch implementation.
   *
   * @param aName       [in] the name of autocomplete search
   */
  Search : function (aName) {
    this.name = aName;
  },

  /**
   * nsIAutoCompleteResult implementation.
   */
  Result : function (aValues, aComments, aStyles, aIcons) {
    this.values = aValues;
    this.comments = aComments;
    this.styles = aStyles;
    this.icons = aIcons;

    if (this.values.length > 0)
    this.searchResult = Components.interfaces.nsIAutoCompleteResult.RESULT_SUCCESS;
    else
    this.searchResult = Components.interfaces.nsIAutoCompleteResult.NOMATCH;
  },

  Request: async function(accountData, aSearchString) {
    let entries = [];
    if (accountData.isConnected()) {
      entries = await TbSync.providers[accountData.getAccountProperty("provider")].Base.abAutoComplete(accountData, aSearchString);
    }
    return entries.map(entry => ({ ...entry, id: accountData.accountID }));
  },
}

abAutoComplete.Search.prototype = {
  constructor: abAutoComplete.Search,

  // nsIAutoCompleteSearch implementation
  startSearch : function (aSearchString, aSearchParam, aPreviousResult, aListener) {
    this.getAutoCompleteResultFor(aSearchString).then(result => aListener.onSearchResult(this, result));
  },

  stopSearch() {},

  // nsISupports implementation
  QueryInterface: ChromeUtils.generateQI(["nsIFactory", "nsIAutoCompleteSearch"]),

  // nsIFactory implementation
  createInstance(outer, iid) {
    return this.QueryInterface(iid);
  },

  // Search name. Used by AutoCompleteController.
  name: null,

  /**
   * Return AutoCompleteResult for the given search string.
   */
  getAutoCompleteResultFor : async function (aSearchString) {
    //check each account and init server request
    let accounts = TbSync.db.getAccounts();
    let requests = [];
    let values = [];
    let comments = [];
    let styles = [];
    let icons = [];

    for (let i=0; i<accounts.IDs.length; i++) {
      let accountID = accounts.IDs[i];

      let accountData = new TbSync.AccountData(accountID);
      let provider = accountData.getAccountProperty("provider");
      let status = accountData.getAccountProperty("status");

      if (status == "disabled") continue;
      //start all requests parallel (do not wait till done here, push the promise)
      if (TbSync.providers[provider].Base.abAutoComplete) {
        try {
          requests.push(TbSync.abAutoComplete.Request(accountData, aSearchString));
        } catch (e) {}
      }
    }

    //wait for all requests to finish (only have to wait for the slowest, all others are done)
    for (let r=0; r < requests.length; r++) {
      try {
        let result = await requests[r];
        for (let count=0; count < result.length; count++) {
          values.push(result[count].value);
          comments.push(result[count].comment);
          styles.push(result[count].style);
          icons.push(result[count].icon);
        }
      } catch (e) {};
    }

    return new abAutoComplete.Result(values, comments, styles, icons);
  }
}

abAutoComplete.Result.prototype = {
  constructor: abAutoComplete.Result,

  searchString: "",
  searchResult: null,

  defaultIndex: 0,

  get matchCount() {
    return this.values.length;
  },

  getValueAt(aIndex) {
    return this.values[aIndex];
  },

  /**
   * This returns the string that is displayed in the dropdown
   */
  getLabelAt(aIndex) {
    return "  " + this.getValueAt(aIndex);
  },

  /**
   * Get the comment of the result at the given index
   */
  getCommentAt(aIndex) {
    return " " + this.comments[aIndex];
  },

  /**
   * Get the style hint for the result at the given index
   */
  getStyleAt(aIndex) {
    return this.styles[aIndex] ? this.styles[aIndex] : null;
  },

  /**
   * Get the image of the result at the given index
   */
  getImageAt(aIndex) {
    return this.icons[aIndex] ?  this.icons[aIndex] : null;
  },

  /**
   * Get the final value that should be completed when the user confirms
   * the match at the given index.
   */
  getFinalCompleteValueAt(aIndex) {
    return this.getValueAt(aIndex);
  },

  removeValueAt(aRowIndex, aRemoveFromDb) {},

  // nsISupports implementation
  QueryInterface: ChromeUtils.generateQI(["nsIAutoCompleteResult"]),

  // Data
  values: null,
  comments: null,
  styles: null,
  icons: null,
}
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 Rafael Gieschke
 * Licensed under the MIT License (<https://opensource.org/licenses/MIT>).
 */

/**
 * @fileoverview
 * await.-variables make interactively debugging `Promise`s a breeze.
 *
 * @description
 * Inject this library into any page by executing (or bookmarking):
 * `javascript:void(document.documentElement.appendChild(document.createElement('script')).src='https://rafaelgieschke.github.io/await.-variables/await.js')`
 * in the Console or by adding a `<script>` element to the page:
 * `<script src="https://rafaelgieschke.github.io/await.-variables/await.js"></script>`.
 *
 * @example
 * // Instead of:
 * var promise = fetch("/");
 * // Execute this in Console:
 * await. a = fetch("/");
 * // (Be sure to include the dot after await!)
 * // Wait some time until result of `Promise` gets printed in Console.
 * a = a.text();
 * // Wait some more time.
 * a.match(/<a href/g);
 * // Or, everything in a single step:
 * await. b = async()=> (await (await fetch("/")).text).match(/<a href/g);
 *
 * @see {@link https://github.com/rafaelgieschke/await.-variables}
 */

try {
  // Try to remove the `<script>` element used to load this library.
  document.currentScript.remove();
} catch (e) {}

{
  const awaitVariables = new WeakSet();
  const AsyncPrototype = Object.getPrototypeOf(async () => {});
  const globalObject = typeof global === "object" ? global : window;

  globalObject["await"] = new Proxy(globalObject, {
    set(target, property, value) {
      const descriptor = Reflect.getOwnPropertyDescriptor(target, property);
      if (!descriptor || !awaitVariables.has(descriptor.set)) {
        let value;
        const set = (newValue) => {
          if (typeof newValue === "function" &&
              Object.getPrototypeOf(newValue) === AsyncPrototype &&
              newValue.length === 0) {
            newValue = newValue();
            console.log(newValue);
          }
          value = newValue;

          try {
            newValue.then(v => value === newValue && console.log(value = v),
              v => value === newValue && console.error(value = v));
          } catch (e) {}
        };
        awaitVariables.add(set);
        Object.defineProperty(target, property, {
          configurable: true,
          set, get: () => value,
        });
      }
      target[property] = value;
      return true;
    },
    get(target, property, receiver) {
      const descriptor = Reflect.getOwnPropertyDescriptor(target, property);
      if (!descriptor || !awaitVariables.has(descriptor.set)) {
        receiver[property] = target[property];
      }
      return target[property];
    },
  });
}
<commit_msg>Use strict mode<commit_after>/**
 * @license
 * Copyright 2017 Rafael Gieschke
 * Licensed under the MIT License (<https://opensource.org/licenses/MIT>).
 */

/**
 * @fileoverview
 * await.-variables make interactively debugging `Promise`s a breeze.
 *
 * @description
 * Inject this library into any page by executing (or bookmarking):
 * `javascript:void(document.documentElement.appendChild(document.createElement('script')).src='https://rafaelgieschke.github.io/await.-variables/await.js')`
 * in the Console or by adding a `<script>` element to the page:
 * `<script src="https://rafaelgieschke.github.io/await.-variables/await.js"></script>`.
 *
 * @example
 * // Instead of:
 * var promise = fetch("/");
 * // Execute this in Console:
 * await. a = fetch("/");
 * // (Be sure to include the dot after await!)
 * // Wait some time until result of `Promise` gets printed in Console.
 * a = a.text();
 * // Wait some more time.
 * a.match(/<a href/g);
 * // Or, everything in a single step:
 * await. b = async()=> (await (await fetch("/")).text).match(/<a href/g);
 *
 * @see {@link https://github.com/rafaelgieschke/await.-variables}
 */

"use strict";

try {
  // Try to remove the `<script>` element used to load this library.
  document.currentScript.remove();
} catch (e) {}

{
  const awaitVariables = new WeakSet();
  const AsyncPrototype = Object.getPrototypeOf(async () => {});
  const globalObject = typeof global === "object" ? global : window;

  globalObject["await"] = new Proxy(globalObject, {
    set(target, property, value) {
      const descriptor = Reflect.getOwnPropertyDescriptor(target, property);
      if (!descriptor || !awaitVariables.has(descriptor.set)) {
        let value;
        const set = (newValue) => {
          if (typeof newValue === "function" &&
              Object.getPrototypeOf(newValue) === AsyncPrototype &&
              newValue.length === 0) {
            newValue = newValue();
            console.log(newValue);
          }
          value = newValue;

          try {
            newValue.then(v => value === newValue && console.log(value = v),
              v => value === newValue && console.error(value = v));
          } catch (e) {}
        };
        awaitVariables.add(set);
        Object.defineProperty(target, property, {
          configurable: true,
          set, get: () => value,
        });
      }
      target[property] = value;
      return true;
    },
    get(target, property, receiver) {
      const descriptor = Reflect.getOwnPropertyDescriptor(target, property);
      if (!descriptor || !awaitVariables.has(descriptor.set)) {
        receiver[property] = target[property];
      }
      return target[property];
    },
  });
}
<|endoftext|>


<commit_before>'use strict';

require('mocha');
var path = require('path');
var assert = require('assert');
var assemble = require('assemble-core');
var streams = require('../');
var app;

describe('src()', function() {
  beforeEach(function() {
    app = assemble();
    app.use(streams());

    app.create('pages');
    app.create('posts');

    app.page('a.html', {content: '...'});
    app.page('b.html', {content: '...'});
    app.page('c.html', {content: '...'});

    app.post('x.html', {content: '...'});
    app.post('y.html', {content: '...'});
    app.post('z.html', {content: '...'});
  });

  it('should return add the `toStream` method to the instance', function(done) {
    assert(app.toStream);
    assert.equal(typeof app.toStream, 'function');
    done();
  });

  it('should return an input stream on a view collection', function(done) {
    var files = [];
    app.toStream('pages')
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 3);
        assert(files[0] === 'a.html');
        assert(files[1] === 'b.html');
        assert(files[2] === 'c.html');
        done();
      });
  });

  it('should stack multiple collections', function(done) {
    var files = [];
    app.toStream('pages')
      .pipe(app.toStream('posts'))
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 6);
        assert(files[0] === 'a.html');
        assert(files[1] === 'b.html');
        assert(files[2] === 'c.html');

        assert(files[3] === 'x.html');
        assert(files[4] === 'y.html');
        assert(files[5] === 'z.html');
        done();
      });
  });

  it('should work with `.src`', function(done) {
    var files = [];
    app.src(__dirname + '/fixtures/*.hbs')
      .pipe(app.toStream('posts'))
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert.equal(files.length, 6);
        assert.equal(files[0], 'x.html');
        assert.equal(files[1], 'y.html');
        assert.equal(files[2], 'z.html');

        assert.equal(path.basename(files[3]), 'a.hbs');
        assert.equal(path.basename(files[4]), 'b.hbs');
        assert.equal(path.basename(files[5]), 'c.hbs');
        done();
      })
  })

  it('should pipe a collection', function(done) {
    var files = [];
    app.pages.toStream()
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 3);
        assert(files[0] === 'a.html');
        assert(files[1] === 'b.html');
        assert(files[2] === 'c.html');
        done();
      });
  });

  it('should pipe from one collection to another', function(done) {
    var files = [];
    app.pages.toStream()
      .pipe(app.toStream('posts'))
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 6);
        assert(files[0] === 'a.html');
        assert(files[1] === 'b.html');
        assert(files[2] === 'c.html');

        assert(files[3] === 'x.html');
        assert(files[4] === 'y.html');
        assert(files[5] === 'z.html');
        done();
      });
  });

  it('should support an optional filter function as the second argument', function(done) {
    var files = [];
    app.toStream('pages', function(key, view) {
        return key !== 'a.html';
      })
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 2);
        assert(files[0] === 'b.html');
        assert(files[1] === 'c.html');
        assert(files.indexOf('a.html') === -1);
        done();
      });
  });

  it('should support an array as the second argument', function(done) {
    var files = [];
    app.toStream('pages', ['a.html', 'c.html'])
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 2);
        assert.equal(files[0], 'a.html');
        assert.equal(files[1], 'c.html');
        assert.equal(files.indexOf('b.html'), -1);
        done();
      });
  });

  it('should support a string as the second argument', function(done) {
    var files = [];
    app.toStream('pages', 'c.html')
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 1);
        assert.equal(files[0], 'c.html');
        assert.equal(files.indexOf('a.html'), -1);
        assert.equal(files.indexOf('b.html'), -1);
        done();
      });
  });

  it('should support matching a file path on any collection', function(done) {
    var files = [];
    app.toStream('c.html')
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 1);
        assert.equal(files[0], 'c.html');
        assert.equal(files.indexOf('a.html'), -1);
        assert.equal(files.indexOf('b.html'), -1);
        done();
      });
  });

  it('should support an array of files on any collection', function(done) {
    var files = [];
    app.toStream(['b.html', 'y.html'])
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 2);
        assert.equal(files[0], 'b.html');
        assert.equal(files[1], 'y.html');
        assert.equal(files.indexOf('a.html'), -1);
        assert.equal(files.indexOf('c.html'), -1);
        assert.equal(files.indexOf('x.html'), -1);
        assert.equal(files.indexOf('z.html'), -1);
        done();
      });
  });
});
<commit_msg>tests for toStream on individual views<commit_after>'use strict';

require('mocha');
var path = require('path');
var assert = require('assert');
var assemble = require('assemble-core');
var streams = require('../');
var app;

describe('src()', function() {
  beforeEach(function() {
    app = assemble();
    app.use(streams());

    app.create('pages');
    app.create('posts');

    app.page('a.html', {content: '...'});
    app.page('b.html', {content: '...'});
    app.page('c.html', {content: '...'});

    app.post('x.html', {content: '...'});
    app.post('y.html', {content: '...'});
    app.post('z.html', {content: '...'});
  });

  it('should return add the `toStream` method to the instance', function(done) {
    assert(app.toStream);
    assert.equal(typeof app.toStream, 'function');
    done();
  });

  it('should return an input stream on a view collection', function(done) {
    var files = [];
    app.toStream('pages')
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 3);
        assert(files[0] === 'a.html');
        assert(files[1] === 'b.html');
        assert(files[2] === 'c.html');
        done();
      });
  });

  it('should stack multiple collections', function(done) {
    var files = [];
    app.toStream('pages')
      .pipe(app.toStream('posts'))
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 6);
        assert(files[0] === 'a.html');
        assert(files[1] === 'b.html');
        assert(files[2] === 'c.html');

        assert(files[3] === 'x.html');
        assert(files[4] === 'y.html');
        assert(files[5] === 'z.html');
        done();
      });
  });

  it('should work with `.src`', function(done) {
    var files = [];
    app.src(__dirname + '/fixtures/*.hbs')
      .pipe(app.toStream('posts'))
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert.equal(files.length, 6);
        assert.equal(files[0], 'x.html');
        assert.equal(files[1], 'y.html');
        assert.equal(files[2], 'z.html');

        assert.equal(path.basename(files[3]), 'a.hbs');
        assert.equal(path.basename(files[4]), 'b.hbs');
        assert.equal(path.basename(files[5]), 'c.hbs');
        done();
      })
  })

  it('should pipe a collection', function(done) {
    var files = [];
    app.pages.toStream()
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 3);
        assert(files[0] === 'a.html');
        assert(files[1] === 'b.html');
        assert(files[2] === 'c.html');
        done();
      });
  });

  it('should pipe from one collection to another', function(done) {
    var files = [];
    app.pages.toStream()
      .pipe(app.toStream('posts'))
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 6);
        assert(files[0] === 'a.html');
        assert(files[1] === 'b.html');
        assert(files[2] === 'c.html');

        assert(files[3] === 'x.html');
        assert(files[4] === 'y.html');
        assert(files[5] === 'z.html');
        done();
      });
  });

  it('should support an optional filter function as the second argument', function(done) {
    var files = [];
    app.toStream('pages', function(key, view) {
        return key !== 'a.html';
      })
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 2);
        assert(files[0] === 'b.html');
        assert(files[1] === 'c.html');
        assert(files.indexOf('a.html') === -1);
        done();
      });
  });

  it('should support an array as the second argument', function(done) {
    var files = [];
    app.toStream('pages', ['a.html', 'c.html'])
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 2);
        assert.equal(files[0], 'a.html');
        assert.equal(files[1], 'c.html');
        assert.equal(files.indexOf('b.html'), -1);
        done();
      });
  });

  it('should support a string as the second argument', function(done) {
    var files = [];
    app.toStream('pages', 'c.html')
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 1);
        assert.equal(files[0], 'c.html');
        assert.equal(files.indexOf('a.html'), -1);
        assert.equal(files.indexOf('b.html'), -1);
        done();
      });
  });

  it('should support matching a file path on any collection', function(done) {
    var files = [];
    app.toStream('c.html')
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 1);
        assert.equal(files[0], 'c.html');
        assert.equal(files.indexOf('a.html'), -1);
        assert.equal(files.indexOf('b.html'), -1);
        done();
      });
  });

  it('should support an array of files on any collection', function(done) {
    var files = [];
    app.toStream(['b.html', 'y.html'])
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 2);
        assert.equal(files[0], 'b.html');
        assert.equal(files[1], 'y.html');
        assert.equal(files.indexOf('a.html'), -1);
        assert.equal(files.indexOf('c.html'), -1);
        assert.equal(files.indexOf('x.html'), -1);
        assert.equal(files.indexOf('z.html'), -1);
        done();
      });
  });

  it('should pipe an individual view into a stream', function(done) {
    var files = [];
    app.pages.getView('b.html')
      .toStream()
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 1);
        assert.equal(files[0], 'b.html');
        assert.equal(files.indexOf('a.html'), -1);
        assert.equal(files.indexOf('c.html'), -1);
        assert.equal(files.indexOf('x.html'), -1);
        assert.equal(files.indexOf('y.html'), -1);
        assert.equal(files.indexOf('z.html'), -1);
        done();
      });
  });

  it('should pipe multiple individual views into a stream', function(done) {
    var files = [];
    app.pages.getView('b.html').toStream()
      .pipe(app.posts.getView('y.html').toStream())
      .on('error', done)
      .on('data', function(file) {
        files.push(file.path);
      })
      .on('end', function() {
        assert(files.length === 2);
        assert.equal(files[0], 'b.html');
        assert.equal(files[1], 'y.html');
        assert.equal(files.indexOf('a.html'), -1);
        assert.equal(files.indexOf('c.html'), -1);
        assert.equal(files.indexOf('x.html'), -1);
        assert.equal(files.indexOf('z.html'), -1);
        done();
      });
  });
});
<|endoftext|>


<commit_before>'use strict'

const fs = require('fs')
const postsContent = fs.readFileSync('static/json/posts.json')
const postsListObject = JSON.parse(postsContent)

const defaultVariables = {
  title: 'Mitoc Group',
  description:
    'Mitoc Group is a technology company focusing on automation using cloud native services. Our track record includes helping private equity portfolio companies migrate to public clouds, as well as establish devops and dataops processes using cloud native services and industry best practices. We deliver automations and business results in weeks instead of months.',
  author: 'https://twitter.com/@eistrati',
  publisher: 'MitocGroup.com',
  company: 'Mitoc Group Inc.',
  address: '2 University Plaza Suite 100',
  city: 'Hackensack',
  state: 'NJ',
  zip: '07601',
  year: '2014',
  phone: '(+1) 801 810 8186',
  email: 'hello@mitocgroup.com',
  url: 'https://www.mitocgroup.com',
  image: 'https://www.mitocgroup.com/images/head.png',
  logo: 'https://www.mitocgroup.com/images/v2/logos/mitoc.svg',
  fb_type: 'website',
  fb_brand: 'MitocGroup',
  // fb_app_id: '',
  tw_type: 'summary',
  tw_handle: '@MitocGroup',
  image_tw: 'https://www.mitocgroup.com/images/cover-tw.png',
  image_fb: 'https://www.mitocgroup.com/images/cover-fb.png'
}

const commonScripts = [
  'js/libs/jquery.min.js',
  'js/libs/jquery-mailchimp.min.js',
  'js/libs/jquery-popup.min.js',
  'js/libs/lazysizes.min.js',
  'js/modal-effects.js',
  'js/main.js',
  'js/mailchimp.js'
]

const commonStyles = [
  'styles/libs/font-awesome.min.css',
  'styles/libs/materialdesignicons.min.css',
  'styles/variables.scss',
  'styles/fonts.scss',
  'styles/base.scss',
  'styles/main.scss',
  'styles/mixins.scss',
  'styles/responsive.scss'
]

const indexAssets = {
  'js/index.min.js': [...commonScripts, 'js/libs/slick.min.js', 'js/carousel.js'],
  'css/index.min.css': [...commonStyles, 'styles/libs/slick.min.css', 'styles/libs/slick-theme.min.css']
}

const commonAssets = {
  'js/common.min.js': [...commonScripts, 'js/scroll.js'],
  'css/common.min.css': commonStyles
}

const servicesAssets = {
  'js/services.min.js': commonScripts,
  'css/services.min.css': [...commonStyles, 'styles/services.scss']
}

const partnersAssets = {
  'js/partners.min.js': commonScripts,
  'css/partners.min.css': [...commonStyles, 'styles/partners.scss']
}

const adtechmediaAssets = {
  'js/adtechmedia.min.js': ['js/libs/bodymovin.min.js', 'js/animation.js'],
  'js/common.min.js': commonScripts,
  'css/common.min.css': commonStyles
}

const aboutAssets = {
  'js/about.min.js': commonScripts,
  'css/about.min.css': [...commonStyles, 'styles/about.scss']
}

const blogAssets = {
  'js/blog.min.js': [...commonScripts, 'js/libs/highlight.pack.min.js', 'js/blog.js'],
  'css/blog.min.css': [...commonStyles, 'styles/libs/github.min.css', 'styles/blog.scss', 'styles/post.scss']
}

const contactAssets = {
  'js/contact.min.js': commonScripts,
  'css/contact.min.css': [...commonStyles, 'styles/contact.scss']
}

let posts = {}
posts = Object.keys(postsListObject)
  .sort((a, b) => {
    return -(new Date(postsListObject[a].PublicationDate) - new Date(postsListObject[b].PublicationDate))
  })
  .reduce((prev, curr) => {
    const event = new Date(postsListObject[curr].PublicationDate)
    const options = { month: 'short', day: 'numeric', year: 'numeric' }
    prev[curr] = postsListObject[curr]
    prev[curr].PublicationDate = event.toLocaleDateString('en-EN', options)
    return prev
  }, {})

let routes = {
  '/': {
    view: 'index.twig',
    vars: {
      ...defaultVariables,
      title: defaultVariables.title + ' | Cloud Native Automation in Private Equity',
      href: defaultVariables.url
    },
    assets: indexAssets
  },
  '/services/': {
    view: 'services/index.twig',
    vars: {
      ...defaultVariables,
      title: 'Professional Services | ' + defaultVariables.title,
      href: defaultVariables.url + '/services/'
    },
    assets: servicesAssets
  },
  '/services/automation-infrastructure/': {
    view: 'services/automation-infrastructure.twig',
    vars: {
      ...defaultVariables,
      title: 'Automation of Infrastructure | Professional Services | ' + defaultVariables.title,
      href: defaultVariables.url + '/services/automation-infrastructure/'
    },
    assets: servicesAssets
  },
  '/services/automation-data/': {
    view: 'services/automation-data.twig',
    vars: {
      ...defaultVariables,
      title: 'Automation of Data | Professional Services | ' + defaultVariables.title,
      href: defaultVariables.url + '/services/automation-data/'
    },
    assets: servicesAssets
  },
  '/services/automation-serverless/': {
    view: 'services/automation-serverless.twig',
    vars: {
      ...defaultVariables,
      title: 'Automation of Serverless | Professional Services | ' + defaultVariables.title,
      href: defaultVariables.url + '/services/automation-serverless/'
    },
    assets: servicesAssets
  },
  '/partners/': {
    view: 'partners/index.twig',
    vars: {
      ...defaultVariables,
      title: 'Partners Program | ' + defaultVariables.title,
      href: defaultVariables.url + '/partners/'
    },
    assets: partnersAssets
  },
  '/partners/aws/': {
    view: 'partners/aws.twig',
    vars: {
      ...defaultVariables,
      title: 'Amazon Web Services | Partners Program | ' + defaultVariables.title,
      href: defaultVariables.url + '/partners/aws/'
    },
    assets: partnersAssets
  },
  '/partners/google/': {
    view: 'partners/google.twig',
    vars: {
      ...defaultVariables,
      title: 'Google Cloud Platform | Partners Program | ' + defaultVariables.title,
      href: defaultVariables.url + '/partners/google/'
    },
    assets: partnersAssets
  },
  '/partners/2ndwatch/': {
    view: 'partners/2ndwatch.twig',
    vars: {
      ...defaultVariables,
      title: '2nd Watch | Partners Program | ' + defaultVariables.title,
      href: defaultVariables.url + '/partners/2ndwatch/'
    },
    assets: partnersAssets
  },
  '/partners/404moldova/': {
    view: 'partners/404moldova.twig',
    vars: {
      ...defaultVariables,
      title: '404 Moldova | Partners Program | ' + defaultVariables.title,
      href: defaultVariables.url + '/partners/404moldova/'
    },
    assets: partnersAssets
  },
  '/case-studies/': {
    view: 'case-studies/index.twig',
    vars: {
      ...defaultVariables,
      title: 'Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/'
    },
    assets: commonAssets
  },
  '/case-studies/broadcasting-conglomerate/': {
    view: 'case-studies/broadcasting-conglomerate.twig',
    vars: {
      ...defaultVariables,
      title: 'Major Broadcasting Conglomerate | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/broadcasting-conglomerate/'
    },
    assets: commonAssets
  },
  '/case-studies/insurance-company/': {
    view: 'case-studies/insurance-company.twig',
    vars: {
      ...defaultVariables,
      title: 'Major Insurance Company | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/insurance-company/'
    },
    assets: commonAssets
  },
  '/case-studies/analytics-company/': {
    view: 'case-studies/analytics-company.twig',
    vars: {
      ...defaultVariables,
      title: 'Major Content Analytics Company | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/analytics-company/'
    },
    assets: commonAssets
  },
  '/case-studies/publishing-conglomerate/': {
    view: 'case-studies/publishing-conglomerate.twig',
    vars: {
      ...defaultVariables,
      title: 'Major Publishing Conglomerate | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/publishing-conglomerate/'
    },
    assets: commonAssets
  },
  '/case-studies/entertainment-company/': {
    view: 'case-studies/entertainment-company.twig',
    vars: {
      ...defaultVariables,
      title: 'Major Media and Entertainment Company | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/entertainment-company/'
    },
    assets: commonAssets
  },
  '/case-studies/terrahub/': {
    view: 'case-studies/terrahub.twig',
    vars: {
      ...defaultVariables,
      title: 'TerraHub - Terraform Automation | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/terrahub/'
    },
    assets: commonAssets
  },
  '/case-studies/adtechmedia/': {
    view: 'case-studies/adtechmedia.twig',
    vars: {
      ...defaultVariables,
      title: 'AdTechMedia | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/adtechmedia/'
    },
    assets: adtechmediaAssets
  },
  '/case-studies/manning/': {
    view: 'case-studies/manning.twig',
    vars: {
      ...defaultVariables,
      title: 'Manning Publications | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/manning/'
    },
    assets: commonAssets
  },
  '/about/': {
    view: 'about/index.twig',
    vars: {
      ...defaultVariables,
      title: 'About Us | ' + defaultVariables.title,
      href: defaultVariables.url + '/about/'
    },
    assets: aboutAssets
  },
  '/about/team/': {
    view: 'about/team.twig',
    vars: {
      ...defaultVariables,
      title: 'Our Team | About Us | ' + defaultVariables.title,
      href: defaultVariables.url + '/about/team/'
    },
    assets: aboutAssets
  },
  '/blog/': {
    view: 'blog/index.twig',
    vars: {
      ...defaultVariables,
      postsListObject: posts,
      nrVisiblePosts: 4,
      title: 'Blog Articles | ' + defaultVariables.title,
      href: defaultVariables.url + '/blog/',
      author: 'https://twitter.com/@eistrati',
      href: '/blog/',
      image: '/images/blog/2018-08-12/dashboard.png',
      description:
        'Mitoc Group is a technology company focusing on automation using cloud native services. Our engineers are proudly sharing here our thoughts and our experience, therefore please enjoy them responsibly.',
      publisher: 'https://www.facebook.com/MitocGroup',
      timestamp: '2018-04-01T12:34:56.789Z',
      fb_brand: 'MitocGroup',
      fb_type: 'website',
      tw_handle: '@MitocGroup',
      tw_type: 'summary_large_image'
    },
    assets: blogAssets
  },
  '/contact/': {
    view: 'contact.twig',
    vars: {
      ...defaultVariables,
      title: 'Contact Us | ' + defaultVariables.title,
      href: defaultVariables.url + '/contact/'
    },
    assets: contactAssets
  },
  '/terms/': {
    view: 'terms.twig',
    vars: {
      ...defaultVariables,
      title: 'Terms and Conditions | ' + defaultVariables.title,
      href: defaultVariables.url + '/terms/'
    },
    assets: commonAssets
  },
  '/privacy/': {
    view: 'privacy.twig',
    vars: {
      ...defaultVariables,
      title: 'Privacy Policy | ' + defaultVariables.title,
      href: defaultVariables.url + '/privacy/'
    },
    assets: commonAssets
  },
  '/404/': {
    view: '404.twig',
    vars: {
      ...defaultVariables,
      title: '404 Page Not Found | ' + defaultVariables.title
    },
    assets: commonAssets
  }
}

Object.keys(posts).forEach(key => {
  let postPath = `/blog/${key}/`

  routes[postPath] = {
    view: 'blog/post.twig',
    vars: {
      ...defaultVariables,
      ...posts[key],
      posts
    }
  }
})

module.exports = {
  server: {
    port: 8000,
    ignorePatterns: ['.idea', '.git', 'bin', 'backend', 'build']
  },
  routes: routes
}
<commit_msg>minor improvements<commit_after>'use strict'

const fs = require('fs')
const postsContent = fs.readFileSync('static/json/posts.json')
const postsListObject = JSON.parse(postsContent)

const defaultVariables = {
  title: 'Mitoc Group',
  description:
    'Mitoc Group is a technology company focusing on automation using cloud native services. Our track record includes helping private equity portfolio companies migrate to public clouds, as well as establish devops and dataops processes using cloud native services and industry best practices. We deliver automations and business results in weeks instead of months.',
  author: 'https://twitter.com/@eistrati',
  publisher: 'MitocGroup.com',
  company: 'Mitoc Group Inc.',
  address: '2 University Plaza Suite 100',
  city: 'Hackensack',
  state: 'NJ',
  zip: '07601',
  year: '2014',
  phone: '(+1) 801 810 8186',
  email: 'hello@mitocgroup.com',
  url: 'https://www.mitocgroup.com',
  image: 'https://www.mitocgroup.com/images/head.png',
  logo: 'https://www.mitocgroup.com/images/v2/logos/mitoc.svg',
  // fb_app_id: '',
  fb_type: 'website',
  fb_brand: 'MitocGroup',
  tw_type: 'summary',
  tw_handle: '@MitocGroup',
  image_tw: 'https://www.mitocgroup.com/images/cover-tw.png',
  image_fb: 'https://www.mitocgroup.com/images/cover-fb.png'
}

const commonScripts = [
  'js/libs/jquery.min.js',
  'js/libs/jquery-mailchimp.min.js',
  'js/libs/jquery-popup.min.js',
  'js/libs/lazysizes.min.js',
  'js/modal-effects.js',
  'js/main.js',
  'js/mailchimp.js'
]

const commonStyles = [
  'styles/libs/font-awesome.min.css',
  'styles/libs/materialdesignicons.min.css',
  'styles/variables.scss',
  'styles/fonts.scss',
  'styles/base.scss',
  'styles/main.scss',
  'styles/mixins.scss',
  'styles/responsive.scss'
]

const indexAssets = {
  'js/index.min.js': [...commonScripts, 'js/libs/slick.min.js', 'js/carousel.js'],
  'css/index.min.css': [...commonStyles, 'styles/libs/slick.min.css', 'styles/libs/slick-theme.min.css']
}

const commonAssets = {
  'js/common.min.js': [...commonScripts, 'js/scroll.js'],
  'css/common.min.css': commonStyles
}

const servicesAssets = {
  'js/services.min.js': commonScripts,
  'css/services.min.css': [...commonStyles, 'styles/services.scss']
}

const partnersAssets = {
  'js/partners.min.js': commonScripts,
  'css/partners.min.css': [...commonStyles, 'styles/partners.scss']
}

const adtechmediaAssets = {
  'js/adtechmedia.min.js': ['js/libs/bodymovin.min.js', 'js/animation.js'],
  'js/common.min.js': commonScripts,
  'css/common.min.css': commonStyles
}

const aboutAssets = {
  'js/about.min.js': commonScripts,
  'css/about.min.css': [...commonStyles, 'styles/about.scss']
}

const blogAssets = {
  'js/blog.min.js': [...commonScripts, 'js/libs/highlight.pack.min.js', 'js/blog.js'],
  'css/blog.min.css': [...commonStyles, 'styles/libs/github.min.css', 'styles/blog.scss', 'styles/post.scss']
}

const contactAssets = {
  'js/contact.min.js': commonScripts,
  'css/contact.min.css': [...commonStyles, 'styles/contact.scss']
}

let posts = {}
posts = Object.keys(postsListObject)
  .sort((a, b) => {
    return -(new Date(postsListObject[a].PublicationDate) - new Date(postsListObject[b].PublicationDate))
  })
  .reduce((prev, curr) => {
    const event = new Date(postsListObject[curr].PublicationDate)
    const options = { month: 'short', day: 'numeric', year: 'numeric' }
    prev[curr] = postsListObject[curr]
    prev[curr].PublicationDate = event.toLocaleDateString('en-EN', options)
    return prev
  }, {})

let routes = {
  '/': {
    view: 'index.twig',
    vars: {
      ...defaultVariables,
      title: defaultVariables.title + ' | Cloud Native Automation in Private Equity',
      href: defaultVariables.url
    },
    assets: indexAssets
  },
  '/services/': {
    view: 'services/index.twig',
    vars: {
      ...defaultVariables,
      title: 'Professional Services | ' + defaultVariables.title,
      href: defaultVariables.url + '/services/'
    },
    assets: servicesAssets
  },
  '/services/automation-infrastructure/': {
    view: 'services/automation-infrastructure.twig',
    vars: {
      ...defaultVariables,
      title: 'Automation of Infrastructure | Professional Services | ' + defaultVariables.title,
      href: defaultVariables.url + '/services/automation-infrastructure/'
    },
    assets: servicesAssets
  },
  '/services/automation-data/': {
    view: 'services/automation-data.twig',
    vars: {
      ...defaultVariables,
      title: 'Automation of Data | Professional Services | ' + defaultVariables.title,
      href: defaultVariables.url + '/services/automation-data/'
    },
    assets: servicesAssets
  },
  '/services/automation-serverless/': {
    view: 'services/automation-serverless.twig',
    vars: {
      ...defaultVariables,
      title: 'Automation of Serverless | Professional Services | ' + defaultVariables.title,
      href: defaultVariables.url + '/services/automation-serverless/'
    },
    assets: servicesAssets
  },
  '/partners/': {
    view: 'partners/index.twig',
    vars: {
      ...defaultVariables,
      title: 'Partners Program | ' + defaultVariables.title,
      href: defaultVariables.url + '/partners/'
    },
    assets: partnersAssets
  },
  '/partners/aws/': {
    view: 'partners/aws.twig',
    vars: {
      ...defaultVariables,
      title: 'Amazon Web Services | Partners Program | ' + defaultVariables.title,
      href: defaultVariables.url + '/partners/aws/'
    },
    assets: partnersAssets
  },
  '/partners/google/': {
    view: 'partners/google.twig',
    vars: {
      ...defaultVariables,
      title: 'Google Cloud Platform | Partners Program | ' + defaultVariables.title,
      href: defaultVariables.url + '/partners/google/'
    },
    assets: partnersAssets
  },
  '/partners/2ndwatch/': {
    view: 'partners/2ndwatch.twig',
    vars: {
      ...defaultVariables,
      title: '2nd Watch | Partners Program | ' + defaultVariables.title,
      href: defaultVariables.url + '/partners/2ndwatch/'
    },
    assets: partnersAssets
  },
  '/partners/404moldova/': {
    view: 'partners/404moldova.twig',
    vars: {
      ...defaultVariables,
      title: '404 Moldova | Partners Program | ' + defaultVariables.title,
      href: defaultVariables.url + '/partners/404moldova/'
    },
    assets: partnersAssets
  },
  '/case-studies/': {
    view: 'case-studies/index.twig',
    vars: {
      ...defaultVariables,
      title: 'Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/'
    },
    assets: commonAssets
  },
  '/case-studies/broadcasting-conglomerate/': {
    view: 'case-studies/broadcasting-conglomerate.twig',
    vars: {
      ...defaultVariables,
      title: 'Major Broadcasting Conglomerate | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/broadcasting-conglomerate/'
    },
    assets: commonAssets
  },
  '/case-studies/insurance-company/': {
    view: 'case-studies/insurance-company.twig',
    vars: {
      ...defaultVariables,
      title: 'Major Insurance Company | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/insurance-company/'
    },
    assets: commonAssets
  },
  '/case-studies/analytics-company/': {
    view: 'case-studies/analytics-company.twig',
    vars: {
      ...defaultVariables,
      title: 'Major Content Analytics Company | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/analytics-company/'
    },
    assets: commonAssets
  },
  '/case-studies/publishing-conglomerate/': {
    view: 'case-studies/publishing-conglomerate.twig',
    vars: {
      ...defaultVariables,
      title: 'Major Publishing Conglomerate | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/publishing-conglomerate/'
    },
    assets: commonAssets
  },
  '/case-studies/entertainment-company/': {
    view: 'case-studies/entertainment-company.twig',
    vars: {
      ...defaultVariables,
      title: 'Major Media and Entertainment Company | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/entertainment-company/'
    },
    assets: commonAssets
  },
  '/case-studies/terrahub/': {
    view: 'case-studies/terrahub.twig',
    vars: {
      ...defaultVariables,
      title: 'TerraHub - Terraform Automation | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/terrahub/'
    },
    assets: commonAssets
  },
  '/case-studies/adtechmedia/': {
    view: 'case-studies/adtechmedia.twig',
    vars: {
      ...defaultVariables,
      title: 'AdTechMedia | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/adtechmedia/'
    },
    assets: adtechmediaAssets
  },
  '/case-studies/manning/': {
    view: 'case-studies/manning.twig',
    vars: {
      ...defaultVariables,
      title: 'Manning Publications | Case Studies | ' + defaultVariables.title,
      href: defaultVariables.url + '/case-studies/manning/'
    },
    assets: commonAssets
  },
  '/about/': {
    view: 'about/index.twig',
    vars: {
      ...defaultVariables,
      title: 'About Us | ' + defaultVariables.title,
      href: defaultVariables.url + '/about/'
    },
    assets: aboutAssets
  },
  '/about/team/': {
    view: 'about/team.twig',
    vars: {
      ...defaultVariables,
      title: 'Our Team | About Us | ' + defaultVariables.title,
      href: defaultVariables.url + '/about/team/'
    },
    assets: aboutAssets
  },
  '/blog/': {
    view: 'blog/index.twig',
    vars: {
      ...defaultVariables,
      postsListObject: posts,
      nrVisiblePosts: 3,
      title: 'Blog Articles | ' + defaultVariables.title,
      description:
        'Mitoc Group is a technology company focusing on automation using cloud native services. Our engineers are proudly sharing here our thoughts and our experience, therefore please enjoy them responsibly.',
      href: defaultVariables.url + '/blog/',
      image: '/images/blog/2018-08-12/dashboard.png',
      publisher: 'https://www.facebook.com/MitocGroup',
      timestamp: '2018-04-01T12:34:56.789Z'
    },
    assets: blogAssets
  },
  '/contact/': {
    view: 'contact.twig',
    vars: {
      ...defaultVariables,
      title: 'Contact Us | ' + defaultVariables.title,
      href: defaultVariables.url + '/contact/'
    },
    assets: contactAssets
  },
  '/terms/': {
    view: 'terms.twig',
    vars: {
      ...defaultVariables,
      title: 'Terms and Conditions | ' + defaultVariables.title,
      href: defaultVariables.url + '/terms/'
    },
    assets: commonAssets
  },
  '/privacy/': {
    view: 'privacy.twig',
    vars: {
      ...defaultVariables,
      title: 'Privacy Policy | ' + defaultVariables.title,
      href: defaultVariables.url + '/privacy/'
    },
    assets: commonAssets
  },
  '/404/': {
    view: '404.twig',
    vars: {
      ...defaultVariables,
      title: '404 Page Not Found | ' + defaultVariables.title
    },
    assets: commonAssets
  }
}

Object.keys(posts).forEach(key => {
  let postPath = `/blog/${key}/`

  routes[postPath] = {
    view: 'blog/post.twig',
    vars: {
      ...defaultVariables,
      ...posts[key],
      posts
    }
  }
})

module.exports = {
  server: {
    port: 8000,
    ignorePatterns: ['.idea', '.git', 'bin', 'backend', 'build']
  },
  routes: routes
}
<|endoftext|>