<commit_before>'use strict';

angular.module('mwComponents', ['ngSanitize','btford.markdown'])

  .directive('mwTextCollapse', function ($filter) {
    return {
      restrict: 'A',
      scope: {
        mwTextCollapse: '@',
        length: '=',
        markdown: '='
      },
      templateUrl: 'uikit/templates/mwComponents/mwTextCollapse.html',
      link: function (scope) {
        // set default length
        if (scope.length && typeof scope.length === 'number') {
          scope.defaultLength = scope.length;
        } else {
          scope.defaultLength = 200;
        }

        // set start length for filter
        scope.filterLength = scope.defaultLength;

        // apply filter length to text
        scope.text = function () {
          return $filter('reduceStringTo')(
            scope.mwTextCollapse, scope.filterLength
          );
        };

        // show Button if text is longer than desired
        scope.showButton = false;
        if (scope.mwTextCollapse.length > scope.defaultLength) {
          scope.showButton = true;
        }

        // set button to "show more" or "show less"
        scope.showLessOrMore = function () {
          if (scope.filterLength === scope.defaultLength) {
            return 'common.showMore';
          } else {
            return 'common.showLess';
          }
        };

        // collapse/expand text by setting filter length
        scope.toggleLength = function () {
          if (scope.filterLength === scope.defaultLength) {
            delete scope.filterLength;
          } else {
            scope.filterLength = scope.defaultLength;
          }
        };
      }
    };
  })

  /**
   * @ngdoc directive
   * @name mwComponents.directive:mwFilterableSearch
   * @element div
   * @description
   *
   * Creates a search field to filter by in the sidebar. Search is triggered on keypress 'enter'.
   *
   * @param {filterable} filterable Filterable instance.
   * @param {expression} disabled If expression evaluates to true, input is disabled.
   * @param {string} property The name of the property on which the filtering should happen.
   */
  .directive('mwFilterableSearch', function ($timeout, $animate, Loading, Detect) {
    return {
      scope: {
        filterable: '=',
        mwDisabled: '=',
        property: '@'
//        loading: '='
      },
      templateUrl: 'uikit/templates/mwComponents/mwFilterableSearch.html',
      link: function (scope, elm) {
        $animate.enabled(false, elm.find('.search-indicator'));
        scope.model = scope.filterable.properties[scope.property];
        scope.inputLength = 0;
        scope.isMobile = Detect.isMobile();

        var timeout;

        var search = function () {
          return scope.filterable.applyFilters();
        };

        var throttler = function () {
          scope.searching = true;

          $timeout.cancel(timeout);

          timeout = $timeout(function () {

            search().then(function () {
              $timeout.cancel(timeout);
              scope.searching = false;
            }, function () {
              scope.searching = false;
            });

          }, 500);
        };

        scope.search = function (event) {

          if (!event || event.keyCode === 13) {
            search();
          } else {

            if (!scope.isMobile) {
              throttler();
            }
          }
        };

        scope.reset = function () {
          scope.model.value = '';
          search();
        };
      }
    };
  })

  .service('mwMarkdown', function () {
    var converter = new window.showdown.Converter({
      headerLevelStart: 3,
      smoothLivePreview: true,
      extensions: [function () {
        return [
          // Replace escaped @ symbols
          {type: 'lang', regex: '•', replace: '-'},
          {
            type: 'lang', filter: function (text) {
            return text.replace(/https?:\/\/\S*/g, function (link) {
              return '<' + link + '>';
            });
          }
          }
        ];
      }]
    });
    return {
      convert: function (val) {
        return converter.makeHtml(val);
      }
    };
  })

  .directive('mwMarkdownPreview', function () {
    return {
      scope: {
        mwModel: '=mwMarkdownPreview'
      },
      templateUrl: 'uikit/templates/mwComponents/mwMarkdownPreview.html',
      link: function (scope, elm) {
        elm.addClass('mw-markdown-preview');
      }
    };
  })

  .directive('mwMarkdown', ['$sanitize', 'mwMarkdown', function ($sanitize, mwMarkdown) {
    return {
      restrict: 'AE',
      link: function (scope, element, attrs) {
        var convertText = function(text){
          try {
            var html = text ? $sanitize(mwMarkdown.convert(text)) : '';
            element.html(html);
          } catch (e) {
            element.text(text);
          }
        };

        if (attrs.mwMarkdown) {
          scope.$watch(attrs.mwMarkdown, function (newVal) {
            convertText(newVal);
          });
        } else {
          convertText(element.text());
        }
      }
    };
  }])

  /**
   * @ngdoc directive
   * @name mwModal.directive:mwModalOnEnter
   * @element button
   * @description
   * Adds ability to trigger button with enter key. Checks validation if button is part of a form.
   */
  .directive('mwModalOnEnter', function (validateEnterKeyUp) {
    return {
      restrict: 'A',
      require: '?^form',
      link: function (scope, elm, attr, ctrl) {
        elm.parents('.modal').first().on('keyup', function (event) {
          validateEnterKeyUp.clickIfValid(elm, event, ctrl);
        });
      }
    };
  })

  .service('validateEnterKeyUp', function () {
    return {
      clickIfValid: function (element, event, controller) {
        if (event.keyCode === 13 && event.target.nodeName !== 'SELECT' && !event.isDefaultPrevented()) {
          if ((controller && controller.$valid) || !controller) {
            element.click();
          }
        }
      }
    };
  });
<commit_msg>removes btford markdown  dependency<commit_after>'use strict';

angular.module('mwComponents', ['ngSanitize'])

  .directive('mwTextCollapse', function ($filter) {
    return {
      restrict: 'A',
      scope: {
        mwTextCollapse: '@',
        length: '=',
        markdown: '='
      },
      templateUrl: 'uikit/templates/mwComponents/mwTextCollapse.html',
      link: function (scope) {
        // set default length
        if (scope.length && typeof scope.length === 'number') {
          scope.defaultLength = scope.length;
        } else {
          scope.defaultLength = 200;
        }

        // set start length for filter
        scope.filterLength = scope.defaultLength;

        // apply filter length to text
        scope.text = function () {
          return $filter('reduceStringTo')(
            scope.mwTextCollapse, scope.filterLength
          );
        };

        // show Button if text is longer than desired
        scope.showButton = false;
        if (scope.mwTextCollapse.length > scope.defaultLength) {
          scope.showButton = true;
        }

        // set button to "show more" or "show less"
        scope.showLessOrMore = function () {
          if (scope.filterLength === scope.defaultLength) {
            return 'common.showMore';
          } else {
            return 'common.showLess';
          }
        };

        // collapse/expand text by setting filter length
        scope.toggleLength = function () {
          if (scope.filterLength === scope.defaultLength) {
            delete scope.filterLength;
          } else {
            scope.filterLength = scope.defaultLength;
          }
        };
      }
    };
  })

  /**
   * @ngdoc directive
   * @name mwComponents.directive:mwFilterableSearch
   * @element div
   * @description
   *
   * Creates a search field to filter by in the sidebar. Search is triggered on keypress 'enter'.
   *
   * @param {filterable} filterable Filterable instance.
   * @param {expression} disabled If expression evaluates to true, input is disabled.
   * @param {string} property The name of the property on which the filtering should happen.
   */
  .directive('mwFilterableSearch', function ($timeout, $animate, Loading, Detect) {
    return {
      scope: {
        filterable: '=',
        mwDisabled: '=',
        property: '@'
//        loading: '='
      },
      templateUrl: 'uikit/templates/mwComponents/mwFilterableSearch.html',
      link: function (scope, elm) {
        $animate.enabled(false, elm.find('.search-indicator'));
        scope.model = scope.filterable.properties[scope.property];
        scope.inputLength = 0;
        scope.isMobile = Detect.isMobile();

        var timeout;

        var search = function () {
          return scope.filterable.applyFilters();
        };

        var throttler = function () {
          scope.searching = true;

          $timeout.cancel(timeout);

          timeout = $timeout(function () {

            search().then(function () {
              $timeout.cancel(timeout);
              scope.searching = false;
            }, function () {
              scope.searching = false;
            });

          }, 500);
        };

        scope.search = function (event) {

          if (!event || event.keyCode === 13) {
            search();
          } else {

            if (!scope.isMobile) {
              throttler();
            }
          }
        };

        scope.reset = function () {
          scope.model.value = '';
          search();
        };
      }
    };
  })

  .service('mwMarkdown', function () {
    var converter = new window.showdown.Converter({
      headerLevelStart: 3,
      smoothLivePreview: true,
      extensions: [function () {
        return [
          // Replace escaped @ symbols
          {type: 'lang', regex: '•', replace: '-'},
          {
            type: 'lang', filter: function (text) {
            return text.replace(/https?:\/\/\S*/g, function (link) {
              return '<' + link + '>';
            });
          }
          }
        ];
      }]
    });
    return {
      convert: function (val) {
        return converter.makeHtml(val);
      }
    };
  })

  .directive('mwMarkdownPreview', function () {
    return {
      scope: {
        mwModel: '=mwMarkdownPreview'
      },
      templateUrl: 'uikit/templates/mwComponents/mwMarkdownPreview.html',
      link: function (scope, elm) {
        elm.addClass('mw-markdown-preview');
      }
    };
  })

  .directive('mwMarkdown', ['$sanitize', 'mwMarkdown', function ($sanitize, mwMarkdown) {
    return {
      restrict: 'AE',
      link: function (scope, element, attrs) {
        var convertText = function(text){
          try {
            var html = text ? $sanitize(mwMarkdown.convert(text)) : '';
            element.html(html);
          } catch (e) {
            element.text(text);
          }
        };

        if (attrs.mwMarkdown) {
          scope.$watch(attrs.mwMarkdown, function (newVal) {
            convertText(newVal);
          });
        } else {
          convertText(element.text());
        }
      }
    };
  }])

  /**
   * @ngdoc directive
   * @name mwModal.directive:mwModalOnEnter
   * @element button
   * @description
   * Adds ability to trigger button with enter key. Checks validation if button is part of a form.
   */
  .directive('mwModalOnEnter', function (validateEnterKeyUp) {
    return {
      restrict: 'A',
      require: '?^form',
      link: function (scope, elm, attr, ctrl) {
        elm.parents('.modal').first().on('keyup', function (event) {
          validateEnterKeyUp.clickIfValid(elm, event, ctrl);
        });
      }
    };
  })

  .service('validateEnterKeyUp', function () {
    return {
      clickIfValid: function (element, event, controller) {
        if (event.keyCode === 13 && event.target.nodeName !== 'SELECT' && !event.isDefaultPrevented()) {
          if ((controller && controller.$valid) || !controller) {
            element.click();
          }
        }
      }
    };
  });
<|endoftext|>


<commit_before>'use strict';

var User = require('./model');

var getUser = function (req, res) {
  User.findOne({_id: req.params.id }, function(err, user) {
    if(err) {
      res.send(err);
      throw err;
    }
    res.send(user);
  });

};

var addUser = function (req, res) {
  var user = new User(req.body);
  user.save(function(err, user) {
    if(err) {
      res.send(err);
      throw err;
    }
    res.send(user);
  });

};

var deleteUser = function (req, res) {
  User.remove({_id: req.params.id }, function(err) {
    if(err) {
      res.send(err);
      throw err;
    }
    res.send('removed user');
  });
};

module.exports.getUser = getUser;
module.exports.addUser = addUser;
module.exports.deleteUser = deleteUser;<commit_msg>(bug) Fix param on users controller<commit_after>'use strict';

var User = require('./model');

var getUser = function (req, res) {
  User.findOne({_id: req.params.user_id }, function(err, user) {
    if(err) {
      res.send(err);
      throw err;
    }
    res.send(user);
  });

};

var addUser = function (req, res) {
  var user = new User(req.body);
  user.save(function(err, user) {
    if(err) {
      res.send(err);
      throw err;
    }
    res.send(user);
  });

};

var deleteUser = function (req, res) {
  User.remove({_id: req.params.user_id }, function(err) {
    if(err) {
      res.send(err);
      throw err;
    }
    res.send('removed user');
  });
};

module.exports.getUser = getUser;
module.exports.addUser = addUser;
module.exports.deleteUser = deleteUser;<|endoftext|>


<commit_before>'use strict';

var app = app || {};

(function(module) {

  const mapThings = {};

  mapThings.userLocation;
  mapThings.map;
  mapThings.infoWindow;
  mapThings.geocoder;

  mapThings.initMap = function initMap() {
    mapThings.geocoder = new google.maps.Geocoder();
    mapThings.map = new google.maps.Map(document.getElementById('google-map'), {
      center: {lat: 47.608, lng: -122.335167},
      zoom: 13
    });
    mapThings.infoWindow = new google.maps.InfoWindow;

    if(navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(function(position) {
        var pos = {
          lat: position.coords.latitude,
          lng: position.coords.longitude
        };
        mapThings.userLocation = new google.maps.LatLng(pos.lat, pos.lng);

        mapThings.infoWindow.setPosition(pos);
        mapThings.infoWindow.setContent('Current Location');
        mapThings.infoWindow.open(mapThings.map);
        mapThings.map.setCenter(pos);
      }, function() {
        handleLocationError(true, mapThings.infoWindow, mapThings.map.getCenter());
      });
    } else {
      handleLocationError(false, mapThings.infoWindow, mapThings.map.getCenter());
    }
    google.maps.event.addDomListener(window, 'resize', function () {
      var center = mapThings.map.getCenter();
      google.maps.event.trigger(mapThings.map, 'resize');
      mapThings.map.setCenter(center);
    })
  };

  function handleLocationError(browserHasGeolocation, infoWindow, pos) {
    infoWindow.setPosition(pos);
    infoWindow.setContent(browserHasGeolocation ?
      'Error: The Geolocation service failed.' :
      'Error: Your browser doesn\'t support geolocation.');
    infoWindow.open(mapThings.map);
  }

  mapThings.makeMarkers = function () {
    app.meetings.filtered.forEach((ele, idx) => {
      var marker = new google.maps.Marker({
        map: mapThings.map,
        position: new google.maps.LatLng(ele.lat, ele.lng)
      });
    });
  };
  module.mapThings = mapThings;
})(app);
<commit_msg>Building event listener for marker click event<commit_after>'use strict';

var app = app || {};

(function(module) {

  const mapThings = {};

  mapThings.userLocation;
  mapThings.map;
  mapThings.infoWindow;
  mapThings.geocoder;
  mapThings.markerWindow;

  mapThings.initMap = function initMap() {
    mapThings.geocoder = new google.maps.Geocoder();
    mapThings.map = new google.maps.Map(document.getElementById('google-map'), {
      center: {lat: 47.608, lng: -122.335167},
      zoom: 13
    });
    mapThings.infoWindow = new google.maps.InfoWindow;

    if(navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(function(position) {
        var pos = {
          lat: position.coords.latitude,
          lng: position.coords.longitude
        };
        mapThings.userLocation = new google.maps.LatLng(pos.lat, pos.lng);

        mapThings.infoWindow.setPosition(pos);
        mapThings.infoWindow.setContent('Current Location');
        mapThings.infoWindow.open(mapThings.map);
        mapThings.map.setCenter(pos);
      }, function() {
        handleLocationError(true, mapThings.infoWindow, mapThings.map.getCenter());
      });
    } else {
      handleLocationError(false, mapThings.infoWindow, mapThings.map.getCenter());
    }
    google.maps.event.addDomListener(window, 'resize', function () {
      var center = mapThings.map.getCenter();
      google.maps.event.trigger(mapThings.map, 'resize');
      mapThings.map.setCenter(center);
    })
    var markerInfo = `<p>Test String</p>`;
    mapThings.markerWindow = new google.maps.InfoWindow({
      content: markerInfo
    });
    mapThings.marker.addListener('click', function() {
      mapThings.markerWindow.open(mapThings.map, mapThings.marker)
    });
  };

  function handleLocationError(browserHasGeolocation, infoWindow, pos) {
    infoWindow.setPosition(pos);
    infoWindow.setContent(browserHasGeolocation ?
      'Error: The Geolocation service failed.' :
      'Error: Your browser doesn\'t support geolocation.');
    infoWindow.open(mapThings.map);
  }

  mapThings.makeMarkers = function () {
    app.meetings.filtered.forEach((ele, idx) => {
      var marker = new google.maps.Marker({
        map: mapThings.map,
        position: new google.maps.LatLng(ele.lat, ele.lng)
      });
    });
  };
  module.mapThings = mapThings;
})(app);
<|endoftext|>


<commit_before>'use strict'

function generateMetadataPrivatePerson (options) {
  if (!options) {
    throw new Error('Missing required input: options')
  }
  if (!options.firstName) {
    throw new Error('Missing required input: options.firstName')
  }
  if (!options.lastName) {
    throw new Error('Missing required input: options.lastName')
  }
  if (!options.personalIdNumber) {
    throw new Error('Missing required input: options.personalIdNumber')
  }
  if (!options.email) {
    throw new Error('Missing required input: options.email')
  }
  if (!options.streetAddress) {
    throw new Error('Missing required input: options.streetAddress')
  }
  if (!options.zipCode) {
    throw new Error('Missing required input: options.zipCode')
  }
  if (!options.zipPlace) {
    throw new Error('Missing required input: options.zipPlace')
  }
  if (!options.area) {
    throw new Error('Missing required input: options.area')
  }

  var meta = {
    'clientService': 'ContactService',
    'clientMethod': 'SynchronizePrivatePerson',
    'args': {
      'parameter': {
        'Firstname': options.firstName,
        'Middlename': options.middleName,
        'Lastname': options.lastName,
        'PersonalId': options.personalIdNumber,
        'Email': options.email,
        'PrivateAddress': [
          {
            Country: 'NOR',
            StreetAddress: options.streetAddress,
            ZipCode: options.zipCode,
            ZipPlace: options.zipPlace,
            Area: options.area
          }
        ]
      }
    }
  }

  return meta
}

module.exports = generateMetadataPrivatePerson
<commit_msg>Update add-private-person.js<commit_after>'use strict'

function generateMetadataPrivatePerson (options) {
  if (!options) {
    throw new Error('Missing required input: options')
  }
  if (!options.firstName) {
    throw new Error('Missing required input: options.firstName')
  }
  if (!options.lastName) {
    throw new Error('Missing required input: options.lastName')
  }
  if (!options.personalIdNumber) {
    throw new Error('Missing required input: options.personalIdNumber')
  }
  if (!options.email) {
    throw new Error('Missing required input: options.email')
  }
  if (!options.streetAddress) {
    throw new Error('Missing required input: options.streetAddress')
  }
  if (!options.zipCode) {
    throw new Error('Missing required input: options.zipCode')
  }
  if (!options.zipPlace) {
    throw new Error('Missing required input: options.zipPlace')
  }
  if (!options.area) {
    throw new Error('Missing required input: options.area')
  }

  var meta = {
    'clientService': 'ContactService',
    'clientMethod': 'SynchronizePrivatePerson',
    'args': {
      'parameter': {
        'FirstName': options.firstName,
        'MiddleName': options.middleName || false,
        'LastName': options.lastName,
        'PersonalIdNumber': options.personalIdNumber,
        'Email': options.email,
        'PrivateAddress': [
          {
            Country: 'NOR',
            StreetAddress: options.streetAddress,
            ZipCode: options.zipCode,
            ZipPlace: options.zipPlace,
            Area: options.area
          }
        ]
      }
    }
  }
  return meta
}

module.exports = generateMetadataPrivatePerson
<|endoftext|>


<commit_before>/*jslint node: true */
"use strict";
require('./enforce_singleton.js');

var EventEmitter = require('events').EventEmitter;

module.exports = new EventEmitter();
<commit_msg>setMaxListeners 20<commit_after>/*jslint node: true */
"use strict";
require('./enforce_singleton.js');

var EventEmitter = require('events').EventEmitter;

var eventEmitter = new EventEmitter();
eventEmitter.setMaxListeners(20);

module.exports = eventEmitter;
<|endoftext|>


<commit_before>var roleHarvester = {

	/** @param {Creep} creep **/
	run: function(creep) {

		if (creep.memory.harvesting) {
			var sources = creep.room.find(FIND_SOURCES);
			var energy = creep.pos.findInRange(FIND_DROPPED_ENERGY, 3);

			if (energy.length) {
				creep.pickup(energy[0]);
			}

			if (!creep.memory.source) {
				for (source in sources) {
					if (_.filter(Game.creeps, (creep) =>
							(creep.memory.source == source)
					).length < 5) {
						creep.memory.source = source;
					}
				}
			}
			if (creep.harvest(sources[creep.memory.source]) == ERR_NOT_IN_RANGE) {
				creep.moveTo(sources[creep.memory.source]);
			}
			if (creep.carry.energy == creep.carryCapacity) {
				creep.say('Depositing');
			  creep.memory.harvesting = false;
			}
		}
		else {
			var targets = creep.pos.findInRange(FIND_STRUCTURES, 3, {
				filter: (structure) => {
					return (structure.structureType == STRUCTURE_CONTAINER);
				}
			});

			if (targets.length == 0) {
				var targets = creep.room.find(FIND_STRUCTURES, {
					filter: (structure) => {
						return (
							((structure.structureType == STRUCTURE_SPAWN) ||
							 (structure.structureType == STRUCTURE_EXTENSION)) &&
							 (structure.energy < structure.energyCapacity));
					}
				});
			}
			if (creep.transfer(targets[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
				creep.moveTo(targets[0]);
			}
			if (creep.carry.energy == 0) {
				creep.say('Harvesting');
			  creep.memory.harvesting = true;
			}
		}

	} // function

}; // roleHarvester

module.exports = roleHarvester;<commit_msg>Minor changes<commit_after>var roleHarvester = {

	/** @param {Creep} creep **/
	run: function(creep) {

		if (creep.memory.harvesting) {
			var sources = creep.room.find(FIND_SOURCES);
			var energy = creep.pos.findInRange(FIND_DROPPED_ENERGY, 3);

			if (energy.length) {
				creep.pickup(energy[0]);
			}

			if (!creep.memory.source) {
				for (source in sources) {
					if (_.filter(Game.creeps, (creep) =>
							(creep.memory.role == 'harvester') &&
							(creep.memory.source == source)
					).length < 1) {
						creep.memory.source = source;
					}
				}
			}
			if (creep.harvest(sources[creep.memory.source]) == ERR_NOT_IN_RANGE) {
				creep.moveTo(sources[creep.memory.source]);
			}
			if (creep.carry.energy == creep.carryCapacity) {
				creep.say('Depositing');
			  creep.memory.harvesting = false;
			}
		}
		else {
			var targets = creep.pos.findInRange(FIND_STRUCTURES, 3, {
				filter: (structure) => {
					return (structure.structureType == STRUCTURE_CONTAINER);
				}
			});

			if (targets.length == 0) {
				var targets = creep.room.find(FIND_STRUCTURES, {
					filter: (structure) => {
						return (
							((structure.structureType == STRUCTURE_SPAWN) ||
							 (structure.structureType == STRUCTURE_EXTENSION)) &&
							 (structure.energy < structure.energyCapacity));
					}
				});
			}
			if (creep.transfer(targets[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
				creep.moveTo(targets[0]);
			}
			if (creep.carry.energy == 0) {
				creep.say('Harvesting');
			  creep.memory.harvesting = true;
			}
		}

	} // function

}; // roleHarvester

module.exports = roleHarvester;<|endoftext|>


<commit_before>'use strict';

var consts = require('../../constants');

function configure (app, wares, settings) {
  var express = require('express'),
      api = express.Router( )
  ;
  // invoke common middleware
  api.use(wares.sendJSONStatus);
  // text body types get handled as raw buffer stream
  api.use(wares.bodyParser.raw( ));
  // json body types get handled as parsed json
  api.use(wares.bodyParser.json( ));
  // also support url-encoded content-type
  api.use(wares.bodyParser.urlencoded({ extended: true }));

  /**********\
   * Settings
  \**********/
  api.param('alias', function (req, res, next, alias) {
    console.log('alias param', alias);
    settings.alias(alias, function (err, profile) {
      console.log('list');
      req.alias = profile;
      next(err);
    });
  });
  api.get('/settings/', function(req, res) {
    settings.list(function (err, profiles) {
      console.log('list');
      return res.json(profiles);
    });
  });
  // Fetch settings
  api.get('/settings/:alias', function(req, res) {
      /*
      settings.getSettings(function(err, settings) {
          if (err)
              res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err);
          else
              return res.json(settings);
      });
      */
      res.json(req.alias);
  });

  function config_authed (app, api, wares, settings) {

    // Delete settings
    api.delete('/settings/:alias', wares.verifyAuthorization, function(req, res) {
      settings.remove(req.alias.alias, function ( ) {
        res.json({ });
      });
    });

    api.put('/settings/:alias', wares.verifyAuthorization, function(req, res) {
      // settings.update( );
      res.json(req.query);
    });

    api.post('/settings/:alias', wares.verifyAuthorization, function(req, res) {
      // settings.update( );
      var r = {
        q: req.query
      , b: req.body
      , p: req.params
      , alias: req.alias
      };
      var b = req.body;
      b.alias = req.params.alias
      settings.update(b, function (err, profile) {
        res.json(profile);
      });

      // res.json(r);
    });

    // Replace settings
    api.put('/settings', wares.verifyAuthorization, function(req, res) {
        // Retrieve the JSON formatted record.
        var json = req.body;

        // Send the new settings to mongodb.
        settings.updateSettings(json, function(err, config) {
            if (err)
                res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err);
            else {
                // Add a warning to the outgoing status when HTTPS is not being used.
                var warning = '';
                if (req.secure === false)
                    warning = 'WARNING: HTTPS is required to secure your data!';

                res.json(config);
            }
        });
    });
  }

  if (app.enabled('api')) {
    config_authed(app, api, wares, settings);
  }

  return api;
}

module.exports = configure;

<commit_msg>cleanup/comment settings api<commit_after>'use strict';

var consts = require('../../constants');

function configure (app, wares, settings) {
  var express = require('express'),
      api = express.Router( )
  ;
  // invoke common middleware
  api.use(wares.sendJSONStatus);
  // text body types get handled as raw buffer stream
  api.use(wares.bodyParser.raw( ));
  // json body types get handled as parsed json
  api.use(wares.bodyParser.json( ));
  // also support url-encoded content-type
  api.use(wares.bodyParser.urlencoded({ extended: true }));

  /**********\
   * Settings
  \**********/
  // Handler for grabbing alias/profile
  api.param('alias', function (req, res, next, alias) {
    console.log('alias param', alias);
    settings.alias(alias, function (err, profile) {
      req.alias = profile;
      next(err);
    });
  });

  // List settings available
  api.get('/settings/', function(req, res) {
    settings.list(function (err, profiles) {
      return res.json(profiles);
    });
  });

  // Fetch settings
  api.get('/settings/:alias', function(req, res) {
      res.json(req.alias);
  });

  function config_authed (app, api, wares, settings) {

    // Delete settings
    api.delete('/settings/:alias', wares.verifyAuthorization, function(req, res) {
      settings.remove(req.alias.alias, function ( ) {
        res.json({ });
      });
    });

    function save_settings (req, res) {
      var b = req.body;
      b.alias = req.params.alias
      settings.update(b, function (err, profile) {
        res.json(profile);
      });
    }

    // Update settings
    api.put('/settings/:alias', wares.verifyAuthorization, save_settings);
    api.post('/settings/:alias', wares.verifyAuthorization, save_settings);

  }

  if (app.enabled('api')) {
    config_authed(app, api, wares, settings);
  }

  return api;
}

module.exports = configure;

<|endoftext|>


<commit_before>var patterns;
var disabled;

function addListeners() {
    chrome.tabs.onUpdated.addListener(rearrangeTabs);
    chrome.tabs.onAttached.addListener(rearrangeTabs);
    chrome.tabs.onCreated.addListener(rearrangeTabs);
    chrome.storage.onChanged.addListener(function(changes) {
        if (changes.hasOwnProperty('patterns')) {
            patterns = changes['patterns']['newValue'];
        }
        if (changes.hasOwnProperty('disabled')) {
            disabled = changes['disabled']['newValue'];
        }
        rearrangeTabs();
    });
}

function loadPatterns() {
    chrome.storage.sync.get({
        'patterns': []
    }, function(items) {
        patterns = items['patterns'];
    });
}

function loadDisabledState() {
    chrome.storage.sync.get({
        'disabled': false
    }, function(items) {
        disabled = items['disabled'];
    });
}

function rearrangeTabs() {
    if (disabled) {
        return;
    }
    chrome.tabs.query({
        currentWindow: true
    }, function(tabs) {
        // We can't move anything to the left of the pinned
        // tabs, so figure out how many there are, that is
        // our left-most target index.
        var targetIndex = tabs.reduce(function(count, tab) {
            if (tab.pinned) {
                return count + 1;
            } else {
                return count;
            }
        }, 0);

        for (var i = 0; i < patterns.length; i++) {
            var pattern = patterns[i];
            var patternTabs = tabs.filter(function(tab) {
                // Ignore pinned tabs since we can't move
                // them anyway and we already accounted
                // for them above.
                if (tab.pinned) {
                    return false;
                }
                if (tab.inPosition === true) {
                    return false;
                }
                return tab.url.match(pattern);
            });
            patternTabs.sort(function(leftTab, rightTab) {
                var left = leftTab.title;
                var right = rightTab.title;
                if (left < right) {
                    return -1;
                }
                if (left === right) {
                    return 0;
                }
                if (left > right) {
                    return 1;
                }
            });
            for (var j = 0; j < patternTabs.length; j++) {
                var tab = patternTabs[j];
                tab.inPosition = true;
                if (tab.index != targetIndex) {
                    chrome.tabs.move(tab.id, {
                        index: targetIndex++
                    });
                } else {
                    targetIndex += 1;
                }
            }
        }
    });
}

loadPatterns();
loadDisabledState();
addListeners();

<commit_msg>Stabilize tab sorting.<commit_after>var patterns;
var disabled;

function addListeners() {
    chrome.tabs.onUpdated.addListener(rearrangeTabs);
    chrome.tabs.onAttached.addListener(rearrangeTabs);
    chrome.tabs.onCreated.addListener(rearrangeTabs);
    chrome.storage.onChanged.addListener(function(changes) {
        if (changes.hasOwnProperty('patterns')) {
            patterns = changes['patterns']['newValue'];
        }
        if (changes.hasOwnProperty('disabled')) {
            disabled = changes['disabled']['newValue'];
        }
        rearrangeTabs();
    });
}

function loadPatterns() {
    chrome.storage.sync.get({
        'patterns': []
    }, function(items) {
        patterns = items['patterns'];
    });
}

function loadDisabledState() {
    chrome.storage.sync.get({
        'disabled': false
    }, function(items) {
        disabled = items['disabled'];
    });
}

function rearrangeTabs() {
    if (disabled) {
        return;
    }
    chrome.tabs.query({
        currentWindow: true
    }, function(tabs) {
        // We can't move anything to the left of the pinned
        // tabs, so figure out how many there are, that is
        // our left-most target index.
        var targetIndex = tabs.reduce(function(count, tab) {
            if (tab.pinned) {
                return count + 1;
            } else {
                return count;
            }
        }, 0);

        for (var i = 0; i < patterns.length; i++) {
            var pattern = patterns[i];
            var patternTabs = tabs.filter(function(tab) {
                // Ignore pinned tabs since we can't move
                // them anyway and we already accounted
                // for them above.
                if (tab.pinned) {
                    return false;
                }
                if (tab.inPosition === true) {
                    return false;
                }
                return tab.url.match(pattern);
            });
            patternTabs.sort(function(leftTab, rightTab) {
                var left = leftTab.title;
                var right = rightTab.title;
                // We can't allow ties, so we sort first on title, then on ID,
                // then, finally, on current index. ID should only be the same
                // for special windows like apps and devtools.
                if (left < right) {
                    return -1;
                }
                if (left === right) {
                    if (leftTab.id < rightTab.id) {
                        return -1;
                    }
                    if (leftTab.id === rightTab.id) {
                        if (leftTab.index < rightTab.index) {
                            return -1;
                        }
                        if (leftTab.index > rightTab.index) {
                            return 1;
                        }
                    }
                    if (leftTab.id > rightTab.id) {
                        return 1;
                    }
                }
                if (left > right) {
                    return 1;
                }
            });
            for (var j = 0; j < patternTabs.length; j++) {
                var tab = patternTabs[j];
                tab.inPosition = true;
                if (tab.index != targetIndex) {
                    chrome.tabs.move(tab.id, {
                        index: targetIndex++
                    });
                } else {
                    targetIndex += 1;
                }
            }
        }
    });
}

loadPatterns();
loadDisabledState();
addListeners();

<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import cx from 'classnames';
import ReactTransitionGroup from 'react/lib/ReactTransitionGroup';
import cloneWithProps from 'react/lib/cloneWithProps';
import { props, t } from '../utils';
import { warn } from '../utils/log';
import TransitionWrapper from '../transition-wrapper/TransitionWrapper';

/**
 * ### Renders and animates toasts (children) inline or in a portal
 */
@props({
  /**
   * list of toasts (any node with a unique key)
   */
  children: t.ReactChildren,
  /**
   * id of the element you want to render the `Toaster` in
   */
  attachTo: t.maybe(t.String),
  /**
   * custom settings for `ReactTransitionGroup`
   */
  transitionGroup: t.maybe(t.Object),
  /**
   * object with style for each transition event (used by `TransitionWrapper`)
   */
  transitionStyles: t.maybe(t.Object),
  /**
   * duration of enter transition in milliseconds (used by `TransitionWrapper`)
   */
  transitionEnterTimeout: t.Number,
  /**
   * duration of leave transition in milliseconds (used by `TransitionWrapper`)
   */
  transitionLeaveTimeout: t.Number,
  position: t.enums.of(['top-left', 'top-right', 'bottom-left', 'bottom-right']),
  id: t.maybe(t.String),
  className: t.maybe(t.String),
  style: t.maybe(t.Object)
})
export default class Toaster extends React.Component {

  static defaultProps = {
    transitionGroup: {},
    position: 'top-right'
  };

  componentWillMount() {
    this.appendToaster();
    this.renderToaster();
  }

  componentDidMount() {
    const node = this.props.attachTo ? this.toaster : ReactDOM.findDOMNode(this).parentNode;
    const { position } = window.getComputedStyle(node);
    if (position !== 'relative' && position !== 'absolute') {
      warn(['Toaster\'s parent node should have "position: relative/absolute"', node]);
    }
  }

  componentWillUnmount() {
    this.removeToaster();
  }

  getTranslationStyle(i) {
    const { position } = this.props;
    const isTop = position.indexOf('top') !== -1;
    const isRight = position.indexOf('right') !== -1;
    const translationBase = isTop ? 100 : -100;
    return {
      transform: `translateY(${translationBase * i}%)`,
      position: 'absolute',
      right: isRight ? 0 : undefined,
      left: isRight ? undefined : 0,
      bottom: isTop ? undefined : 0,
      top: isTop ? 0 : undefined
    };
  }

  getToasts = () => {
    const { children, transitionStyles, transitionEnterTimeout, transitionLeaveTimeout } = this.props;
    return React.Children.map(children, (el, i) => {
      return (
        <TransitionWrapper
          {...{ transitionStyles, transitionEnterTimeout, transitionLeaveTimeout }}
          style={this.getTranslationStyle(i)}
          key={el.key}
        >
          {cloneWithProps(el, { uniqueKey: el.key })}
        </TransitionWrapper>
      );
    });
  };

  appendToaster = () => {
    if (this.props.attachTo) {
      this.toaster = document.getElementById(this.props.attachTo);
    }
  };

  removeToaster = () => {
    if (this.toaster && this.props.attachTo) {
      this.toaster.innerHTML = ''; // stupid??
    }
  };

  getToaster = () => {
    const { style: styleProp, id, className, position } = this.props;
    const isTop = position.indexOf('top') !== -1;
    const isRight = position.indexOf('right') !== -1;
    const style = {
      position: 'absolute',
      right: isRight ? 0 : undefined,
      left: isRight ? undefined : 0,
      bottom: isTop ? undefined : 0,
      top: isTop ? 0 : undefined,
      height: '100%',
      ...styleProp
    };

    return (

        <ReactTransitionGroup {...this.props.transitionGroup}>
          {this.getToasts()}
        </ReactTransitionGroup>

    );
  };

  renderToaster = () => {
    if (this.props.attachTo) {
      ReactDOM.render(this.getToaster(), this.toaster);
    }
  };

  render() {
    if (this.props.attachTo) {
      return null;
    } else {
      return this.getToaster();
    }
  }

  componentDidUpdate() {
    this.renderToaster();
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.attachTo !== nextProps.attachTo) {
      warn('You can\'t change "attachTo" prop after the first render!');
    }
  }

}
<commit_msg>replace cloneWithProps with React.cloneElement<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import cx from 'classnames';
import ReactTransitionGroup from 'react/lib/ReactTransitionGroup';
import { props, t } from '../utils';
import { warn } from '../utils/log';
import TransitionWrapper from '../transition-wrapper/TransitionWrapper';

/**
 * ### Renders and animates toasts (children) inline or in a portal
 */
@props({
  /**
   * list of toasts (any node with a unique key)
   */
  children: t.ReactChildren,
  /**
   * id of the element you want to render the `Toaster` in
   */
  attachTo: t.maybe(t.String),
  /**
   * custom settings for `ReactTransitionGroup`
   */
  transitionGroup: t.maybe(t.Object),
  /**
   * object with style for each transition event (used by `TransitionWrapper`)
   */
  transitionStyles: t.maybe(t.Object),
  /**
   * duration of enter transition in milliseconds (used by `TransitionWrapper`)
   */
  transitionEnterTimeout: t.Number,
  /**
   * duration of leave transition in milliseconds (used by `TransitionWrapper`)
   */
  transitionLeaveTimeout: t.Number,
  position: t.enums.of(['top-left', 'top-right', 'bottom-left', 'bottom-right']),
  id: t.maybe(t.String),
  className: t.maybe(t.String),
  style: t.maybe(t.Object)
})
export default class Toaster extends React.Component {

  static defaultProps = {
    transitionGroup: {},
    position: 'top-right'
  };

  componentWillMount() {
    this.appendToaster();
    this.renderToaster();
  }

  componentDidMount() {
    const node = this.props.attachTo ? this.toaster : ReactDOM.findDOMNode(this).parentNode;
    const { position } = window.getComputedStyle(node);
    if (position !== 'relative' && position !== 'absolute') {
      warn(['Toaster\'s parent node should have "position: relative/absolute"', node]);
    }
  }

  componentWillUnmount() {
    this.removeToaster();
  }

  getTranslationStyle(i) {
    const { position } = this.props;
    const isTop = position.indexOf('top') !== -1;
    const isRight = position.indexOf('right') !== -1;
    const translationBase = isTop ? 100 : -100;
    return {
      transform: `translateY(${translationBase * i}%)`,
      position: 'absolute',
      right: isRight ? 0 : undefined,
      left: isRight ? undefined : 0,
      bottom: isTop ? undefined : 0,
      top: isTop ? 0 : undefined
    };
  }

  getToasts = () => {
    const { children, transitionStyles, transitionEnterTimeout, transitionLeaveTimeout } = this.props;
    return React.Children.map(children, (el, i) => {
      return (
        <TransitionWrapper
          {...{ transitionStyles, transitionEnterTimeout, transitionLeaveTimeout }}
          style={this.getTranslationStyle(i)}
          key={el.key}
        >
          {React.cloneElement(el, { uniqueKey: el.key })}
        </TransitionWrapper>
      );
    });
  };

  appendToaster = () => {
    if (this.props.attachTo) {
      this.toaster = document.getElementById(this.props.attachTo);
    }
  };

  removeToaster = () => {
    if (this.toaster && this.props.attachTo) {
      this.toaster.innerHTML = ''; // stupid??
    }
  };

  getToaster = () => {
    const { style: styleProp, id, className, position } = this.props;
    const isTop = position.indexOf('top') !== -1;
    const isRight = position.indexOf('right') !== -1;
    const style = {
      position: 'absolute',
      right: isRight ? 0 : undefined,
      left: isRight ? undefined : 0,
      bottom: isTop ? undefined : 0,
      top: isTop ? 0 : undefined,
      height: '100%',
      ...styleProp
    };

    return (

        <ReactTransitionGroup {...this.props.transitionGroup}>
          {this.getToasts()}
        </ReactTransitionGroup>

    );
  };

  renderToaster = () => {
    if (this.props.attachTo) {
      ReactDOM.render(this.getToaster(), this.toaster);
    }
  };

  render() {
    if (this.props.attachTo) {
      return null;
    } else {
      return this.getToaster();
    }
  }

  componentDidUpdate() {
    this.renderToaster();
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.attachTo !== nextProps.attachTo) {
      warn('You can\'t change "attachTo" prop after the first render!');
    }
  }

}
<|endoftext|>


<commit_before>
module.exports = function( node, record ){

  if( node.tags ){

    // remove rubbish tags
    delete node.tags['created_by'];
    delete node.tags['FIXME'];

    // remove dates
    for( var tag in node.tags ){
      if( tag.match('date') ){
        delete node.tags[tag];
      }
    }
  }

};<commit_msg>add osm rubbish tag<commit_after>
module.exports = function( node, record ){

  if( node.tags ){

    // remove rubbish tags
    delete node.tags['created_by'];
    delete node.tags['FIXME'];
    delete node.tags['fixme'];

    // remove dates
    for( var tag in node.tags ){
      if( tag.match('date') ){
        delete node.tags[tag];
      }
    }
  }

};<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');

let adWhitelist = (Config.adWhitelist ? Config.adWhitelist : []);
let bannedMessages = (Config.bannedMessages ? Config.bannedMessages : []);

let adRegex = new RegExp("\\b(?!(" + adWhitelist.join('|') + ").*)(\\w+(?:-\\w+)*)(?=.*psim.*us)", "g");
let adRegex2 = new RegExp("(play.pokemonshowdown.com\\/~~)(?!(" + adWhitelist.join('|') + "))", "g");

Config.chatfilter = function (message, user, room, connection) {
	user.lastActive = Date.now();

	for (let x in bannedMessages) {
		if (message.toLowerCase().indexOf(bannedMessages[x]) > -1 && bannedMessages[x] !== '' && message.substr(0, 1) !== '/') {
			if (user.locked) return false;
			Punishments.lock(user, Date.now() + 7 * 24 * 60 * 60 * 1000, "Said a banned word: " + bannedMessages[x]);
			user.popup('You have been automatically locked for sending a message containing a banned word.');
			Rooms('staff').add('[PornMonitor] ' + (room ? '(' + room + ') ' : '') + Tools.escapeHTML(user.name) +
			' was automatically locked for trying to say "' + message + '"').update();
			fs.appendFile('logs/modlog/modlog_staff.txt', '[' + (new Date().toJSON()) + '] (staff) ' + user.name + ' was locked from talking by the Server (' +
			bannedMessages[x] + ') (' + connection.ip + ')\n');
			Gold.pmUpperStaff(user.name + ' has been automatically locked for sending a message containing a banned word **Room:** ' + room.id +
			' **Message:** ' + message, '~Server');
			return false;
		}
	}

	if (!user.can('hotpatch') && (message.replace(/gold/gi, '').match(adRegex) || message.match(adRegex2))) {
		if (user.locked) return false;
		if (!user.advWarns) user.advWarns = 0;
		user.advWarns++;
		if (user.advWarns > 1) {
			Punishments.lock(user, Date.now() + 7 * 24 * 60 * 60 * 1000, "Advertising");
			fs.appendFile('logs/modlog/modlog_staff.txt', '[' + (new Date().toJSON()) + '] (staff) ' + user.name +
				' was locked from talking by the Server. (Advertising) (' + connection.ip + ')\n');
			connection.sendTo(room, '|raw|You have been locked for attempting to advertise.');
			Gold.pmUpperStaff(user.name + " has been locked for attempting to advertise" + (room ? ". **Room:**" + room.id : " in a private message.") +
				" **Message:** " + message, "~Server");
			return false;
		}

		Gold.pmUpperStaff(user.name + " has attempted to advertise" + (room ? ". **Room:** " + room.id : " in a private message.") +
			" **Message:** " + message);
		connection.sendTo(room, '|raw|Advertising detected, your message has not been sent and upper staff has been notified.' +
			'
Further attempts to advertise will result in being locked');
		connection.user.popup("Advertising detected, your message has not been sent and upper staff has been notified.\n" +
			"Further attempts to advertise will result in being locked");
		return false;
	}
	return message;
};
<commit_msg>Fix chat filter from detecting when people use http, https or www before server<commit_after>'use strict';

const fs = require('fs');

let adWhitelist = (Config.adWhitelist ? Config.adWhitelist : []);
let bannedMessages = (Config.bannedMessages ? Config.bannedMessages : []);

let adRegex = new RegExp("\\b(?!(" + adWhitelist.join('|') + ").*)(\\w+(?:-\\w+)*)(?=.*psim.*us)", "g");
let adRegex2 = new RegExp("(play.pokemonshowdown.com\\/~~)(?!(" + adWhitelist.join('|') + "))", "g");

Config.chatfilter = function (message, user, room, connection) {
	user.lastActive = Date.now();

	for (let x in bannedMessages) {
		if (message.toLowerCase().indexOf(bannedMessages[x]) > -1 && bannedMessages[x] !== '' && message.substr(0, 1) !== '/') {
			if (user.locked) return false;
			Punishments.lock(user, Date.now() + 7 * 24 * 60 * 60 * 1000, "Said a banned word: " + bannedMessages[x]);
			user.popup('You have been automatically locked for sending a message containing a banned word.');
			Rooms('staff').add('[PornMonitor] ' + (room ? '(' + room + ') ' : '') + Tools.escapeHTML(user.name) +
			' was automatically locked for trying to say "' + message + '"').update();
			fs.appendFile('logs/modlog/modlog_staff.txt', '[' + (new Date().toJSON()) + '] (staff) ' + user.name + ' was locked from talking by the Server (' +
			bannedMessages[x] + ') (' + connection.ip + ')\n');
			Gold.pmUpperStaff(user.name + ' has been automatically locked for sending a message containing a banned word **Room:** ' + room.id +
			' **Message:** ' + message, '~Server');
			return false;
		}
	}

	let advMessage = message.replace(/^http:\/\//i, '');
	advMessage = message.replace(/^https:\/\//i, '');
	advMessage = message.replace(/^www./i, '');

	if (!user.can('hotpatch') && (advMessage.replace(/gold/gi, '').match(adRegex) || advMessage.match(adRegex2))) {
		if (user.locked) return false;
		if (!user.advWarns) user.advWarns = 0;
		user.advWarns++;
		if (user.advWarns > 1) {
			Punishments.lock(user, Date.now() + 7 * 24 * 60 * 60 * 1000, "Advertising");
			fs.appendFile('logs/modlog/modlog_staff.txt', '[' + (new Date().toJSON()) + '] (staff) ' + user.name +
				' was locked from talking by the Server. (Advertising) (' + connection.ip + ')\n');
			connection.sendTo(room, '|raw|You have been locked for attempting to advertise.');
			Gold.pmUpperStaff(user.name + " has been locked for attempting to advertise" + (room ? ". **Room:**" + room.id : " in a private message.") +
				" **Message:** " + message, "~Server");
			return false;
		}

		Gold.pmUpperStaff(user.name + " has attempted to advertise" + (room ? ". **Room:** " + room.id : " in a private message.") +
			" **Message:** " + message);
		connection.sendTo(room, '|raw|Advertising detected, your message has not been sent and upper staff has been notified.' +
			'
Further attempts to advertise will result in being locked');
		connection.user.popup("Advertising detected, your message has not been sent and upper staff has been notified.\n" +
			"Further attempts to advertise will result in being locked");
		return false;
	}
	return message;
};
<|endoftext|>


<commit_before>import React from "react";
import Draggable from "react-draggable";
import ReactList from "react-list";
import Axis from "../RowItem/Axis";
import getXStartAndWidthFromNonCircularRange from "../RowItem/getXStartAndWidthFromNonCircularRange";
import { view } from "react-easy-state";

export default class Minimap extends React.Component {
  shouldComponentUpdate(newProps) {
    const { props } = this;
    if (
      ["numBpsShownInLinearView", "scrollAlignmentView"].some(
        key => props[key] !== newProps[key]
      )
    )
      return true;
    return false;
  }
  handleMinimapClick = e => {
    if (
      this.isDragging ||
      (e.target && e.target.classList.contains("minimapCaret"))
    ) {
      e.stopPropagation();
      return;
    }
    const {
      onMinimapScroll,
      laneHeight,
      handleScrollToTrack,
      dimensions: { width = 200 }
    } = this.props;
    const scrollHandleWidth = this.getScrollHandleWidth();
    const percent =
      (this.getXPositionOfClickInMinimap(e) - scrollHandleWidth / 2) /
      (width - scrollHandleWidth);
    onMinimapScroll(percent);

    //scroll vertically
    const y = this.getYPositionOfClickInMinimap(e);
    const trackIndex = Math.floor(y / laneHeight);
    handleScrollToTrack(trackIndex);
  };

  getCharWidth = () => {
    const {
      alignmentTracks = [],
      dimensions: { width = 200 }
    } = this.props;
    const [template] = alignmentTracks;
    const seqLength = template.alignmentData.sequence.length;
    const charWidth = Math.min(16, width / seqLength);
    return charWidth || 12;
  };
  getScrollHandleWidth = () => {
    const { numBpsShownInLinearView, dimensions } = this.props;
    const charWidth = this.getCharWidth();
    const { width } = getXStartAndWidthFromNonCircularRange(
      { start: 0, end: Math.max(numBpsShownInLinearView - 1, 0) },
      charWidth
    );
    return Math.min(width, dimensions.width);
  };
  getXPositionOfClickInMinimap = e => {
    const leftStart = this.minimap.getBoundingClientRect().left;
    return Math.max(e.clientX - leftStart, 0);
  };
  getYPositionOfClickInMinimap = e => {
    const topStart = this.minimap.getBoundingClientRect().top;
    return Math.max(e.clientY + this.minimapTracks.scrollTop - topStart, 0);
  };
  handleDragStop = () => {
    setTimeout(() => {
      this.isDragging = false;
    }, 150);
  };
  handleDrag = e => {
    const {
      onMinimapScroll,
      dimensions: { width = 200 }
    } = this.props;
    this.isDragging = true; //needed to block erroneous click events from being triggered!
    const percent = this.getXPositionOfClickInMinimap(e) / width;
    onMinimapScroll(percent);
  };
  itemSizeGetter = () => {
    return this.props.laneHeight;
  };
  renderItem = i => {
    const {
      alignmentTracks = [],
      dimensions: { width = 200 },
      laneHeight,
      laneSpacing = 1
    } = this.props;
    const charWidth = this.getCharWidth();

    const { matchHighlightRanges } = alignmentTracks[i];
    //need to get the chunks that can be rendered
    let redPath = ""; //draw these as just 1 path instead of a bunch of rectangles to improve browser performance
    let greyPath = "";
    matchHighlightRanges.forEach(range => {
      const { xStart, width } = getXStartAndWidthFromNonCircularRange(
        range,
        charWidth
      );
      const height = laneHeight - laneSpacing;
      const y = 0;
      const toAdd = ` M${xStart},${y} L${xStart + width},${y} L${xStart +
        width},${y + height} L${xStart},${y + height} `;
      if (range.isMatch) {
        greyPath += toAdd;
      } else {
        redPath += toAdd;
      }
    });
    return (
      <div
        key={i + "-lane"}
        style={{ height: laneHeight, maxHeight: laneHeight }}
      >
        <svg style={{ display: "block" }} height={laneHeight} width={width}>
          <path d={redPath} fill={"red"} />
          <path d={greyPath} fill={"grey"} />
        </svg>
      </div>
    );
  };

  render() {
    const {
      alignmentTracks = [],
      dimensions: { width = 200 },
      laneHeight,
      onSizeAdjust,
      minSliderSize,
      onMinimapScroll,
      easyStore
    } = this.props;

    const [template /* ...nonTemplates */] = alignmentTracks;
    const seqLength = template.alignmentData.sequence.length;
    const charWidth = this.getCharWidth();
    const scrollHandleWidth = this.getScrollHandleWidth();

    return (
      <div
        ref={ref => (this.minimap = ref)}
        className={"alignmentMinimap"}
        style={{
          position: "relative",
          width,
          overflowX: "visible",
          overflowY: "hidden"
        }}
        onClick={this.handleMinimapClick}
      >
        <div
          ref={ref => {
            if (ref) {
              this.minimapTracks = ref;
            }
          }}
          style={{
            maxHeight: 250,
            overflowY: "auto",
            position: "relative"
          }}
          className={"alignmentMinimapTracks"}
        >
          <YellowScrollHandle
            width={width}
            handleDrag={this.handleDrag}
            handleDragStop={this.handleDragStop}
            onMinimapScroll={onMinimapScroll}
            minSliderSize={minSliderSize}
            onSizeAdjust={onSizeAdjust}
            easyStore={easyStore} //we use react-easy-state here to prevent costly setStates from being called
            scrollHandleWidth={scrollHandleWidth}
            alignmentTracks={alignmentTracks}
            laneHeight={laneHeight}
            minimapTracksPartialHeight={laneHeight * alignmentTracks.length}
          />
          <ReactList
            type={"uniform"}
            itemSizeGetter={this.itemSizeGetter}
            itemRenderer={this.renderItem}
            length={alignmentTracks.length}
          />
        </div>

        <Axis
          {...{
            row: { start: 0, end: seqLength },
            tickSpacing: Math.floor(seqLength / 10),
            bpsPerRow: seqLength,
            charWidth,
            annotationHeight: 15,
            sequenceLength: seqLength
          }}
        />
      </div>
    );
  }
}
const YellowScrollHandle = view(
  class YellowScrollHandleInner extends React.Component {
    render() {
      const {
        scrollHandleWidth,
        width,
        easyStore,
        handleDrag,
        handleDragStop,
        minSliderSize,
        laneHeight,
        onSizeAdjust,
        minimapTracksPartialHeight
      } = this.props;
      const { verticalVisibleRange, percentScrolled } = easyStore;

      const xScroll = percentScrolled * (width - scrollHandleWidth);

      return (
        <Draggable
          bounds={"parent"}
          zIndex={105}
          handle=".handle"
          position={{ x: xScroll, y: 0 }}
          axis={"x"}
          // onStart={this.onStart}
          onStop={handleDragStop}
          onDrag={handleDrag}
        >
          <div
            style={{
              height: minimapTracksPartialHeight || 0,
              // height: "100%",
              border: "none",
              top: "0px",
              position: "absolute",
              zIndex: "10"
            }}
          >
            {/* left hand side drag handle */}
            <Draggable
              bounds={{
                left: -xScroll,
                right: scrollHandleWidth - minSliderSize
              }}
              zIndex={105}
              position={{ x: 0, y: 0 }}
              axis={"x"}
              onStart={(e, { x }) => {
                this.x = x;
              }}
              onStop={(e, { x }) => {
                const deltaX = x - this.x;

                const newSliderSize = scrollHandleWidth - deltaX;
                //user is resizing to the left so we need to update the scroll percentage so the slider does not jump
                const newScrollPercent = Math.min(
                  1,
                  (xScroll + deltaX) / (width - newSliderSize)
                );
                onSizeAdjust(newSliderSize, newScrollPercent);
              }}
            >
              {/* caret component */}
              <div
                style={{
                  height: minimapTracksPartialHeight || 0,
                  // height: "100%",
                  border: "none",
                  cursor: "ew-resize",
                  opacity: "1",
                  top: "0px",
                  position: "absolute",
                  zIndex: "10",
                  width: 2,
                  background: "black"
                }}
                className={"minimapCaret"}
              />
            </Draggable>
            {/* the actual handle component */}
            <div
              className={"syncscroll handle"}
              dataname="scrollGroup"
              style={{
                height: minimapTracksPartialHeight || 0,
                border: "none",
                cursor: "move",
                opacity: ".3",
                zIndex: "10",
                width: scrollHandleWidth,
                background: "yellow"
              }}
            >
              {/* this is the blue vertical scroll position display element */}
              <div
                className={"verticalScrollDisplay"}
                style={{
                  height:
                    (verticalVisibleRange.end -
                      verticalVisibleRange.start +
                      1) *
                    laneHeight,

                  zIndex: "-10",
                  background: "blue",
                  position: "relative",
                  top: verticalVisibleRange.start * laneHeight
                }}
              />
            </div>
            {/* right hand side drag handle */}
            <Draggable
              bounds={{
                right: minSliderSize + width - xScroll,
                left: minSliderSize
              }}
              zIndex={105}
              position={{ x: scrollHandleWidth, y: 0 }}
              axis={"x"}
              onStart={(e, { x }) => {
                this.x = x;
              }}
              onStop={(e, { x }) => {
                const deltaX = this.x - x;
                const newSliderSize = scrollHandleWidth - deltaX;
                onSizeAdjust(newSliderSize);

                //user is resizing to the right so we need to update the scroll percentage so the slider does not jump
                const newScrollPercent = xScroll / (width - newSliderSize);
                onSizeAdjust(newSliderSize, newScrollPercent);
              }}
            >
              <div
                style={{
                  height: minimapTracksPartialHeight || 0,
                  // height: "100%",
                  border: "none",
                  cursor: "ew-resize",
                  opacity: "1",
                  top: "0px",
                  // right: 0,
                  position: "absolute",
                  zIndex: "10",
                  width: 2,
                  background: "black"
                }}
                className={"minimapCaret"}
              />
            </Draggable>
          </div>
        </Draggable>
      );
    }
  }
);
<commit_msg>fixing minimap svg rendering<commit_after>import React from "react";
import Draggable from "react-draggable";
import ReactList from "react-list";
import Axis from "../RowItem/Axis";
import getXStartAndWidthFromNonCircularRange from "../RowItem/getXStartAndWidthFromNonCircularRange";
import { view } from "react-easy-state";

export default class Minimap extends React.Component {
  shouldComponentUpdate(newProps) {
    const { props } = this;
    if (
      ["numBpsShownInLinearView", "scrollAlignmentView"].some(
        key => props[key] !== newProps[key]
      )
    )
      return true;
    return false;
  }
  handleMinimapClick = e => {
    if (
      this.isDragging ||
      (e.target && e.target.classList.contains("minimapCaret"))
    ) {
      e.stopPropagation();
      return;
    }
    const {
      onMinimapScroll,
      laneHeight,
      handleScrollToTrack,
      dimensions: { width = 200 }
    } = this.props;
    const scrollHandleWidth = this.getScrollHandleWidth();
    const percent =
      (this.getXPositionOfClickInMinimap(e) - scrollHandleWidth / 2) /
      (width - scrollHandleWidth);
    onMinimapScroll(percent);

    //scroll vertically
    const y = this.getYPositionOfClickInMinimap(e);
    const trackIndex = Math.floor(y / laneHeight);
    handleScrollToTrack(trackIndex);
  };

  getCharWidth = () => {
    const {
      alignmentTracks = [],
      dimensions: { width = 200 }
    } = this.props;
    const [template] = alignmentTracks;
    const seqLength = template.alignmentData.sequence.length;
    const charWidth = Math.min(16, width / seqLength);
    return charWidth || 12;
  };
  getScrollHandleWidth = () => {
    const { numBpsShownInLinearView, dimensions } = this.props;
    const charWidth = this.getCharWidth();
    const { width } = getXStartAndWidthFromNonCircularRange(
      { start: 0, end: Math.max(numBpsShownInLinearView - 1, 0) },
      charWidth
    );
    return Math.min(width, dimensions.width);
  };
  getXPositionOfClickInMinimap = e => {
    const leftStart = this.minimap.getBoundingClientRect().left;
    return Math.max(e.clientX - leftStart, 0);
  };
  getYPositionOfClickInMinimap = e => {
    const topStart = this.minimap.getBoundingClientRect().top;
    return Math.max(e.clientY + this.minimapTracks.scrollTop - topStart, 0);
  };
  handleDragStop = () => {
    setTimeout(() => {
      this.isDragging = false;
    }, 150);
  };
  handleDrag = e => {
    const {
      onMinimapScroll,
      dimensions: { width = 200 }
    } = this.props;
    this.isDragging = true; //needed to block erroneous click events from being triggered!
    const percent = this.getXPositionOfClickInMinimap(e) / width;
    onMinimapScroll(percent);
  };
  itemSizeGetter = () => {
    return this.props.laneHeight;
  };
  renderItem = i => {
    const {
      alignmentTracks = [],
      dimensions: { width = 200 },
      laneHeight,
      laneSpacing = 1
    } = this.props;
    const charWidth = this.getCharWidth();

    const { matchHighlightRanges } = alignmentTracks[i];
    //need to get the chunks that can be rendered
    let redPath = ""; //draw these as just 1 path instead of a bunch of rectangles to improve browser performance
    let greyPath = "";
    // draw one grey rectangle then draw red/mismatching regions on top of it
    const height = laneHeight - laneSpacing;
    const y = 0;
    const firstRange = getXStartAndWidthFromNonCircularRange(
      matchHighlightRanges[0],
      charWidth
    );
    const lastRange = getXStartAndWidthFromNonCircularRange(
      matchHighlightRanges[matchHighlightRanges.length - 1],
      charWidth
    );
    greyPath += `M${firstRange.xStart},${y} L${lastRange.xStart +
      lastRange.width},${y} L${lastRange.xStart + lastRange.width},${y +
      height} L${firstRange.xStart},${y + height}`;
    matchHighlightRanges.forEach(range => {
      const { xStart, width } = getXStartAndWidthFromNonCircularRange(
        range,
        charWidth
      );
      const toAdd = `M${xStart},${y} L${xStart + width},${y} L${xStart +
        width},${y + height} L${xStart},${y + height}`;
      if (!range.isMatch) {
        redPath += toAdd;
      }
    });
    return (
      <div
        key={i + "-lane"}
        style={{ height: laneHeight, maxHeight: laneHeight }}
      >
        <svg
          height={laneHeight}
          width={width}
          shapeRendering={"geometricPrecision"}
        >
          <path d={greyPath} fill={"grey"} />
          <path d={redPath} fill={"red"} />
        </svg>
      </div>
    );
  };

  render() {
    const {
      alignmentTracks = [],
      dimensions: { width = 200 },
      laneHeight,
      onSizeAdjust,
      minSliderSize,
      onMinimapScroll,
      easyStore
    } = this.props;

    const [template /* ...nonTemplates */] = alignmentTracks;
    const seqLength = template.alignmentData.sequence.length;
    const charWidth = this.getCharWidth();
    const scrollHandleWidth = this.getScrollHandleWidth();

    return (
      <div
        ref={ref => (this.minimap = ref)}
        className={"alignmentMinimap"}
        style={{
          position: "relative",
          width,
          overflowX: "visible",
          overflowY: "hidden"
        }}
        onClick={this.handleMinimapClick}
      >
        <div
          ref={ref => {
            if (ref) {
              this.minimapTracks = ref;
            }
          }}
          style={{
            maxHeight: 250,
            overflowY: "auto",
            position: "relative"
          }}
          className={"alignmentMinimapTracks"}
        >
          <YellowScrollHandle
            width={width}
            handleDrag={this.handleDrag}
            handleDragStop={this.handleDragStop}
            onMinimapScroll={onMinimapScroll}
            minSliderSize={minSliderSize}
            onSizeAdjust={onSizeAdjust}
            easyStore={easyStore} //we use react-easy-state here to prevent costly setStates from being called
            scrollHandleWidth={scrollHandleWidth}
            alignmentTracks={alignmentTracks}
            laneHeight={laneHeight}
            minimapTracksPartialHeight={laneHeight * alignmentTracks.length}
          />
          <ReactList
            type={"uniform"}
            itemSizeGetter={this.itemSizeGetter}
            itemRenderer={this.renderItem}
            length={alignmentTracks.length}
          />
        </div>

        <Axis
          {...{
            row: { start: 0, end: seqLength },
            tickSpacing: Math.floor(seqLength / 10),
            bpsPerRow: seqLength,
            charWidth,
            annotationHeight: 15,
            sequenceLength: seqLength
          }}
        />
      </div>
    );
  }
}
const YellowScrollHandle = view(
  class YellowScrollHandleInner extends React.Component {
    render() {
      const {
        scrollHandleWidth,
        width,
        easyStore,
        handleDrag,
        handleDragStop,
        minSliderSize,
        laneHeight,
        onSizeAdjust,
        minimapTracksPartialHeight
      } = this.props;
      const { verticalVisibleRange, percentScrolled } = easyStore;

      const xScroll = percentScrolled * (width - scrollHandleWidth);

      return (
        <Draggable
          bounds={"parent"}
          zIndex={105}
          handle=".handle"
          position={{ x: xScroll, y: 0 }}
          axis={"x"}
          // onStart={this.onStart}
          onStop={handleDragStop}
          onDrag={handleDrag}
        >
          <div
            style={{
              height: minimapTracksPartialHeight || 0,
              // height: "100%",
              border: "none",
              top: "0px",
              position: "absolute",
              zIndex: "10"
            }}
          >
            {/* left hand side drag handle */}
            <Draggable
              bounds={{
                left: -xScroll,
                right: scrollHandleWidth - minSliderSize
              }}
              zIndex={105}
              position={{ x: 0, y: 0 }}
              axis={"x"}
              onStart={(e, { x }) => {
                this.x = x;
              }}
              onStop={(e, { x }) => {
                const deltaX = x - this.x;

                const newSliderSize = scrollHandleWidth - deltaX;
                //user is resizing to the left so we need to update the scroll percentage so the slider does not jump
                const newScrollPercent = Math.min(
                  1,
                  (xScroll + deltaX) / (width - newSliderSize)
                );
                onSizeAdjust(newSliderSize, newScrollPercent);
              }}
            >
              {/* caret component */}
              <div
                style={{
                  height: minimapTracksPartialHeight || 0,
                  // height: "100%",
                  border: "none",
                  cursor: "ew-resize",
                  opacity: "1",
                  top: "0px",
                  position: "absolute",
                  zIndex: "10",
                  width: 2,
                  background: "black"
                }}
                className={"minimapCaret"}
              />
            </Draggable>
            {/* the actual handle component */}
            <div
              className={"syncscroll handle"}
              dataname="scrollGroup"
              style={{
                height: minimapTracksPartialHeight || 0,
                border: "none",
                cursor: "move",
                opacity: ".3",
                zIndex: "10",
                width: scrollHandleWidth,
                background: "yellow"
              }}
            >
              {/* this is the blue vertical scroll position display element */}
              <div
                className={"verticalScrollDisplay"}
                style={{
                  height:
                    (verticalVisibleRange.end -
                      verticalVisibleRange.start +
                      1) *
                    laneHeight,

                  zIndex: "-10",
                  background: "blue",
                  position: "relative",
                  top: verticalVisibleRange.start * laneHeight
                }}
              />
            </div>
            {/* right hand side drag handle */}
            <Draggable
              bounds={{
                right: minSliderSize + width - xScroll,
                left: minSliderSize
              }}
              zIndex={105}
              position={{ x: scrollHandleWidth, y: 0 }}
              axis={"x"}
              onStart={(e, { x }) => {
                this.x = x;
              }}
              onStop={(e, { x }) => {
                const deltaX = this.x - x;
                const newSliderSize = scrollHandleWidth - deltaX;
                onSizeAdjust(newSliderSize);

                //user is resizing to the right so we need to update the scroll percentage so the slider does not jump
                const newScrollPercent = xScroll / (width - newSliderSize);
                onSizeAdjust(newSliderSize, newScrollPercent);
              }}
            >
              <div
                style={{
                  height: minimapTracksPartialHeight || 0,
                  // height: "100%",
                  border: "none",
                  cursor: "ew-resize",
                  opacity: "1",
                  top: "0px",
                  // right: 0,
                  position: "absolute",
                  zIndex: "10",
                  width: 2,
                  background: "black"
                }}
                className={"minimapCaret"}
              />
            </Draggable>
          </div>
        </Draggable>
      );
    }
  }
);
<|endoftext|>


<commit_before>/**
 *  You can use inline styles or classNames inside your callbacks
 */

import React, {Component} from 'react'
import redraft from 'redraft'

var Prism = require('prismjs');
//Prism.highlightAll();

const handlePrismRenderer = (syntax, children)=>{
  const code = children.flat().flat().map((o)=> o.props ? o.props.children.join(" ") : o ).join("\r")
  const formattedCode =  Prism.highlight(code, Prism.languages.javascript, 'javascript');
  return {__html: formattedCode }
}

const styles = {
  code: {
    backgroundColor: 'rgba(0, 0, 0, 0.05)',
    fontFamily: '"Inconsolata", "Menlo", "Consolas", monospace',
    fontSize: 16,
    padding: 2,
  },
  codeBlock: {
    backgroundColor: 'rgba(0, 0, 0, 0.05)',
    fontFamily: '"Inconsolata", "Menlo", "Consolas", monospace',
    fontSize: 16,
    padding: 20,
  },
};

// just a helper to add a
 after a block
const addBreaklines = (children) => children.map(child => [child,
]);

/**
 * Define the renderers
 */
const renderers = {
  /**
   * Those callbacks will be called recursively to render a nested structure
   */
  inline: {
    // The key passed here is just an index based on rendering order inside a block
    BOLD: (children, { key }) => {children},
    ITALIC: (children, { key }) => {children},
    UNDERLINE: (children, { key }) => {children},
    //CODE: (children, { key }) => ,
  },
  /**
   * Blocks receive children and depth
   * Note that children are an array of blocks with same styling,
   */
  blocks: {

    unstyled: (children, { keys }) => {
      return children.map(
        (o, i)=> (
{o}
)
      )
    },
    blockquote: (children, { keys }) =>

                                {addBreaklines(children)}

,
    'header-one': (children, { keys }) =>
{children}
,
    'header-two': (children, { keys }) =>
{children}
,
    // You can also access the original keys of the blocks
    'code-block': (children, { keys, data }) => {
      return

                  {/*addBreaklines(children)*/}

},
    // or depth for nested lists
    'unordered-list-item': (children, { depth, keys }) => <ul key={keys[keys.length - 1]} className={`ul-level-${depth}`}>
                                                            {children.map(child =>

                                                              {child}

)}

,
    'ordered-list-item': (children, { depth, keys }) => <ol key={keys.join('|')} className={`ol-level-${depth}`}>{
      children.map((child, index) =>

        {child}

)
    }
,

    'image': (children, {keys, data}) => {
      const data2 = data[0]
      const {url, aspect_ratio, caption} = data2

      if(!aspect_ratio){
        var height = "100%"
        var width  = "100%"
        var ratio  = "100%"
      }else{
        var { height, width, ratio} = aspect_ratio
      }

      return

                    <div className="aspectRatioPlaceholder is-locked"
                      //style={{maxWidth: '1000px', maxHeight: `${height}px`}}
                      >
                      <div className="aspect-ratio-fill"
                          style={{paddingBottom: `${ratio}%`}}>

                  {
                    caption &&
                    caption != "type a caption (optional)"
                    &&

                        {children}

                  }

    },
    embed: (children, {keys, data})=>{

      const {provisory_text, type, embed_data } = data[0]
      const {images, title, media, provider_url, description, url } = embed_data

      return

                {
                  images[0].url ?
                    <a target="_blank" className="js-mixtapeImage mixtapeImage"
                      href={provisory_text}
                      style={{ backgroundImage: `url(${images[0].url})` }}>
                     : null
                }

                    {title}

                    {description}

                {provider_url}

    },
    video: (children, {keys, data})=>{

      const {provisory_text, type, embed_data } = data[0]
      const {html} = embed_data

      return

                <div className="iframeContainer" dangerouslySetInnerHTML={
                          { __html: `${html}` }
                        }/>

                {
                  provisory_text &&
                  provisory_text === "type a caption (optional)"
                  &&

                      {provisory_text}

                }

    },
    'recorded-video': (children, {keys, data})=>{
      const {url, text} = data[0]

      return

                <video
                  autoplay={false}
                  style={{width:"100%" }}
                  controls={true}
                  src={url}>
                </video>

                  {text}

    },
    // If your blocks use meta data it can also be accessed like keys
    //atomic: (children, { keys, data }) => children.map((child, i) => <Atomic key={keys[i]} {...data[i]} />),
  },
  /**
   * Entities receive children and the entity data
   */
  entities: {
    // key is the entity key value from raw
    LINK: (children, data, { key }) =>

      {children}
    ,
  },
  /**
   * Array of decorators,
   * Entities receive children and the entity data,
   * inspired by https://facebook.github.io/draft-js/docs/advanced-topics-decorators.html
   * it's also possible to pass a custom Decorator class that matches the [DraftDecoratorType](https://github.com/facebook/draft-js/blob/master/src/model/decorators/DraftDecoratorType.js)
   */
  /*decorators: [
    {
      // by default linkStrategy receives a ContentBlock stub (more info under Creating the ContentBlock)
      // strategy only receives first two arguments, contentState is yet not provided
      strategy: linkStrategy,
      // component - a callback as with other renderers
      // decoratedText a plain string matched by the strategy
      // if your decorator depends on draft-js contentState you need to provide convertFromRaw in redraft options
      component: ({ children, decoratedText }) => {children},
    },
    new CustomDecorator(someOptions),
  ],*/
}

export default class Renderer extends Component {

  /*static propTypes = {
    raw: PropTypes.object
  }*/

  renderWarning() {
    if(this.props.html){
      return

    }else{
      return
---
;
    }
  }

  render() {
    const { raw } = this.props;
    if (!raw) {
      return this.renderWarning();
    }
    const rendered = redraft(raw, renderers);
    // redraft returns a null if there's nothing to render
    if (!rendered) {
      return this.renderWarning();
    }
    return (

        {rendered}

    );
  }
}<commit_msg>Update draftRenderer.js<commit_after>/**
 *  You can use inline styles or classNames inside your callbacks
 */

import React, {Component} from 'react'
import redraft from 'redraft'

var Prism = require('prismjs');
//Prism.highlightAll();

const handlePrismRenderer = (syntax, children)=>{
  const code = children.flat().flat().map((o)=> o.props ? o.props.children.join(" ") : o ).join("\r")
  const formattedCode =  Prism.highlight(code, Prism.languages.javascript, 'javascript');
  return {__html: formattedCode }
}

const styles = {
  code: {
    backgroundColor: 'rgba(0, 0, 0, 0.05)',
    fontFamily: '"Inconsolata", "Menlo", "Consolas", monospace',
    fontSize: 16,
    padding: 2,
  },
  codeBlock: {
    backgroundColor: 'rgba(0, 0, 0, 0.05)',
    fontFamily: '"Inconsolata", "Menlo", "Consolas", monospace',
    fontSize: 16,
    padding: 20,
  },
};

// just a helper to add a
 after a block
const addBreaklines = (children) => children.map(child => [child,
]);

/**
 * Define the renderers
 */
const renderers = {
  /**
   * Those callbacks will be called recursively to render a nested structure
   */
  inline: {
    // The key passed here is just an index based on rendering order inside a block
    BOLD: (children, { key }) => {children},
    ITALIC: (children, { key }) => {children},
    UNDERLINE: (children, { key }) => {children},
    //CODE: (children, { key }) => ,
  },
  /**
   * Blocks receive children and depth
   * Note that children are an array of blocks with same styling,
   */
  blocks: {

    unstyled: (children, { keys }) => {
      return children.map(
        (o, i)=> (
{o}
)
      )
    },
    blockquote: (children, { keys }) =>

                                {addBreaklines(children)}

,
    'header-one': (children, { keys }) =>
{children}
,
    'header-two': (children, { keys }) =>
{children}
,
    'header-three': (children, { keys }) =>
{children}
,
    // You can also access the original keys of the blocks
    'code-block': (children, { keys, data }) => {
      return

                  {/*addBreaklines(children)*/}

},
    // or depth for nested lists
    'unordered-list-item': (children, { depth, keys }) => <ul key={keys[keys.length - 1]} className={`ul-level-${depth}`}>
                                                            {children.map(child =>

                                                              {child}

)}

,
    'ordered-list-item': (children, { depth, keys }) => <ol key={keys.join('|')} className={`ol-level-${depth}`}>{
      children.map((child, index) =>

        {child}

)
    }
,

    'image': (children, {keys, data}) => {
      const data2 = data[0]
      const {url, aspect_ratio, caption} = data2

      if(!aspect_ratio){
        var height = "100%"
        var width  = "100%"
        var ratio  = "100%"
      }else{
        var { height, width, ratio} = aspect_ratio
      }

      return

                    <div className="aspectRatioPlaceholder is-locked"
                      //style={{maxWidth: '1000px', maxHeight: `${height}px`}}
                      >
                      <div className="aspect-ratio-fill"
                          style={{paddingBottom: `${ratio}%`}}>

                  {
                    caption &&
                    caption != "type a caption (optional)"
                    &&

                        {children}

                  }

    },
    embed: (children, {keys, data})=>{

      const {provisory_text, type, embed_data } = data[0]
      const {images, title, media, provider_url, description, url } = embed_data

      return

                {
                  images[0].url ?
                    <a target="_blank" className="js-mixtapeImage mixtapeImage"
                      href={provisory_text}
                      style={{ backgroundImage: `url(${images[0].url})` }}>
                     : null
                }

                    {title}

                    {description}

                {provider_url}

    },
    video: (children, {keys, data})=>{

      const {provisory_text, type, embed_data } = data[0]
      const {html} = embed_data

      return

                <div className="iframeContainer" dangerouslySetInnerHTML={
                          { __html: `${html}` }
                        }/>

                {
                  provisory_text &&
                  provisory_text === "type a caption (optional)"
                  &&

                      {provisory_text}

                }

    },
    'recorded-video': (children, {keys, data})=>{
      const {url, text} = data[0]

      return

                <video
                  autoplay={false}
                  style={{width:"100%" }}
                  controls={true}
                  src={url}>
                </video>

                  {text}

    },
    // If your blocks use meta data it can also be accessed like keys
    //atomic: (children, { keys, data }) => children.map((child, i) => <Atomic key={keys[i]} {...data[i]} />),
  },
  /**
   * Entities receive children and the entity data
   */
  entities: {
    // key is the entity key value from raw
    LINK: (children, data, { key }) =>

      {children}
    ,
  },
  /**
   * Array of decorators,
   * Entities receive children and the entity data,
   * inspired by https://facebook.github.io/draft-js/docs/advanced-topics-decorators.html
   * it's also possible to pass a custom Decorator class that matches the [DraftDecoratorType](https://github.com/facebook/draft-js/blob/master/src/model/decorators/DraftDecoratorType.js)
   */
  /*decorators: [
    {
      // by default linkStrategy receives a ContentBlock stub (more info under Creating the ContentBlock)
      // strategy only receives first two arguments, contentState is yet not provided
      strategy: linkStrategy,
      // component - a callback as with other renderers
      // decoratedText a plain string matched by the strategy
      // if your decorator depends on draft-js contentState you need to provide convertFromRaw in redraft options
      component: ({ children, decoratedText }) => {children},
    },
    new CustomDecorator(someOptions),
  ],*/
}

export default class Renderer extends Component {

  /*static propTypes = {
    raw: PropTypes.object
  }*/

  renderWarning() {
    if(this.props.html){
      return

    }else{
      return
---
;
    }
  }

  render() {
    const { raw } = this.props;
    if (!raw) {
      return this.renderWarning();
    }
    const rendered = redraft(raw, renderers);
    // redraft returns a null if there's nothing to render
    if (!rendered) {
      return this.renderWarning();
    }
    return (

        {rendered}

    );
  }
}<|endoftext|>