<commit_before>// Conditional load for NodeJS
if (typeof require !== 'undefined') {
  var angular = require('angular'),
      showdown = require('showdown');
}

//Check if AngularJs and Showdown is defined and only load ng-Showdown if both are present
if (typeof angular !== 'undefined' && typeof showdown !== 'undefined') {

  (function (module, showdown) {
    'use strict';

    module
      .provider('$showdown', provider)
      .directive('sdModelToHtml', ['$showdown', '$sanitize', markdownToHtmlDirective])
      .filter('sdStripHtml', stripHtmlFilter);

    /**
     * Angular Provider
     * Enables configuration of showdown via angular.config and Dependency Injection into controllers, views
     * directives, etc... This assures the directives and filters provided by the library itself stay consistent
     * with the user configurations.
     * If the user wants to use a different configuration in a determined context, he can use the "classic" Showdown
     * object instead.
     */
    function provider() {

      // Configuration parameters for Showdown
      var config = {
        extensions: [],
        stripHtml:  true
      };

      /**
       * Sets a configuration option
       *
       * @param {string} key Config parameter key
       * @param {string} value Config parameter value
       */
      /* jshint validthis: true */
      this.setOption = function (key, value) {
        config[key] = value;

        return this;
      };

      /**
       * Gets the value of the configuration parameter specified by key
       *
       * @param {string} key The config parameter key
       * @returns {string|null} Returns the value of the config parameter. (or null if the config parameter is not set)
       */
      this.getOption = function (key) {
        if (config.hasOwnProperty(key)) {
          return config.key;
        } else {
          return null;
        }
      };

      /**
       * Loads a Showdown Extension
       *
       * @param {string} extensionName The name of the extension to load
       */
      this.loadExtension = function (extensionName) {
        config.extensions.push(extensionName);

        return this;
      };

      function SDObject() {
        var converter = new showdown.Converter(config);

        /**
         * Converts a markdown text into HTML
         *
         * @param {string} markdown The markdown string to be converted to HTML
         * @returns {string} The converted HTML
         */
        this.makeHtml = function (markdown) {
          return converter.makeHtml(markdown);
        };

        /**
         * Strips a text of it's HTML tags
         *
         * @param {string} text
         * @returns {string}
         */
        this.stripHtml = function (text) {
          return String(text).replace(/<[^>]+>/gm, '');
        };
      }

      // The object returned by service provider
      this.$get = function () {
        return new SDObject();
      };
    }

    /**
     * AngularJS Directive to Md to HTML transformation
     *
     * Usage example:
     *

     *
     * @param {showdown.Converter} $showdown
     * @returns {*}
     */
    function markdownToHtmlDirective($showdown, $sanitize) {

      var link = function (scope, element) {
        scope.$watch('model', function (newValue) {
          var val;
          if (typeof newValue === 'string') {
            val = $sanitize($showdown.makeHtml(newValue));
          } else {
            val = typeof newValue;
          }
          element.html(val);
        });
      };

      return {
        restrict: 'A',
        link:     link,
        scope:    {
          model: '=sdModelToHtml'
        }
      };
    }

    /**
     * AngularJS Filter to Strip HTML tags from text
     *
     * @returns {Function}
     */
    function stripHtmlFilter() {
      return function (text) {
        return String(text).replace(/<[^>]+>/gm, '');
      };
    }

  })(angular.module('showdown', ['ngSanitize']), showdown);

} else {
  throw new Error('ng-showdown was not loaded because one of its dependencies (AngularJS or Showdown) was not met');
}
<commit_msg>docs(ng-showdown): add missing jsdoc param<commit_after>// Conditional load for NodeJS
if (typeof require !== 'undefined') {
  var angular = require('angular'),
      showdown = require('showdown');
}

//Check if AngularJs and Showdown is defined and only load ng-Showdown if both are present
if (typeof angular !== 'undefined' && typeof showdown !== 'undefined') {

  (function (module, showdown) {
    'use strict';

    module
      .provider('$showdown', provider)
      .directive('sdModelToHtml', ['$showdown', '$sanitize', markdownToHtmlDirective])
      .filter('sdStripHtml', stripHtmlFilter);

    /**
     * Angular Provider
     * Enables configuration of showdown via angular.config and Dependency Injection into controllers, views
     * directives, etc... This assures the directives and filters provided by the library itself stay consistent
     * with the user configurations.
     * If the user wants to use a different configuration in a determined context, he can use the "classic" Showdown
     * object instead.
     */
    function provider() {

      // Configuration parameters for Showdown
      var config = {
        extensions: [],
        stripHtml:  true
      };

      /**
       * Sets a configuration option
       *
       * @param {string} key Config parameter key
       * @param {string} value Config parameter value
       */
      /* jshint validthis: true */
      this.setOption = function (key, value) {
        config[key] = value;

        return this;
      };

      /**
       * Gets the value of the configuration parameter specified by key
       *
       * @param {string} key The config parameter key
       * @returns {string|null} Returns the value of the config parameter. (or null if the config parameter is not set)
       */
      this.getOption = function (key) {
        if (config.hasOwnProperty(key)) {
          return config.key;
        } else {
          return null;
        }
      };

      /**
       * Loads a Showdown Extension
       *
       * @param {string} extensionName The name of the extension to load
       */
      this.loadExtension = function (extensionName) {
        config.extensions.push(extensionName);

        return this;
      };

      function SDObject() {
        var converter = new showdown.Converter(config);

        /**
         * Converts a markdown text into HTML
         *
         * @param {string} markdown The markdown string to be converted to HTML
         * @returns {string} The converted HTML
         */
        this.makeHtml = function (markdown) {
          return converter.makeHtml(markdown);
        };

        /**
         * Strips a text of it's HTML tags
         *
         * @param {string} text
         * @returns {string}
         */
        this.stripHtml = function (text) {
          return String(text).replace(/<[^>]+>/gm, '');
        };
      }

      // The object returned by service provider
      this.$get = function () {
        return new SDObject();
      };
    }

    /**
     * AngularJS Directive to Md to HTML transformation
     *
     * Usage example:
     *

     *
     * @param {showdown.Converter} $showdown
     * @param $sanitize
     * @returns {*}
     */
    function markdownToHtmlDirective($showdown, $sanitize) {

      var link = function (scope, element) {
        scope.$watch('model', function (newValue) {
          var val;
          if (typeof newValue === 'string') {
            val = $sanitize($showdown.makeHtml(newValue));
          } else {
            val = typeof newValue;
          }
          element.html(val);
        });
      };

      return {
        restrict: 'A',
        link:     link,
        scope:    {
          model: '=sdModelToHtml'
        }
      };
    }

    /**
     * AngularJS Filter to Strip HTML tags from text
     *
     * @returns {Function}
     */
    function stripHtmlFilter() {
      return function (text) {
        return String(text).replace(/<[^>]+>/gm, '');
      };
    }

  })(angular.module('showdown', ['ngSanitize']), showdown);

} else {
  throw new Error('ng-showdown was not loaded because one of its dependencies (AngularJS or Showdown) was not met');
}
<|endoftext|>


<commit_before>/**
 * Created by Julian/Wolke on 07.11.2016.
 */
let Command = require('../../structures/command');
let winston = require('winston');
let request = require('request');
let key = remConfig.lbsearch_nsfw_key;
class Iblewd extends Command {
    constructor({t}) {
        super();
        this.cmd = 'iblewd';
        this.cat = 'nsfw';
        this.needGuild = false;
        this.t = t;
        this.accessLevel = 0;
    }

    run(msg) {
        let msgSplit = msg.content.split(' ');
        let msgSearch = '';
        let searchOrig = '';
        for (let i = 1; i < msgSplit.length; i++) {
            if (i === 1) {
                searchOrig = msgSplit[i];
            } else {
                searchOrig = searchOrig + ' ' + msgSplit[i];
            }
        }
        msgSearch = 'rating:e random: ' + searchOrig;
        request.get('https://ibsearch.xxx/api/v1/images.json', {
            qs: {
                limit: 100,
                q: msgSearch
            }, headers: {'X-lbSearch-Key': key}
        }, (error, response, body) => {
            if (error) {
                msg.channel.createMessage(this.t('generic.error', {lngs: msg.lang}));
            }
            if (!error && response.statusCode == 200) {
                try {
                    body = JSON.parse(body);
                } catch (e) {
                    winston.info(e.getMessage());
                }
                if (typeof (body) !== 'undefined' && body.length > 0) {
                    let random = Math.floor(Math.random() * body.length);
                    let img = body[random];
                    msg.channel.createMessage(`https://${img.server}.ibsearch.xxx/${img.path}`);
                } else {
                    msg.channel.createMessage(this.t('nsfw-images.nothing-found', {
                        lngs: msg.lang,
                        tags: searchOrig
                    }));
                }
            }
        });
    }
}
module.exports = Iblewd;<commit_msg>feat: remove iblewd command<commit_after><|endoftext|>


<commit_before>'use strict';

// Get proper requestAnimationFrame
var requestFrame = window.requestAnimationFrame,
    cancelFrame  = window.cancelAnimationFrame;

if (!requestFrame) {
    ['ms', 'moz', 'webkit', 'o'].every(function(prefix) {
        requestFrame = window[prefix + 'RequestAnimationFrame'];
        cancelFrame  = window[prefix + 'CancelAnimationFrame'] ||
                       window[prefix + 'CancelRequestAnimationFrame'];
        // Continue iterating only if requestFrame is still false
        return !requestFrame;
    });
}

// Module state
var isSupported    = !!requestFrame,
    isListening    = false,
    isQueued       = false,
    isIdle         = true,
    scrollY        = window.pageYOffset,
    scrollX        = window.pageXOffset,
    scrollYCached  = scrollY,
    scrollXCached  = scrollX,
    directionX     = ['x', 'horizontal'],
    directionAll   = ['any'],
    callbackQueue  = {
        x   : [],
        y   : [],
        any : []
    },
    detectIdleTimeout,
    tickId;

// Main scroll handler
// -------------------
function handleScroll() {
    var isScrollChanged = false;
    if (callbackQueue.x.length || callbackQueue.any.length) {
        scrollX = window.pageXOffset;
    }
    if (callbackQueue.y.length || callbackQueue.any.length) {
        scrollY = window.pageYOffset;
    }

	if (scrollY !== scrollYCached) {
        callbackQueue.y.forEach(triggerCallback.y);
        scrollYCached = scrollY;
        isScrollChanged = true;
    }
	if (scrollX !== scrollXCached) {
        callbackQueue.x.forEach(triggerCallback.x);
        scrollXCached = scrollX;
        isScrollChanged = true;
    }
    if (isScrollChanged) {
        callbackQueue.any.forEach(triggerCallback.any);
        window.clearTimeout(detectIdleTimeout);
        detectIdleTimeout = null;
    }

    isQueued = false;
    requestTick();
}

// Utilities
// ---------
function triggerCallback(callback, scroll) {
    callback(scroll);
}
triggerCallback.y = function(callback) {
    triggerCallback(callback, scrollY);
};
triggerCallback.x = function(callback) {
    triggerCallback(callback, scrollX);
};
triggerCallback.any = function(callback) {
    triggerCallback(callback, [scrollX, scrollY]);
};

function enableScrollListener() {
    if (isListening || isQueued) {
        return;
    }
    if (isIdle) {
        isListening = true;
        window.addEventListener('scroll', onScrollDebouncer);
        document.body.addEventListener('touchmove', onScrollDebouncer);
        return;
    }
    requestTick();
}

function disableScrollListener() {
    if (!isListening) {
        return;
    }
    window.removeEventListener('scroll', onScrollDebouncer);
    document.body.removeEventListener('touchmove', onScrollDebouncer);
    isListening = false;
}

function onScrollDebouncer() {
    isIdle = false;
	requestTick();
    disableScrollListener();
}

function requestTick() {
	if (isQueued) {
        return;
	}
    if (!detectIdleTimeout) {
        // Idle is defined as 1.5 seconds without scroll change
        detectIdleTimeout = window.setTimeout(detectIdle, 1500);
    }
	tickId = requestFrame(handleScroll);
	isQueued = true;
}

function cancelTick() {
	if (!isQueued) {
        return;
	}
	cancelFrame(tickId);
	isQueued = false;
}

function detectIdle() {
    isIdle = true;
    cancelTick();
    enableScrollListener();
}

/**
 * Attach callback to debounced scroll event
 *
 * Takes two forms:
 * @param function callback  Function to attach to a vertical scroll event
 * Or:
 * @param string   direction Direction of scroll to attach to:
 *                 'horizontal'/'x', 'vertical'/'y' (the default),
 *                 or 'any' (listens to both)
 * @param function callback  Function to attach to a scroll event in specified direction
 */
function onscrolling(direction, callback) {
	if (!isSupported) {
		return;
	}
	enableScrollListener();
    // Verify parameters
    if (typeof direction === 'function') {
        callback = direction;
        callbackQueue.y.push(callback);
        return;
    }
    if (typeof callback === 'function') {
        if (~directionX.indexOf(direction)) {
            callbackQueue.x.push(callback);
        } else if (~directionAll.indexOf(direction)) {
            callbackQueue.any.push(callback);
        } else {
            callbackQueue.y.push(callback);
        }
    }
}

onscrolling.remove = function(direction, fn) {
    var queueKey = 'y',
        queue,
        fnIdx;

    if (typeof direction === 'string') {
        // If second parameter is not a function, return
        if (typeof fn !== 'function') {
            return;
        }
        if (~directionX.indexOf(direction)) {
            queueKey = directionX[0];
        } else if (~directionAll.indexOf(direction)) {
            queueKey = directionAll[0];
        }
    } else {
        fn = direction;
    }
    queue = callbackQueue[queueKey];
    fnIdx = queue.indexOf(fn);
    if (fnIdx > -1) {
        queue.splice(fnIdx, 1);
    }
};
onscrolling.off = onscrolling.remove;

export default onscrolling;
<commit_msg>Disable listening if there are no listener callbacks left<commit_after>'use strict';

// Get proper requestAnimationFrame
var requestFrame = window.requestAnimationFrame,
    cancelFrame  = window.cancelAnimationFrame;

if (!requestFrame) {
    ['ms', 'moz', 'webkit', 'o'].every(function(prefix) {
        requestFrame = window[prefix + 'RequestAnimationFrame'];
        cancelFrame  = window[prefix + 'CancelAnimationFrame'] ||
                       window[prefix + 'CancelRequestAnimationFrame'];
        // Continue iterating only if requestFrame is still false
        return !requestFrame;
    });
}

// Module state
var isSupported    = !!requestFrame,
    isListening    = false,
    isQueued       = false,
    isIdle         = true,
    scrollY        = window.pageYOffset,
    scrollX        = window.pageXOffset,
    scrollYCached  = scrollY,
    scrollXCached  = scrollX,
    directionX     = ['x', 'horizontal'],
    directionAll   = ['any'],
    callbackQueue  = {
        x   : [],
        y   : [],
        any : []
    },
    detectIdleTimeout,
    tickId;

// Main scroll handler
// -------------------
function handleScroll() {
    var isScrollChanged = false;
    if (callbackQueue.x.length || callbackQueue.any.length) {
        scrollX = window.pageXOffset;
    }
    if (callbackQueue.y.length || callbackQueue.any.length) {
        scrollY = window.pageYOffset;
    }

	if (scrollY !== scrollYCached) {
        callbackQueue.y.forEach(triggerCallback.y);
        scrollYCached = scrollY;
        isScrollChanged = true;
    }
	if (scrollX !== scrollXCached) {
        callbackQueue.x.forEach(triggerCallback.x);
        scrollXCached = scrollX;
        isScrollChanged = true;
    }
    if (isScrollChanged) {
        callbackQueue.any.forEach(triggerCallback.any);
        window.clearTimeout(detectIdleTimeout);
        detectIdleTimeout = null;
    }

    isQueued = false;
    requestTick();
}

// Utilities
// ---------
function triggerCallback(callback, scroll) {
    callback(scroll);
}
triggerCallback.y = function(callback) {
    triggerCallback(callback, scrollY);
};
triggerCallback.x = function(callback) {
    triggerCallback(callback, scrollX);
};
triggerCallback.any = function(callback) {
    triggerCallback(callback, [scrollX, scrollY]);
};

function enableScrollListener() {
    if (isListening || isQueued) {
        return;
    }
    if (isIdle) {
        isListening = true;
        window.addEventListener('scroll', onScrollDebouncer);
        document.body.addEventListener('touchmove', onScrollDebouncer);
        return;
    }
    requestTick();
}

function disableScrollListener() {
    if (!isListening) {
        return;
    }
    window.removeEventListener('scroll', onScrollDebouncer);
    document.body.removeEventListener('touchmove', onScrollDebouncer);
    isListening = false;
}

function onScrollDebouncer() {
    isIdle = false;
	requestTick();
    disableScrollListener();
}

function requestTick() {
	if (isQueued) {
        return;
	}
    if (!detectIdleTimeout) {
        // Idle is defined as 1.5 seconds without scroll change
        detectIdleTimeout = window.setTimeout(detectIdle, 1500);
    }
	tickId = requestFrame(handleScroll);
	isQueued = true;
}

function cancelTick() {
	if (!isQueued) {
        return;
	}
	cancelFrame(tickId);
	isQueued = false;
}

function detectIdle() {
    isIdle = true;
    cancelTick();
    enableScrollListener();
}

/**
 * Attach callback to debounced scroll event
 *
 * Takes two forms:
 * @param function callback  Function to attach to a vertical scroll event
 * Or:
 * @param string   direction Direction of scroll to attach to:
 *                 'horizontal'/'x', 'vertical'/'y' (the default),
 *                 or 'any' (listens to both)
 * @param function callback  Function to attach to a scroll event in specified direction
 */
function onscrolling(direction, callback) {
	if (!isSupported) {
		return;
	}
	enableScrollListener();
    // Verify parameters
    if (typeof direction === 'function') {
        callback = direction;
        callbackQueue.y.push(callback);
        return;
    }
    if (typeof callback === 'function') {
        if (~directionX.indexOf(direction)) {
            callbackQueue.x.push(callback);
        } else if (~directionAll.indexOf(direction)) {
            callbackQueue.any.push(callback);
        } else {
            callbackQueue.y.push(callback);
        }
    }
}

onscrolling.remove = function(direction, fn) {
    var queueKey = 'y',
        queue,
        fnIdx;

    if (typeof direction === 'string') {
        // If second parameter is not a function, return
        if (typeof fn !== 'function') {
            return;
        }
        if (~directionX.indexOf(direction)) {
            queueKey = directionX[0];
        } else if (~directionAll.indexOf(direction)) {
            queueKey = directionAll[0];
        }
    } else {
        fn = direction;
    }
    queue = callbackQueue[queueKey];
    fnIdx = queue.indexOf(fn);
    if (fnIdx > -1) {
        queue.splice(fnIdx, 1);
    }
    // If there's no listeners left, disable listening
    if (!callbackQueue.x.length && !callbackQueue.y.length && !callbackQueue.any.length) {
        cancelTick();
        disableScrollListener();
    }
};
onscrolling.off = onscrolling.remove;

export default onscrolling;
<|endoftext|>


<commit_before>import React from "react";
import { withPrefix } from "gatsby-link";
import Img from "gatsby-image";
import styled from "styled-components";

import * as palette from "../utils/styles";

const AboutPage = ({ data }) => {
  const { name, bio, portrait } = data.contentfulAbout;

  const Wrapper = styled.div``;
  const Grid = styled.div`
    margin: 1rem 0;
    display: grid;
    grid-template-columns: 1fr;
    grid-auto-flow: row dense;
    grid-gap: 1rem;
  `;
  const GridItem = styled.div`
    .gatsby-image-outer-wrapper,
    .gatsby-image-wrapper {
      position: static !important;
    }
  `;
  const Card = styled.div`
    background: ${palette.POST_COLOR};
    min-height: ${palette.HEIGHT};
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: left;
    justify-content: top;
    flex-direction: column;
  `;
  const Cover = styled.div`
    width: 100%;
    height: 100%;
    position: absolute;
  `;
  const Data = styled.div`
    background: ${palette.POST_COLOR};
    padding: 1rem;
    z-index: 10;
    opacity: 1;
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-auto-flow: row dense;
    grid-gap: 1rem;
    @media (max-width: 991px) {
      grid-template-columns: 1fr;
    }
  `;
  const CardContent = styled.div`
    padding: 1rem;
    position: relative;
  `;
  const Name = styled.h1`
    text-transform: uppercase;
  `;

  const Form = styled.form`
    max-width: 100%;
    margin: 0 auto;
    display: flex;
    flex-flow: row wrap;
    justify-content: space-between;
    align-items: flex-start;
    input,
    textarea {
      font-family: inherit;
      font-size: inherit;
      background: none;
      border: 1px ${palette.SECONDARY_COLOR} solid;
      outline: none;
      color: ${palette.SECONDARY_COLOR};
      border-radius: 0px;
      padding: 0.618rem;
      resize: none;
      &:focus {
        outline: none;
      }
      &:required {
        box-shadow: none;
      }
    }
  `;

  const FormName = styled.input`
    margin: 0 0 1rem 0;
    width: 100%;
    @media (min-width: 992px) {
      width: 49%;
    }
  `;

  const Email = styled.input`
    margin: 0 0 1rem 0;
    width: 100%;
    @media (min-width: 992px) {
      width: 49%;
    }
  `;

  const Message = styled.textarea`
    width: 100%;
    margin: 0 0 1rem 0;
    line-height: 1.6;
    min-height: 15vh;
    resize: vertical;
  `;
  const Submit = styled.input`
    cursor: pointer;
    transition: 0.2s;
    width: 100%;
  `;
  const SocialIcon = styled.div`
    display: flex;
    flex-direction: row;
    align-items: center;
    position: relative;
    margin-bottom: 0.618rem;
    a {
      margin: 1rem;
    }
    a:first-child {
      margin-left: 0;
    }
    img {
      height: 1.382rem;
      margin: 0;
      vertical-align: middle;
    }
  `;

  return (
    <wrapper>
      <Grid>
        <GridItem>
          <Data>
            <CardContent>
              <Name>{name}</Name>
              <SocialIcon>

              </SocialIcon>

            </CardContent>

            <Form
              name="contact"
              method="POST"
              action="/about-thanks"
              data-netlify="true"
              data-netlify-honeypot="bot-field"
            >

                thanks

              <input
                type="hidden"
                name="form-name"
                value="contact"
                action="/about-thanks/"
              />

                  Don’t fill this out:{" "}
                  <input className="hidden" name="bot-field" />

              <FormName
                name="name"
                type="text"
                placeholder="Full Name"
                required
              />
              <Email name="email" type="email" placeholder="Email" required />
              <Message
                name="message"
                type="text"
                placeholder="Message"
                required
              />
              <Submit name="submit" type="submit" value="Send" />
            </Form>
          </Data>
        </GridItem>
        <GridItem>
          <Card>
            <Cover>

            </Cover>
          </Card>
        </GridItem>
      </Grid>
    </wrapper>
  );
};

export const query = graphql`
  query AboutQuery {
    contentfulAbout {
      name
      id
      formSubmission {
        childMarkdownRemark {
          html
        }
      }
      portrait {
        resolutions(width: 1800) {
          ...GatsbyContentfulResolutions_withWebp
        }
      }
      bio {
        childMarkdownRemark {
          html
        }
      }
    }
  }
`;
export default AboutPage;
<commit_msg>Update about.js<commit_after>import React from "react";
import { withPrefix } from "gatsby-link";
import Img from "gatsby-image";
import styled from "styled-components";

import * as palette from "../utils/styles";

const AboutPage = ({ data }) => {
  const { name, bio, portrait } = data.contentfulAbout;

  const Wrapper = styled.div``;
  const Grid = styled.div`
    margin: 1rem 0;
    display: grid;
    grid-template-columns: 1fr;
    grid-auto-flow: row dense;
    grid-gap: 1rem;
  `;
  const GridItem = styled.div`
    .gatsby-image-outer-wrapper,
    .gatsby-image-wrapper {
      position: static !important;
    }
  `;
  const Card = styled.div`
    background: ${palette.POST_COLOR};
    min-height: ${palette.HEIGHT};
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: left;
    justify-content: top;
    flex-direction: column;
  `;
  const Cover = styled.div`
    width: 100%;
    height: 100%;
    position: absolute;
  `;
  const Data = styled.div`
    background: ${palette.POST_COLOR};
    padding: 1rem;
    z-index: 10;
    opacity: 1;
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-auto-flow: row dense;
    grid-gap: 1rem;
    @media (max-width: 991px) {
      grid-template-columns: 1fr;
    }
  `;
  const CardContent = styled.div`
    padding: 1rem;
    position: relative;
  `;
  const Name = styled.h1`
    text-transform: uppercase;
  `;

  const Form = styled.form`
    width: 100%;
    max-width: 100%;
    margin: 0 auto;
    display: flex;
    flex-flow: row wrap;
    justify-content: space-between;
    align-items: flex-start;
    input,
    textarea {
      font-family: inherit;
      font-size: inherit;
      background: none;
      border: 1px ${palette.SECONDARY_COLOR} solid;
      outline: none;
      color: ${palette.SECONDARY_COLOR};
      border-radius: 0px;
      padding: 0.618rem;
      resize: none;
      &:focus {
        outline: none;
      }
      &:required {
        box-shadow: none;
      }
    }
  `;

  const FormName = styled.input`
    margin: 0 0 1rem 0;
    width: 100%;
    @media (min-width: 992px) {
      width: 49%;
    }
  `;

  const Email = styled.input`
    margin: 0 0 1rem 0;
    width: 100%;
    @media (min-width: 992px) {
      width: 49%;
    }
  `;

  const Message = styled.textarea`
    width: 100%;
    margin: 0 0 1rem 0;
    line-height: 1.6;
    min-height: 15vh;
    resize: vertical;
  `;
  const Submit = styled.input`
    cursor: pointer;
    transition: 0.2s;
    width: 100%;
  `;
  const SocialIcon = styled.div`
    display: flex;
    flex-direction: row;
    align-items: center;
    position: relative;
    margin-bottom: 0.618rem;
    a {
      margin: 1rem;
    }
    a:first-child {
      margin-left: 0;
    }
    img {
      height: 1.382rem;
      margin: 0;
      vertical-align: middle;
    }
  `;

  return (
    <wrapper>
      <Grid>
        <GridItem>
          <Data>
            <CardContent>
              <Name>{name}</Name>
              <SocialIcon>

              </SocialIcon>

            </CardContent>

            <Form
              name="contact"
              method="POST"
              action="/about-thanks"
              data-netlify="true"
              data-netlify-honeypot="bot-field"
            >

                thanks

              <input
                type="hidden"
                name="form-name"
                value="contact"
                action="/about-thanks/"
              />

                  Don’t fill this out:{" "}
                  <input className="hidden" name="bot-field" />

              <FormName
                name="name"
                type="text"
                placeholder="Full Name"
                required
              />
              <Email name="email" type="email" placeholder="Email" required />
              <Message
                name="message"
                type="text"
                placeholder="Message"
                required
              />
              <Submit name="submit" type="submit" value="Send" />
            </Form>
          </Data>
        </GridItem>
        <GridItem>
          <Card>
            <Cover>

            </Cover>
          </Card>
        </GridItem>
      </Grid>
    </wrapper>
  );
};

export const query = graphql`
  query AboutQuery {
    contentfulAbout {
      name
      id
      formSubmission {
        childMarkdownRemark {
          html
        }
      }
      portrait {
        resolutions(width: 1800) {
          ...GatsbyContentfulResolutions_withWebp
        }
      }
      bio {
        childMarkdownRemark {
          html
        }
      }
    }
  }
`;
export default AboutPage;
<|endoftext|>


<commit_before>import React from "react";
import Link from "gatsby-link"
import Helmet from "react-helmet"
import $ from 'jquery';

export default class Index extends React.Component {
  componentDidMount() {
    // window.nvtag_callbacks = window.nvtag_callbacks || {};
    // var postRenderCallbacks = window.nvtag_callbacks.postRender = window.nvtag_callbacks.postRender || [];
    // var ngpHasInit = postRenderCallbacks.length > 0;
    // if (!ngpHasInit) {
    //     console.log("SETUP")
    //     postRenderCallbacks.push(function() {
    //       console.log('ngp has rendered');
    //       var $signupHolder = $('.ngp-signup-holder');
    //       var $getInvolvedHolder = $('.ngp-get-involved-holder');
    //
    //       if (!signupForm) {
    //         signupForm = $signupHolder.find('.ngp-form');
    //         getInvolvedForm = $getInvolvedHolder.find('.ngp-form');
    //       }
    //
    //       var newsignupForm = signupForm.clone();
    //       var newgetInvolvedForm = getInvolvedForm.clone();
    //
    //       $('.ngp-signup-display').append(newsignupForm);
    //       $('.ngp-get-involved-display').append(newgetInvolvedForm);
    //     })

    window.NgpForms.onFormReady("Quick Sign Up", function() {
      console.log('quick signup start render');
      var $signupHolder = $('.ngp-signup-holder');
      var signupForm = $signupHolder.find('.ngp-form');
      var newsignupForm = signupForm.clone();
      $('.ngp-signup-display').append(newsignupForm);
      console.log('quick signup rendered');
    });

  }
  componentWillUnmount() {
    $('.ngp-signup-display').find('.ngp-form').detach();
    $('.ngp-signup-display').find('.ngp-form').detach();
  }
  render() {
    const { about: { about }, quote: { quote } } = this.props.data.basic
    return (

About Alex

                  Contribute

                  Get Involved

Get Involved

              PAID FOR BY ALEX T FOR CONGRESS

PO Box 25345, Houston, TX 77265

                832.779.1878 |{" "}

                  info@alextfortexas.com

                  Website Design by Mouth Watering Media

                Contribute

                    <svg
                      xmlns="http://www.w3.org/2000/svg"
                      width="30"
                      height="30"
                      viewBox="-9 11 30 30"
                      enableBackground="new -9 11 30 30"
                    >
                      <g fill="#fff">
                        <path d="m2 36.2c8.8 0 13.6-7.3 13.6-13.6 0-.2 0-.4 0-.6.9-.7 1.7-1.5 2.4-2.5-.9.4-1.8.6-2.7.8 1-.6 1.7-1.5 2.1-2.6-.9.5-1.9.9-3 1.2-.9-.9-2.1-1.5-3.5-1.5-2.6 0-4.8 2.1-4.8 4.8 0 .4 0 .7.1 1.1-4-.2-7.5-2.1-9.9-5-.4.5-.6 1.3-.6 2.2 0 1.7.8 3.1 2.1 4-.8 0-1.5-.2-2.2-.6 0 0 0 0 0 .1 0 2.3 1.6 4.3 3.8 4.7-.4.1-.8.2-1.3.2-.3 0-.6 0-.9-.1.6 1.9 2.4 3.3 4.5 3.3-1.6 1.3-3.7 2-5.9 2-.4 0-.8 0-1.1-.1 2.1 1.4 4.6 2.2 7.3 2.2" />
                      </g>
                    </svg>

                    <svg
                      xmlns="http://www.w3.org/2000/svg"
                      width="30"
                      height="30"
                      viewBox="-9 11 30 30"
                      enableBackground="new -9 11 30 30"
                    >
                      <g fill="#fff">
                        <path d="m7.5 36.5v-9.6h3.2l.5-3.8h-3.7v-2.4c0-1.1.3-1.8 1.9-1.8h2v-3.4c-.3 0-1.5-.1-2.9-.1-2.9 0-4.8 1.8-4.8 5v2.8h-3.2v3.8h3.2v9.6l3.8-.1" />
                      </g>
                    </svg>

                    <svg
                      xmlns="http://www.w3.org/2000/svg"
                      width="30"
                      height="30"
                      viewBox="-9 11 30 30"
                      enableBackground="new -9 11 30 30"
                    >
                      <g fill="#fff">
                        <path d="m6 16.4c3.1 0 3.5 0 4.7.1 1.1.1 1.8.2 2.2.4.5.2.9.5 1.3.9s.7.8.9 1.3c.2.4.4 1 .4 2.2.1 1.2.1 1.6.1 4.7s0 3.5-.1 4.7c-.1 1.1-.2 1.8-.4 2.2-.2.5-.5.9-.9 1.3-.4.4-.8.7-1.3.9-.4.2-1 .4-2.2.4-1.2.1-1.6.1-4.7.1s-3.5 0-4.7-.1c-1.1-.1-1.8-.2-2.2-.4-.5-.2-.9-.5-1.3-.9-.4-.4-.7-.8-.9-1.3-.2-.4-.4-1-.4-2.2-.1-1.2-.1-1.6-.1-4.7s0-3.5.1-4.7c.1-1.1.2-1.8.4-2.2.2-.5.5-.9.9-1.3.4-.4.8-.7 1.3-.9.4-.2 1-.4 2.2-.4 1.2-.1 1.6-.1 4.7-.1m0-2.1c-3.2 0-3.6 0-4.8.1-1.2.1-2.1.3-2.8.5-.8.3-1.4.7-2.1 1.4-.7.7-1.1 1.3-1.4 2.1-.3.7-.5 1.6-.5 2.8-.1 1.2-.1 1.6-.1 4.8s0 3.6.1 4.8c.1 1.2.3 2.1.5 2.8.3.8.7 1.4 1.4 2.1.7.7 1.3 1.1 2.1 1.4.7.3 1.6.5 2.8.5 1.2.1 1.6.1 4.8.1 3.2 0 3.6 0 4.8-.1 1.2-.1 2.1-.3 2.8-.5.8-.3 1.4-.7 2.1-1.4.7-.7 1.1-1.3 1.4-2.1.3-.7.5-1.6.5-2.8.1-1.2.1-1.6.1-4.8s0-3.6-.1-4.8-.3-2.1-.5-2.8c-.3-.8-.7-1.4-1.4-2.1-.7-.7-1.3-1.1-2.1-1.4-.7-.3-1.6-.5-2.8-.5-1.2-.1-1.6-.1-4.8-.1z" />
                        <path d="m6 20c-3.3 0-6 2.7-6 6s2.7 6 6 6 6-2.7 6-6-2.7-6-6-6m0 9.9c-2.2 0-3.9-1.7-3.9-3.9s1.7-3.9 3.9-3.9c2.2 0 3.9 1.7 3.9 3.9s-1.7 3.9-3.9 3.9" />
                        <circle cx="12.2" cy="19.8" r="1.4" />
                      </g>
                    </svg>

    );
  }
}
export const pageQuery = graphql`
  query PageQuery {
    basic: contentfulBasicInfo {
        id
        about { about }
        quote { quote }
    }
  }
`
<commit_msg>debug before registering listeners for ngp form<commit_after>import React from "react";
import Link from "gatsby-link"
import Helmet from "react-helmet"
import $ from 'jquery';

export default class Index extends React.Component {
  componentDidMount() {
    // window.nvtag_callbacks = window.nvtag_callbacks || {};
    // var postRenderCallbacks = window.nvtag_callbacks.postRender = window.nvtag_callbacks.postRender || [];
    // var ngpHasInit = postRenderCallbacks.length > 0;
    // if (!ngpHasInit) {
    //     console.log("SETUP")
    //     postRenderCallbacks.push(function() {
    //       console.log('ngp has rendered');
    //       var $signupHolder = $('.ngp-signup-holder');
    //       var $getInvolvedHolder = $('.ngp-get-involved-holder');
    //
    //       if (!signupForm) {
    //         signupForm = $signupHolder.find('.ngp-form');
    //         getInvolvedForm = $getInvolvedHolder.find('.ngp-form');
    //       }
    //
    //       var newsignupForm = signupForm.clone();
    //       var newgetInvolvedForm = getInvolvedForm.clone();
    //
    //       $('.ngp-signup-display').append(newsignupForm);
    //       $('.ngp-get-involved-display').append(newgetInvolvedForm);
    //     })

    console.log('before register quicksignup')
    window.NgpForms.onFormReady("Quick Sign Up", function() {
      console.log('quick signup start render');
      var $signupHolder = $('.ngp-signup-holder');
      var signupForm = $signupHolder.find('.ngp-form');
      var newsignupForm = signupForm.clone();
      $('.ngp-signup-display').append(newsignupForm);
      console.log('quick signup rendered');
    });

  }
  componentWillUnmount() {
    $('.ngp-signup-display').find('.ngp-form').detach();
    $('.ngp-signup-display').find('.ngp-form').detach();
  }
  render() {
    const { about: { about }, quote: { quote } } = this.props.data.basic
    return (

About Alex

                  Contribute

                  Get Involved

Get Involved

              PAID FOR BY ALEX T FOR CONGRESS

PO Box 25345, Houston, TX 77265

                832.779.1878 |{" "}

                  info@alextfortexas.com

                  Website Design by Mouth Watering Media

                Contribute

                    <svg
                      xmlns="http://www.w3.org/2000/svg"
                      width="30"
                      height="30"
                      viewBox="-9 11 30 30"
                      enableBackground="new -9 11 30 30"
                    >
                      <g fill="#fff">
                        <path d="m2 36.2c8.8 0 13.6-7.3 13.6-13.6 0-.2 0-.4 0-.6.9-.7 1.7-1.5 2.4-2.5-.9.4-1.8.6-2.7.8 1-.6 1.7-1.5 2.1-2.6-.9.5-1.9.9-3 1.2-.9-.9-2.1-1.5-3.5-1.5-2.6 0-4.8 2.1-4.8 4.8 0 .4 0 .7.1 1.1-4-.2-7.5-2.1-9.9-5-.4.5-.6 1.3-.6 2.2 0 1.7.8 3.1 2.1 4-.8 0-1.5-.2-2.2-.6 0 0 0 0 0 .1 0 2.3 1.6 4.3 3.8 4.7-.4.1-.8.2-1.3.2-.3 0-.6 0-.9-.1.6 1.9 2.4 3.3 4.5 3.3-1.6 1.3-3.7 2-5.9 2-.4 0-.8 0-1.1-.1 2.1 1.4 4.6 2.2 7.3 2.2" />
                      </g>
                    </svg>

                    <svg
                      xmlns="http://www.w3.org/2000/svg"
                      width="30"
                      height="30"
                      viewBox="-9 11 30 30"
                      enableBackground="new -9 11 30 30"
                    >
                      <g fill="#fff">
                        <path d="m7.5 36.5v-9.6h3.2l.5-3.8h-3.7v-2.4c0-1.1.3-1.8 1.9-1.8h2v-3.4c-.3 0-1.5-.1-2.9-.1-2.9 0-4.8 1.8-4.8 5v2.8h-3.2v3.8h3.2v9.6l3.8-.1" />
                      </g>
                    </svg>

                    <svg
                      xmlns="http://www.w3.org/2000/svg"
                      width="30"
                      height="30"
                      viewBox="-9 11 30 30"
                      enableBackground="new -9 11 30 30"
                    >
                      <g fill="#fff">
                        <path d="m6 16.4c3.1 0 3.5 0 4.7.1 1.1.1 1.8.2 2.2.4.5.2.9.5 1.3.9s.7.8.9 1.3c.2.4.4 1 .4 2.2.1 1.2.1 1.6.1 4.7s0 3.5-.1 4.7c-.1 1.1-.2 1.8-.4 2.2-.2.5-.5.9-.9 1.3-.4.4-.8.7-1.3.9-.4.2-1 .4-2.2.4-1.2.1-1.6.1-4.7.1s-3.5 0-4.7-.1c-1.1-.1-1.8-.2-2.2-.4-.5-.2-.9-.5-1.3-.9-.4-.4-.7-.8-.9-1.3-.2-.4-.4-1-.4-2.2-.1-1.2-.1-1.6-.1-4.7s0-3.5.1-4.7c.1-1.1.2-1.8.4-2.2.2-.5.5-.9.9-1.3.4-.4.8-.7 1.3-.9.4-.2 1-.4 2.2-.4 1.2-.1 1.6-.1 4.7-.1m0-2.1c-3.2 0-3.6 0-4.8.1-1.2.1-2.1.3-2.8.5-.8.3-1.4.7-2.1 1.4-.7.7-1.1 1.3-1.4 2.1-.3.7-.5 1.6-.5 2.8-.1 1.2-.1 1.6-.1 4.8s0 3.6.1 4.8c.1 1.2.3 2.1.5 2.8.3.8.7 1.4 1.4 2.1.7.7 1.3 1.1 2.1 1.4.7.3 1.6.5 2.8.5 1.2.1 1.6.1 4.8.1 3.2 0 3.6 0 4.8-.1 1.2-.1 2.1-.3 2.8-.5.8-.3 1.4-.7 2.1-1.4.7-.7 1.1-1.3 1.4-2.1.3-.7.5-1.6.5-2.8.1-1.2.1-1.6.1-4.8s0-3.6-.1-4.8-.3-2.1-.5-2.8c-.3-.8-.7-1.4-1.4-2.1-.7-.7-1.3-1.1-2.1-1.4-.7-.3-1.6-.5-2.8-.5-1.2-.1-1.6-.1-4.8-.1z" />
                        <path d="m6 20c-3.3 0-6 2.7-6 6s2.7 6 6 6 6-2.7 6-6-2.7-6-6-6m0 9.9c-2.2 0-3.9-1.7-3.9-3.9s1.7-3.9 3.9-3.9c2.2 0 3.9 1.7 3.9 3.9s-1.7 3.9-3.9 3.9" />
                        <circle cx="12.2" cy="19.8" r="1.4" />
                      </g>
                    </svg>

    );
  }
}
export const pageQuery = graphql`
  query PageQuery {
    basic: contentfulBasicInfo {
        id
        about { about }
        quote { quote }
    }
  }
`
<|endoftext|>


<commit_before>$.extend($.boom, {

	/**
	* @class
	* @name $.boom.editor
	*/
	editor : {
		/** @lends $.boom.editor */

		/** @property
		@type string
		@default '/boom/js/tiny_mce'
		*/
		base_url: '/media/boom/js/xing',
		/** @property
		@type string
		@default 'tiny_mce_src.js'
		*/
		path: '/wysihtml5-0.3.0.js',

		/**
		@property
		@type string
		*/
		parser_rules : '/parser_rules/hoop.js',

		/**
		@property
		@type string
		*/
		mode : 'block',

		/**
		@property
		@type object
		*/
		options : {
		},

		/**
		* @function
		@returns {Deferred}
		*/
		load : function() {

			var self = this;

			var editor_loaded = new $.Deferred();

			if (!top.wysihtml5) {

				$(document)
					.ready(function(){

						$.boom.log('wysihtml5 loading');

						top.$.getScript( self.base_url + self.parser_rules )
						.pipe( function(){
							return top.$.getScript( self.base_url + self.path );
						})
						.done( function(response, textStatus){

							editor_loaded.resolve();

							self._load_extensions( top.wysihtml5 );

							$.boom.log('wysihtml5 loaded');
						});

					});
			}

			return editor_loaded;
		},

		/**
		* @function
		@returns {boolean}
		*/
		ready : function() {

			if (!top.wysihtml5) {

				return false;
			}

			return true;
		},

		/**
		* @function
		@param {jQuery object} element The element being edited.
		@returns {Deferred}
		*/
		edit : function ( element ){

			var self = this;

			self.mode = element.is( 'div' ) ? 'block' : 'inline';
			self.mode = element.is( ':header' ) ? 'text' : self.mode;
			self.edited = new $.Deferred();

			self._insert_toolbar( element )
				.done( function(){

					$.boom.page.toolbar.hide();

					if ( self.mode == 'text' || self.mode == 'inline' ) {

						self.original_html = element.text();

						self.inline_editor.init( element );
					} else {

						self._insert_textarea( element );

						self.instance = new top.wysihtml5.Editor('b-wh5', { // id of textarea element
							toolbar:      "wysihtml5-toolbar", // id of toolbar element
							style: true,
							parserRules:  top.wysihtml5ParserRules // defined in parser rules set
						});

						self.instance.on( 'load', function(){

							var frame =  self.instance.composer.iframe;
							$( frame )
								.css( 'border', '1px solid #333')
								.contents()
								.find( 'head' )
								.append( '<link rel="stylesheet" href="/media/site/css/main.css" />' );

							resizeIframe();

							self.original_html = self.get_content();

							var el = self.instance.composer.element;

							if (el.addEventListener) {
							  	el.addEventListener("blur", resizeIframe, false);
								el.addEventListener("focus", resizeIframe, false);
								el.addEventListener("keyup", resizeIframe, false);
							} else if (el.attachEvent)  {
								el.attachEvent("onblur", resizeIframe);
								el.attachEvent("onfocus", resizeIframe);
								el.attachEvent("onkeyup", resizeIframe);
							}

						});

						self.instance.on( 'show:dialog', function( options ){

							switch( options.command ) {
								case 'createLink' :
									var href = top.$( '[data-wysihtml5-dialog-field=href]' ).val();
								 	var match = href.match( /asset\/(thumb|view|get_asset)\/([0-9]+)/ );
									var asset_id = match ? match[2] : 0;
									if ( asset_id == 0 ) self._edit_link();
									break;
								case 'insertImage' :
									var src = top.$( '[data-wysihtml5-dialog-field=src]' ).val();
									var asset_id = 0;
									if ( src && src != 'http://' ) {
										var match = src.match( /asset\/(thumb|view|get_asset)\/([0-9]+)/ );

										asset_id = match ? match[2] : 0;
									}
									self._edit_asset( asset_id );
									break;
							}
						});

						var resizeIframe = function() {
						    self.instance.composer.iframe.style.height = self.instance.composer.element.scrollHeight + "px";
						};

						self.instance.on( 'paste', resizeIframe );
					}
				});

			return self.edited;

		},

		/**
		* @function
		@returns {String} HTML content of the editor
		*/
		get_content : function(){

			return top.$( '#b-wh5' ).val();
		},

		/**
		* @function
		@param {jQuery object} element The element being edited.
		*/
		remove : function( element ){

			$.boom.page.toolbar.show();
			top.$( '#b-wh5, #wysihtml5-toolbar, iframe.wysihtml5-sandbox' ).remove();
			element.removeAttr( 'contenteditable' );
			self.instance = null;
		},

		/**
		* @function
		@param {jQuery object} element The element being edited.
		*/
		apply : function( element ){

			var self = this;

			self.edited.resolve( self.get_content() );

			self.remove( element );

		},

		/**
		* @function
		@param {jQuery object} element The element being edited.
		*/
		cancel : function( element ){

			var self = this;

			if ( self.mode == 'text' || self.mode == 'inline' ) {
				var content = element.text();
			} else {
				var content = self.get_content();
			}

			if ( content != self.original_html ) {

				$.boom.dialog.confirm(
					'Cancel changes',
					'Cancel all changes and exit the editor?',
					function(){

						$.boom.log( 'canceling text edits' );

						self.remove( element );

						self.edited.reject();
					}
				);

			} else {

				self.remove( element );
				self.edited.reject();
			}

		},

		/**
		@function
		@param {jQuery object} element The element being edited.
		@returns {Deferred}
		*/
		_insert_toolbar : function( element ) {

			var self = this;

			 return $.get( '/media/boom/toolbars/text.php?mode=' + self.mode )
			.done( function( response ) {
				top.$('body').prepend( response );

				top.$( '#b-editor-accept').on( 'click', function( event ){

					event.preventDefault();
					self.apply( element );
					return false;
				});

				top.$( '#b-editor-cancel').on( 'click', function( event ){

					event.preventDefault();
					self.cancel( element );
					return false;
				});
			});

		},

		/**
		@function
		@param {jQuery object} element The element being edited.
		*/
		_insert_textarea : function( element ) {
			var original_html = element.html();
			element
				.html( '<textarea id="b-wh5" style="border: 1px solid #000; overflow: hidden; width: 100%; height: ' + element.innerHeight() + 'px;">' + original_html + '</textarea>');
		},

		/**
		@function
		@returns {Deferred}
		*/
		_edit_asset : function( asset_rid ) {

			var self = this;
			var ed = self.instance.composer;

			 return $.boom.assets
				.picker({
					asset_rid : asset_rid
				})
				.done( function( rid ){

					$.post( '/asset/embed/' + rid )
					.done( function( response ) {
						ed.commands.exec( "insertHTML", response );
					});

				});
		},

		/**
		@function
		@returns {Deferred}
		*/
		_edit_link : function() {

			var self = this;
			var ed = self.instance.composer;
			var existing_link = ed.commands.state( "createLink" )[0];

			if ( !existing_link ) {
				ed.commands.exec("createLink", { href: '', rel: 'new-link'});

				existing_link = top.$( ed.element ).find( '[rel=new-link]' );
			}

			 return $.boom.links
				.picker({})
				.done( function( link ){

					var uri = link.url;
					var page_rid = link.rid;

					if ( existing_link ) {
						top.$( existing_link )
							.attr( 'href', uri )
							.attr( 'rel', page_rid );
					} else {
						if ( top.getSelection ) {
							console.log( selection );
							new_selection = top.getSelection( selection );
						} else if ( top.document.selection ) {
							new_selection = top.document.selection.createRange();
							console.log( selection );
							new_selection = new_selection.moveToBookmark( selection );
						} else {
							new_selection = top.rangy.getSelection();
						}

						ed.commands.exec("createLink", { href: uri, rel: page_rid});
					}

				});

		},

		/**
		@function
		@param {Object} wh5 Instance of wysihtml5
		*/
		_load_extensions : function( wh5 ) {

			/** blockquote command */
			(function(wysihtml5) {
				var undef;

				wysihtml5.commands.indent = {
					exec: function(composer, command) {

						command = this.state( composer ) ? 'outdent' : 'indent';

						/*
						TODO: what happens if a browser doesn't support indent/outdent?
						*/
						if (composer.commands.support(command)) {
							composer.doc.execCommand(command, false, null);

							/* clean inline styles left by webkit */
							var blockquote = this.state( composer );
							if ( blockquote ) {
								blockquote.removeAttribute( 'class' );
								blockquote.removeAttribute( 'style' );
							}
							return;
						}
					},

					state: function(composer) {
						var selectedNode = composer.selection.getSelectedNode();
						return wysihtml5.dom.getParentElement(selectedNode, { nodeName: "BLOCKQUOTE" });
					},

					value: function() {
						return undef;
					}
				};
			})( wh5 );
		},

		/**
		* @class
		* @name $.boom.editor.inline_editor
		*/
		inline_editor : {
			/** @lends $.boom.editor.inline_editor */

			/** @property */
			rangy : null,

			/** @property */
			toolbar : null,

			/** @property */
			selected_node : null,

			/** @function */
			init : function( element ) {

				var self = this;
				this.toolbar = top.$( '#wysihtml5-toolbar');
				this.rangy = top.rangy;

				element
					.attr( 'contenteditable', 'true' )
					.on( 'click', 'a, b, strong, i, em', function( event ){
						event.preventDefault();
						event.stopPropagation();
						self.highlight_command( this );
					} )
					.on( 'click', function( event ){
						event.preventDefault();
						event.stopPropagation();
						top.$( 'button[data-wysihtml5-command]' )
							.removeClass( 'wysihtml5-command-active' );
					} )
					.on( 'keydown', function( event ){
						switch( event.which ) {

							case 13:
								top.document.execCommand( 'insertHTML', null, '
' );

								return false;
							break;
						}
					});
				self.toolbar
					.on( 'mousedown', 'button[data-wysihtml5-command]', function(){

						var command = $( this ).attr( 'data-wysihtml5-command' );
						var button = $( this );

						switch( command ) {
							case 'createLink':
								var existing_link = self.selected_node;

								if ( !existing_link ) {
									top.document.execCommand( command, null, 'url' );

									self.selected_node = element.find( '[href=url]' )[0];
								}

								$.boom.links
									.picker({})
									.done( function( link ){

										var command = self.insert_link( link );

										switch( command ) {
											case 'unlink':
												button.removeClass( 'wysihtml5-command-active' );
											break;
											case 'createLink':
												button.addClass( 'wysihtml5-command-active' );
											break;
										}

									});
							break;

							case 'insertImage':
								var asset_rid = 0;
								$.boom.assets
									.picker({
										asset_rid : asset_rid
									})
									.done( function( rid ){

										$.post( '/asset/embed/' + rid )
										.done( function( response ) {
											top.document.execCommand( "insertHTML", null, response );
										});

									});
							break;

							default:
								top.document.execCommand( command, null, null );
								$( this ).toggleClass( 'wysihtml5-command-active' );
						}

					});
			},

			/** @function */
			select_node : function() {
				// expand the selection range to the clicked node.
				var selection;
				if ( top.getSelection ) {
					selection = top.getSelection();
				} else if ( top.document.selection ) {
					selection = top.document.selection.createRange();
				} else {
					selection = top.rangy.getSelection();
				}

				if ( selection.anchorNode ) {
					this.selected_node = selection.anchorNode.parentNode;
					selection.selectAllChildren( this.selected_node );
				} else {
					this.selected_node = selection.parentElement();
					selection.parentElement().focus();
				}

			},

			/** @function */
			highlight_command : function( node ) {

				var command = '';

				switch ( node.nodeName ){
					case 'A':
						command = 'createLink';
					break;
					case 'I': case 'EM':
						command = 'italic';
					break;
					case 'B': case 'STRONG':
						command = 'bold';
					break;
				}

				this.select_node();
				this.selected_node = node;
				top.$( 'button[data-wysihtml5-command=' + command + ']' )
					.addClass( 'wysihtml5-command-active' );

			},

			/** @function */
			insert_link : function( link ) {

				var url = link.url;
				var page_rid = link.rid;
				var existing_link = this.selected_node;

				command = ( url == 'http://' ) ? 'unlink' : 'createLink';

				if (document.selection ) {
					document.selection.createRange( self.selected_node );
				}

				console.log( existing_link );

				if ( existing_link && existing_link.nodeName == 'A' ) {
					top.$( existing_link )
						.attr( 'href', url )
						.attr( 'rel', page_rid );
				} else {
					top.document.execCommand( command, null, url );
				}

				return command;
			}
		}
	}
});
<commit_msg>fix the image editor in IE<commit_after>$.extend($.boom, {

	/**
	* @class
	* @name $.boom.editor
	*/
	editor : {
		/** @lends $.boom.editor */

		/** @property
		@type string
		@default '/boom/js/tiny_mce'
		*/
		base_url: '/media/boom/js/xing',
		/** @property
		@type string
		@default 'tiny_mce_src.js'
		*/
		path: '/wysihtml5-0.3.0.js',

		/**
		@property
		@type string
		*/
		parser_rules : '/parser_rules/hoop.js',

		/**
		@property
		@type string
		*/
		mode : 'block',

		/**
		@property
		@type object
		*/
		options : {
		},

		/**
		* @function
		@returns {Deferred}
		*/
		load : function() {

			var self = this;

			var editor_loaded = new $.Deferred();

			if (!top.wysihtml5) {

				$(document)
					.ready(function(){

						$.boom.log('wysihtml5 loading');

						top.$.getScript( self.base_url + self.parser_rules )
						.pipe( function(){
							return top.$.getScript( self.base_url + self.path );
						})
						.done( function(response, textStatus){

							editor_loaded.resolve();

							self._load_extensions( top.wysihtml5 );

							$.boom.log('wysihtml5 loaded');
						});

					});
			}

			return editor_loaded;
		},

		/**
		* @function
		@returns {boolean}
		*/
		ready : function() {

			if (!top.wysihtml5) {

				return false;
			}

			return true;
		},

		/**
		* @function
		@param {jQuery object} element The element being edited.
		@returns {Deferred}
		*/
		edit : function ( element ){

			var self = this;

			self.mode = element.is( 'div' ) ? 'block' : 'inline';
			self.mode = element.is( ':header' ) ? 'text' : self.mode;
			self.edited = new $.Deferred();

			self._insert_toolbar( element )
				.done( function(){

					$.boom.page.toolbar.hide();

					if ( self.mode == 'text' || self.mode == 'inline' ) {

						self.original_html = element.text();

						self.inline_editor.init( element );
					} else {

						self._insert_textarea( element );

						self.instance = new top.wysihtml5.Editor('b-wh5', { // id of textarea element
							toolbar:      "wysihtml5-toolbar", // id of toolbar element
							style: true,
							parserRules:  top.wysihtml5ParserRules // defined in parser rules set
						});

						self.instance.on( 'load', function(){

							var frame =  self.instance.composer.iframe;
							$( frame )
								.css( 'border', '1px solid #333')
								.contents()
								.find( 'head' )
								.append( '<link rel="stylesheet" href="/media/site/css/main.css" />' );

							resizeIframe();

							self.original_html = self.get_content();

							var el = self.instance.composer.element;

							if (el.addEventListener) {
							  	el.addEventListener("blur", resizeIframe, false);
								el.addEventListener("focus", resizeIframe, false);
								el.addEventListener("keyup", resizeIframe, false);
							} else if (el.attachEvent)  {
								el.attachEvent("onblur", resizeIframe);
								el.attachEvent("onfocus", resizeIframe);
								el.attachEvent("onkeyup", resizeIframe);
							}

						});

						self.instance.on( 'show:dialog', function( options ){

							switch( options.command ) {
								case 'createLink' :
									var href = top.$( '[data-wysihtml5-dialog-field=href]' ).val();
								 	var match = href.match( /asset\/(thumb|view|get_asset)\/([0-9]+)/ );
									var asset_id = match ? match[2] : 0;
									if ( asset_id == 0 ) self._edit_link();
									break;
								case 'insertImage' :
									var src = top.$( '[data-wysihtml5-dialog-field=src]' ).val();
									var asset_id = 0;
									if ( src && src != 'http://' ) {
										var match = src.match( /asset\/(thumb|view|get_asset)\/([0-9]+)/ );

										asset_id = match ? match[2] : 0;
									}
									self._edit_asset( asset_id );
									break;
							}
						});

						var resizeIframe = function() {
						    self.instance.composer.iframe.style.height = self.instance.composer.element.scrollHeight + "px";
						};

						self.instance.on( 'paste', resizeIframe );
					}
				});

			return self.edited;

		},

		/**
		* @function
		@returns {String} HTML content of the editor
		*/
		get_content : function(){

			return top.$( '#b-wh5' ).val();
		},

		/**
		* @function
		@param {jQuery object} element The element being edited.
		*/
		remove : function( element ){

			$.boom.page.toolbar.show();
			top.$( '#b-wh5, #wysihtml5-toolbar, iframe.wysihtml5-sandbox' ).remove();
			element.removeAttr( 'contenteditable' );
			self.instance = null;
		},

		/**
		* @function
		@param {jQuery object} element The element being edited.
		*/
		apply : function( element ){

			var self = this;

			self.edited.resolve( self.get_content() );

			self.remove( element );

		},

		/**
		* @function
		@param {jQuery object} element The element being edited.
		*/
		cancel : function( element ){

			var self = this;

			if ( self.mode == 'text' || self.mode == 'inline' ) {
				var content = element.text();
			} else {
				var content = self.get_content();
			}

			if ( content != self.original_html ) {

				$.boom.dialog.confirm(
					'Cancel changes',
					'Cancel all changes and exit the editor?',
					function(){

						$.boom.log( 'canceling text edits' );

						self.remove( element );

						self.edited.reject();
					}
				);

			} else {

				self.remove( element );
				self.edited.reject();
			}

		},

		/**
		@function
		@param {jQuery object} element The element being edited.
		@returns {Deferred}
		*/
		_insert_toolbar : function( element ) {

			var self = this;

			 return $.get( '/media/boom/toolbars/text.php?mode=' + self.mode )
			.done( function( response ) {
				top.$('body').prepend( response );

				top.$( '#b-editor-accept').on( 'click', function( event ){

					event.preventDefault();
					self.apply( element );
					return false;
				});

				top.$( '#b-editor-cancel').on( 'click', function( event ){

					event.preventDefault();
					self.cancel( element );
					return false;
				});
			});

		},

		/**
		@function
		@param {jQuery object} element The element being edited.
		*/
		_insert_textarea : function( element ) {
			var original_html = element.html();
			element
				.html( '<textarea id="b-wh5" style="border: 1px solid #000; overflow: hidden; width: 100%; height: ' + element.innerHeight() + 'px;">' + original_html + '</textarea>');
		},

		/**
		@function
		@returns {Deferred}
		*/
		_edit_asset : function( asset_rid ) {

			var self = this;
			var ed = self.instance.composer;

			ed.commands.exec( "insertHTML", '' );

			var img = top.$( ed.element ).find( '[src=url]' )

			return $.boom.assets
				.picker({
					asset_rid : asset_rid
				})
				.done( function( rid ){

					$.post( '/asset/embed/' + rid )
					.done( function( response ) {
						img.replaceWith( response );
					});

				});
		},

		/**
		@function
		@returns {Deferred}
		*/
		_edit_link : function() {

			var self = this;
			var ed = self.instance.composer;
			var existing_link = ed.commands.state( "createLink" )[0];

			if ( !existing_link ) {
				ed.commands.exec("createLink", { href: '', rel: 'new-link'});

				existing_link = top.$( ed.element ).find( '[rel=new-link]' );
			}

			 return $.boom.links
				.picker({})
				.done( function( link ){

					var uri = link.url;
					var page_rid = link.rid;

					if ( existing_link ) {
						top.$( existing_link )
							.attr( 'href', uri )
							.attr( 'rel', page_rid );
					} else {
						if ( top.getSelection ) {
							console.log( selection );
							new_selection = top.getSelection( selection );
						} else if ( top.document.selection ) {
							new_selection = top.document.selection.createRange();
							console.log( selection );
							new_selection = new_selection.moveToBookmark( selection );
						} else {
							new_selection = top.rangy.getSelection();
						}

						ed.commands.exec("createLink", { href: uri, rel: page_rid});
					}

				});

		},

		/**
		@function
		@param {Object} wh5 Instance of wysihtml5
		*/
		_load_extensions : function( wh5 ) {

			/** blockquote command */
			(function(wysihtml5) {
				var undef;

				wysihtml5.commands.indent = {
					exec: function(composer, command) {

						command = this.state( composer ) ? 'outdent' : 'indent';

						/*
						TODO: what happens if a browser doesn't support indent/outdent?
						*/
						if (composer.commands.support(command)) {
							composer.doc.execCommand(command, false, null);

							/* clean inline styles left by webkit */
							var blockquote = this.state( composer );
							if ( blockquote ) {
								blockquote.removeAttribute( 'class' );
								blockquote.removeAttribute( 'style' );
							}
							return;
						}
					},

					state: function(composer) {
						var selectedNode = composer.selection.getSelectedNode();
						return wysihtml5.dom.getParentElement(selectedNode, { nodeName: "BLOCKQUOTE" });
					},

					value: function() {
						return undef;
					}
				};
			})( wh5 );
		},

		/**
		* @class
		* @name $.boom.editor.inline_editor
		*/
		inline_editor : {
			/** @lends $.boom.editor.inline_editor */

			/** @property */
			rangy : null,

			/** @property */
			toolbar : null,

			/** @property */
			selected_node : null,

			/** @function */
			init : function( element ) {

				var self = this;
				this.toolbar = top.$( '#wysihtml5-toolbar');
				this.rangy = top.rangy;

				element
					.attr( 'contenteditable', 'true' )
					.on( 'click', 'a, b, strong, i, em', function( event ){
						event.preventDefault();
						event.stopPropagation();
						self.highlight_command( this );
					} )
					.on( 'click', function( event ){
						event.preventDefault();
						event.stopPropagation();
						top.$( 'button[data-wysihtml5-command]' )
							.removeClass( 'wysihtml5-command-active' );
					} )
					.on( 'keydown', function( event ){
						switch( event.which ) {

							case 13:
								top.document.execCommand( 'insertHTML', null, '
' );

								return false;
							break;
						}
					});
				self.toolbar
					.on( 'mousedown', 'button[data-wysihtml5-command]', function(){

						var command = $( this ).attr( 'data-wysihtml5-command' );
						var button = $( this );

						switch( command ) {
							case 'createLink':
								var existing_link = self.selected_node;

								if ( !existing_link ) {
									top.document.execCommand( command, null, 'url' );

									self.selected_node = element.find( '[href=url]' )[0];
								}

								$.boom.links
									.picker({})
									.done( function( link ){

										var command = self.insert_link( link );

										switch( command ) {
											case 'unlink':
												button.removeClass( 'wysihtml5-command-active' );
											break;
											case 'createLink':
												button.addClass( 'wysihtml5-command-active' );
											break;
										}

									});
							break;

							case 'insertImage':
								var asset_rid = 0;
								$.boom.assets
									.picker({
										asset_rid : asset_rid
									})
									.done( function( rid ){

										$.post( '/asset/embed/' + rid )
										.done( function( response ) {
											top.document.execCommand( "insertHTML", null, response );
										});

									});
							break;

							default:
								top.document.execCommand( command, null, null );
								$( this ).toggleClass( 'wysihtml5-command-active' );
						}

					});
			},

			/** @function */
			select_node : function() {
				// expand the selection range to the clicked node.
				var selection;
				if ( top.getSelection ) {
					selection = top.getSelection();
				} else if ( top.document.selection ) {
					selection = top.document.selection.createRange();
				} else {
					selection = top.rangy.getSelection();
				}

				if ( selection.anchorNode ) {
					this.selected_node = selection.anchorNode.parentNode;
					selection.selectAllChildren( this.selected_node );
				} else {
					this.selected_node = selection.parentElement();
					selection.parentElement().focus();
				}

			},

			/** @function */
			highlight_command : function( node ) {

				var command = '';

				switch ( node.nodeName ){
					case 'A':
						command = 'createLink';
					break;
					case 'I': case 'EM':
						command = 'italic';
					break;
					case 'B': case 'STRONG':
						command = 'bold';
					break;
				}

				this.select_node();
				this.selected_node = node;
				top.$( 'button[data-wysihtml5-command=' + command + ']' )
					.addClass( 'wysihtml5-command-active' );

			},

			/** @function */
			insert_link : function( link ) {

				var url = link.url;
				var page_rid = link.rid;
				var existing_link = this.selected_node;

				command = ( url == 'http://' ) ? 'unlink' : 'createLink';

				if (document.selection ) {
					document.selection.createRange( self.selected_node );
				}

				console.log( existing_link );

				if ( existing_link && existing_link.nodeName == 'A' ) {
					top.$( existing_link )
						.attr( 'href', url )
						.attr( 'rel', page_rid );
				} else {
					top.document.execCommand( command, null, url );
				}

				return command;
			}
		}
	}
});
<|endoftext|>


<commit_before>(function($) {
    'use strict';

    var $parent = $('#apps-newsletter-subscribe');
    var $checkbox = $parent.find('#id_newsletter');
    var $settings = $parent.find('.newsletter-setting');
    var $agree = $parent.find('#id_agree');
    var required = 'required';

    if(!$checkbox.is(':checked')) {
        $settings.hide(0);
        $agree.removeAttr(required);
    }

    $checkbox.on('click', function() {
        if($checkbox.is(':checked')) {
            $settings.fadeIn();
            $agree.attr(required, required);
        } else {
            $settings.fadeOut();
            $agree.removeAttr(required);
        }
    });
})(jQuery);
<commit_msg>Fix checkbox id to take form prefix into account.<commit_after>(function($) {
    'use strict';

    var $parent = $('#apps-newsletter-subscribe');
    var $checkbox = $parent.find('#id_newsletter-newsletter');
    var $settings = $parent.find('.newsletter-setting');
    var $agree = $parent.find('#id_agree');
    var required = 'required';

    if(!$checkbox.is(':checked')) {
        $settings.hide(0);
        $agree.removeAttr(required);
    }

    $checkbox.on('click', function() {
        if($checkbox.is(':checked')) {
            $settings.fadeIn();
            $agree.attr(required, required);
        } else {
            $settings.fadeOut();
            $agree.removeAttr(required);
        }
    });
})(jQuery);
<|endoftext|>


<commit_before>'use strict'

const {type} = require('message-type')
const canvasApi = require('../canvasApi')
const Promise = require('bluebird')
const cl = require('../azureStorage')
const config = require('../server/init/configuration')
const log = require('../server/init/logging')
require('colors')

const csvVol = config.secure.azure.csvBlobName
const msgVol = config.secure.azure.msgBlobName
const csvDir = config.secure.localFile.csvDir
const lmsDatabase = config.secure.azure.databaseName
const lmsCollection = config.secure.azure.collectionName

function _createCsvFile (msg, sisCourseCode, timeStamp) {
  let header = 'course_id,user_id,role,status\n'
  let msgtype = msg._desc.userType
  let csvFileName = 'enrollments.' + msgtype + '.' + sisCourseCode + '.' + timeStamp + '.csv'
  let msgFileName = 'enrollments.' + msgtype + '.' + sisCourseCode + '.' + timeStamp + '.msg'
  let csvString = ''

  if (msg.member && msg.member.length > 0) {
    let csvArray = msg.member.map(user => {
      return {
        course_id: sisCourseCode,
        user_id: user,
        role: msgtype,
        status: 'active'
      }
    })
    csvArray.forEach(csvRow => {
      csvString = csvString + `${csvRow.course_id},${csvRow.user_id},${csvRow.role},${csvRow.status}
`
    })
  }

  let csvData = header + csvString
  log.info('\nGoing to open file: ' + csvFileName + ' ' + msgFileName)
  return cl.cloudStoreTextToFile(csvFileName, csvVol, csvData)
  .then(result => { log.info(result); return cl.cloudStoreTextToFile(msgFileName, msgVol, JSON.stringify(msg, null, 4)) })
  .then(() => cl.cloudgetFile(csvFileName, csvVol, csvDir))
  .then(result => { log.info(result); return {csvContent: csvData, csvFileName: csvDir + result.name} })
  .catch(error => { log.error(error); return Promise.reject(error) })
}

function _parseKeyStudent (key) {
  // ladok2.kurser.DM.2517.registrerade_20162.1
  let course = null
  let termin = null
  let year = null
  let ladok = null
  let myRe = /^(\w+).(\w+).(\w+).(\w+).(\w+)_(\d\d)(\d\d)(\d).(\d+)/g
  let myArray = myRe.exec(key)
  if (myArray != null) {
    let courseInOne = 3
    let courseInTwo = 4
    let terminIn = 8
    let yearIn = 7
    let ladokIn = 9
    course = myArray[courseInOne] + myArray[courseInTwo]
    termin = myArray[terminIn] === 1 ? 'VT' : 'HT'
    year = myArray[yearIn]
    ladok = myArray[ladokIn]
    let sisCourseCode = course + termin + year + ladok
    return sisCourseCode
  }
  return
}

function _parseKeyTeacher (key) {
   // edu.courses.AE.AE2302.20162.1.teachers edu.courses.DD.DD1310.20162.1.assistants
  let course = null
  let termin = null
  let year = null
  let ladok = null
  let courseIn = 2
  let terminIn = 5
  let yearIn = 4
  let ladokIn = 6

  let myRe = /^edu.courses.(\w+).(\w+).(\d\d)(\d\d)(\d).(\d).(\w+)$/g
  let myArray = myRe.exec(key)
  if (myArray != null) {
    course = myArray[courseIn]
    termin = myArray[terminIn] === 1 ? 'VT' : 'HT'
    year = myArray[yearIn]
    ladok = myArray[ladokIn]
    let sisCourseCode = course + termin + year + ladok
    return sisCourseCode
  }
  return
}

function _parseKey (key, msgtype) {
  let sisCourseCode = 0
  if (msgtype === type.students) {
    sisCourseCode = _parseKeyStudent(key)
  }
  if (msgtype === type.teachers || msgtype === type.assistants) {
    sisCourseCode = _parseKeyTeacher(key)
  }
  if (!sisCourseCode) {
    log.error('\nCourse code not parsable from Key. type, ' + msgtype + ' key, ' + key)
    return Promise.reject(Error('Key parse error, type, ' + msgtype + ' key, ' + key))
  }
  return Promise.resolve(sisCourseCode)
}

function _process (msg) {
  let sisCourseCode = ''
  let timeStamp = Date.now()

  return _parseKey(msg.ug1Name, msg._desc.userType)
    .then(sisCode => {
      sisCourseCode = sisCode
      log.info(`In _process ${sisCourseCode}, processing for ${msg._desc.userType}`)
      return canvasApi.findCourse(sisCourseCode)
    })
    .then(result => {
      log.info(JSON.parse(result, null, 4))
      return _createCsvFile(msg, sisCourseCode, timeStamp)
    })
    .then(csvObject => {
      log.info('FileName: ', csvObject.csvFileName)
      return csvObject.csvFileName
    })
    .then(fileName => canvasApi.sendCsvFile(fileName))
    .then(canvasReturnValue => {
      let documentId = sisCourseCode + '.' + timeStamp
      let document = {id: documentId, msg: msg, resp: canvasReturnValue}
      let collectionUrl = `dbs/${lmsDatabase}/colls/${lmsCollection}`
      return cl.cloudCreateDocument(document, collectionUrl)
    })
    .catch(err => {
      if (err.statusCode === 404) {
        log.info('Course does not exist in canvas, skipping, '.red + sisCourseCode.red)
        return Promise.resolve('Course does not exist in canvas')
      } else {
        return Promise.reject(Error(err))
      }
    })
}

module.exports = function (msg, counter) {
  log.info('\nProcessing for msg..... ' + msg.ug1Name)
  var msgtype = msg._desc.userType
  if (msg._desc && (msgtype === type.students || msgtype === type.teachers || msgtype === type.assistants)) {
    return _process(msg)
  } else {
    log.error('\nThis is something else than students, teacher, assistant, we can probably wait with this until the students is handled', JSON.stringify(msg, null, 4))
    return Promise.resolve('Unknown flag: ' + msgtype)
  }
}
<commit_msg>removed json parse<commit_after>'use strict'

const {type} = require('message-type')
const canvasApi = require('../canvasApi')
const Promise = require('bluebird')
const cl = require('../azureStorage')
const config = require('../server/init/configuration')
const log = require('../server/init/logging')
require('colors')

const csvVol = config.secure.azure.csvBlobName
const msgVol = config.secure.azure.msgBlobName
const csvDir = config.secure.localFile.csvDir
const lmsDatabase = config.secure.azure.databaseName
const lmsCollection = config.secure.azure.collectionName

function _createCsvFile (msg, sisCourseCode, timeStamp) {
  let header = 'course_id,user_id,role,status\n'
  let msgtype = msg._desc.userType
  let csvFileName = 'enrollments.' + msgtype + '.' + sisCourseCode + '.' + timeStamp + '.csv'
  let msgFileName = 'enrollments.' + msgtype + '.' + sisCourseCode + '.' + timeStamp + '.msg'
  let csvString = ''

  if (msg.member && msg.member.length > 0) {
    let csvArray = msg.member.map(user => {
      return {
        course_id: sisCourseCode,
        user_id: user,
        role: msgtype,
        status: 'active'
      }
    })
    csvArray.forEach(csvRow => {
      csvString = csvString + `${csvRow.course_id},${csvRow.user_id},${csvRow.role},${csvRow.status}
`
    })
  }

  let csvData = header + csvString
  log.info('\nGoing to open file: ' + csvFileName + ' ' + msgFileName)
  return cl.cloudStoreTextToFile(csvFileName, csvVol, csvData)
  .then(result => { log.info(result); return cl.cloudStoreTextToFile(msgFileName, msgVol, JSON.stringify(msg, null, 4)) })
  .then(() => cl.cloudgetFile(csvFileName, csvVol, csvDir))
  .then(result => { log.info(result); return {csvContent: csvData, csvFileName: csvDir + result.name} })
  .catch(error => { log.error(error); return Promise.reject(error) })
}

function _parseKeyStudent (key) {
  // ladok2.kurser.DM.2517.registrerade_20162.1
  let course = null
  let termin = null
  let year = null
  let ladok = null
  let myRe = /^(\w+).(\w+).(\w+).(\w+).(\w+)_(\d\d)(\d\d)(\d).(\d+)/g
  let myArray = myRe.exec(key)
  if (myArray != null) {
    let courseInOne = 3
    let courseInTwo = 4
    let terminIn = 8
    let yearIn = 7
    let ladokIn = 9
    course = myArray[courseInOne] + myArray[courseInTwo]
    termin = myArray[terminIn] === 1 ? 'VT' : 'HT'
    year = myArray[yearIn]
    ladok = myArray[ladokIn]
    let sisCourseCode = course + termin + year + ladok
    return sisCourseCode
  }
  return
}

function _parseKeyTeacher (key) {
   // edu.courses.AE.AE2302.20162.1.teachers edu.courses.DD.DD1310.20162.1.assistants
  let course = null
  let termin = null
  let year = null
  let ladok = null
  let courseIn = 2
  let terminIn = 5
  let yearIn = 4
  let ladokIn = 6

  let myRe = /^edu.courses.(\w+).(\w+).(\d\d)(\d\d)(\d).(\d).(\w+)$/g
  let myArray = myRe.exec(key)
  if (myArray != null) {
    course = myArray[courseIn]
    termin = myArray[terminIn] === 1 ? 'VT' : 'HT'
    year = myArray[yearIn]
    ladok = myArray[ladokIn]
    let sisCourseCode = course + termin + year + ladok
    return sisCourseCode
  }
  return
}

function _parseKey (key, msgtype) {
  let sisCourseCode = 0
  if (msgtype === type.students) {
    sisCourseCode = _parseKeyStudent(key)
  }
  if (msgtype === type.teachers || msgtype === type.assistants) {
    sisCourseCode = _parseKeyTeacher(key)
  }
  if (!sisCourseCode) {
    log.error('\nCourse code not parsable from Key. type, ' + msgtype + ' key, ' + key)
    return Promise.reject(Error('Key parse error, type, ' + msgtype + ' key, ' + key))
  }
  return Promise.resolve(sisCourseCode)
}

function _process (msg) {
  let sisCourseCode = ''
  let timeStamp = Date.now()

  return _parseKey(msg.ug1Name, msg._desc.userType)
    .then(sisCode => {
      sisCourseCode = sisCode
      log.info(`In _process ${sisCourseCode}, processing for ${msg._desc.userType}`)
      return canvasApi.findCourse(sisCourseCode)
    })
    .then(result => {
      log.info(result)
      return _createCsvFile(msg, sisCourseCode, timeStamp)
    })
    .then(csvObject => {
      log.info('FileName: ', csvObject.csvFileName)
      return csvObject.csvFileName
    })
    .then(fileName => canvasApi.sendCsvFile(fileName))
    .then(canvasReturnValue => {
      let documentId = sisCourseCode + '.' + timeStamp
      let document = {id: documentId, msg: msg, resp: canvasReturnValue}
      let collectionUrl = `dbs/${lmsDatabase}/colls/${lmsCollection}`
      return cl.cloudCreateDocument(document, collectionUrl)
    })
    .catch(err => {
      if (err.statusCode === 404) {
        log.info('Course does not exist in canvas, skipping, '.red + sisCourseCode.red)
        return Promise.resolve('Course does not exist in canvas')
      } else {
        return Promise.reject(Error(err))
      }
    })
}

module.exports = function (msg, counter) {
  log.info('\nProcessing for msg..... ' + msg.ug1Name)
  var msgtype = msg._desc.userType
  if (msg._desc && (msgtype === type.students || msgtype === type.teachers || msgtype === type.assistants)) {
    return _process(msg)
  } else {
    log.error('\nThis is something else than students, teacher, assistant, we can probably wait with this until the students is handled', JSON.stringify(msg, null, 4))
    return Promise.resolve('Unknown flag: ' + msgtype)
  }
}
<|endoftext|>