<commit_before>import $ from '../../utils/dom';
import Utils from '../../utils/utils';

const Lazy = {
  loadImagesInSlide(index, loadInDuplicate = true) {
    const swiper = this;
    const params = swiper.params.lazy;
    if (typeof index === 'undefined') return;
    if (swiper.slides.length === 0) return;

    const $slideEl = swiper.slides.eq(index);
    let $images = $slideEl.find(`.${params.elementClass}:not(.${params.loadedClass}):not(.${params.loadingClass})`);
    if ($slideEl.hasClass(params.elementClass) && !$slideEl.hasClass(params.loadedClass) && !$slideEl.hasClass(params.loadingClass)) {
      $images = $images.add($slideEl[0]);
    }
    if ($images.length === 0) return;

    $images.each((imageIndex, imageEl) => {
      const $imageEl = $(imageEl);
      $imageEl.addClass(params.loadingClass);

      const background = $imageEl.attr('data-background');
      const src = $imageEl.attr('data-src');
      const srcset = $imageEl.attr('data-srcset');
      const sizes = $imageEl.attr('data-sizes');

      swiper.loadImage($imageEl[0], (src || background), srcset, sizes, false, () => {
        if (typeof swiper === 'undefined' || swiper === null || !swiper) return;
        if (background) {
          $imageEl.css('background-image', `url("${background}")`);
          $imageEl.removeAttr('data-background');
        } else {
          if (srcset) {
            $imageEl.attr('srcset', srcset);
            $imageEl.removeAttr('data-srcset');
          }
          if (sizes) {
            $imageEl.attr('sizes', sizes);
            $imageEl.removeAttr('data-sizes');
          }
          if (src) {
            $imageEl.attr('src', src);
            $imageEl.removeAttr('data-src');
          }
        }

        $imageEl.addClass(params.loadedClass).removeClass(params.loadingClass);
        $slideEl.find(`.${params.preloaderClass}, .${params.preloaderClass}`).remove();
        if (swiper.params.loop && loadInDuplicate) {
          const slideOriginalIndex = $slideEl.attr('data-swiper-slide-index');
          if ($slideEl.hasClass(swiper.params.slideDuplicateClass)) {
            const originalSlide = swiper.$wrapperEl.children(`[data-swiper-slide-index="${slideOriginalIndex}"]:not(.${swiper.params.slideDuplicateClass})`);
            swiper.lazy.loadImagesInSlide(originalSlide.index(), false);
          } else {
            const duplicatedSlide = swiper.$wrapperEl.children(`.${swiper.params.slideDuplicateClass}[data-swiper-slide-index="${slideOriginalIndex}"]`);
            swiper.lazy.loadImagesInSlide(duplicatedSlide.index(), false);
          }
        }
        swiper.emit('lazyImageReady', $slideEl[0], $imageEl[0]);
      });

      swiper.emit('lazyImageLoad', $slideEl[0], $imageEl[0]);
    });
  },
  load() {
    const swiper = this;
    const { $wrapperEl, params: swiperParams, slides, activeIndex } = swiper;
    const params = swiperParams.lazy;

    let slidesPerView = swiperParams.slidesPerView;
    if (slidesPerView === 'auto') {
      slidesPerView = 0;
    }

    if (!swiper.lazy.initialImageLoaded) swiper.lazy.initialImageLoaded = true;
    if (swiper.params.watchSlidesVisibility) {
      $wrapperEl.children(`.${swiperParams.slideVisibleClass}`).each((index, slideEl) => {
        swiper.lazy.loadImagesInSlide($(slideEl).index());
      });
    } else if (slidesPerView > 1) {
      for (let i = activeIndex; i < activeIndex + slidesPerView; i += 1) {
        if (slides[i]) swiper.lazy.loadImagesInSlide(i);
      }
    } else {
      swiper.lazy.loadImagesInSlide(activeIndex);
    }
    if (params.loadPrevNext) {
      if (slidesPerView > 1 || (params.loadPrevNextAmount && params.loadPrevNextAmount > 1)) {
        const amount = params.loadPrevNextAmount;
        const spv = slidesPerView;
        const maxIndex = Math.min(activeIndex + spv + Math.max(amount, spv), slides.length);
        const minIndex = Math.max(activeIndex - Math.max(spv, amount), 0);
        // Next Slides
        for (let i = activeIndex + slidesPerView; i < maxIndex; i += 1) {
          if (slides[i]) swiper.lazy.loadImagesInSlide(i);
        }
        // Prev Slides
        for (let i = minIndex; i < activeIndex; i += 1) {
          if (slides[i]) swiper.lazy.loadImagesInSlide(i);
        }
      } else {
        const nextSlide = $wrapperEl.children(`.${swiperParams.slideNextClass}`);
        if (nextSlide.length > 0) swiper.lazy.loadImagesInSlide(nextSlide.index());

        const prevSlide = $wrapperEl.children(`.${swiperParams.slidePrevClass}`);
        if (prevSlide.length > 0) swiper.lazy.loadImagesInSlide(prevSlide.index());
      }
    }
  },
};

export default {
  name: 'lazy',
  params: {
    lazy: {
      enabled: true,
      loadPrevNext: false,
      loadPrevNextAmount: 1,
      loadOnTransitionStart: false,

      elementClass: 'swiper-lazy',
      loadingClass: 'swiper-lazy-loading',
      loadedClass: 'swiper-lazy-loaded',
      preloaderClass: 'swiper-lazy-preloader',
    },
  },
  create() {
    const swiper = this;
    Utils.extend(swiper, {
      lazy: {
        initialImageLoaded: false,
        load: Lazy.load.bind(swiper),
        loadImagesInSlide: Lazy.loadImagesInSlide.bind(swiper),
      },
    });
  },
  on: {
    beforeInit() {
      const swiper = this;
      if (swiper.params.preloadImages) swiper.params.preloadImages = false;
    },
    init() {
      const swiper = this;
      if (swiper.params.lazy.enabled && !swiper.params.loop && swiper.params.initialSlide === 0) {
        swiper.lazy.load();
      }
    },
    scroll() {
      const swiper = this;
      if (swiper.params.freeMode && !swiper.params.freeModeSticky) {
        swiper.lazy.load();
      }
    },
    transitionStart() {
      const swiper = this;
      if (swiper.params.lazy.enabled) {
        if (swiper.params.lazy.loadOnTransitionStart || (!swiper.params.lazy.loadOnTransitionStart && !swiper.lazy.initialImageLoaded)) {
          swiper.lazy.load();
        }
      }
    },
    transitionEnd() {
      const swiper = this;
      if (swiper.params.lazy.enabled && !swiper.params.lazy.loadOnTransitionStart) {
        swiper.lazy.load();
      }
    },
  },
};
<commit_msg>Lazy load on resize<commit_after>import $ from '../../utils/dom';
import Utils from '../../utils/utils';

const Lazy = {
  loadImagesInSlide(index, loadInDuplicate = true) {
    const swiper = this;
    const params = swiper.params.lazy;
    if (typeof index === 'undefined') return;
    if (swiper.slides.length === 0) return;

    const $slideEl = swiper.slides.eq(index);
    let $images = $slideEl.find(`.${params.elementClass}:not(.${params.loadedClass}):not(.${params.loadingClass})`);
    if ($slideEl.hasClass(params.elementClass) && !$slideEl.hasClass(params.loadedClass) && !$slideEl.hasClass(params.loadingClass)) {
      $images = $images.add($slideEl[0]);
    }
    if ($images.length === 0) return;

    $images.each((imageIndex, imageEl) => {
      const $imageEl = $(imageEl);
      $imageEl.addClass(params.loadingClass);

      const background = $imageEl.attr('data-background');
      const src = $imageEl.attr('data-src');
      const srcset = $imageEl.attr('data-srcset');
      const sizes = $imageEl.attr('data-sizes');

      swiper.loadImage($imageEl[0], (src || background), srcset, sizes, false, () => {
        if (typeof swiper === 'undefined' || swiper === null || !swiper) return;
        if (background) {
          $imageEl.css('background-image', `url("${background}")`);
          $imageEl.removeAttr('data-background');
        } else {
          if (srcset) {
            $imageEl.attr('srcset', srcset);
            $imageEl.removeAttr('data-srcset');
          }
          if (sizes) {
            $imageEl.attr('sizes', sizes);
            $imageEl.removeAttr('data-sizes');
          }
          if (src) {
            $imageEl.attr('src', src);
            $imageEl.removeAttr('data-src');
          }
        }

        $imageEl.addClass(params.loadedClass).removeClass(params.loadingClass);
        $slideEl.find(`.${params.preloaderClass}, .${params.preloaderClass}`).remove();
        if (swiper.params.loop && loadInDuplicate) {
          const slideOriginalIndex = $slideEl.attr('data-swiper-slide-index');
          if ($slideEl.hasClass(swiper.params.slideDuplicateClass)) {
            const originalSlide = swiper.$wrapperEl.children(`[data-swiper-slide-index="${slideOriginalIndex}"]:not(.${swiper.params.slideDuplicateClass})`);
            swiper.lazy.loadImagesInSlide(originalSlide.index(), false);
          } else {
            const duplicatedSlide = swiper.$wrapperEl.children(`.${swiper.params.slideDuplicateClass}[data-swiper-slide-index="${slideOriginalIndex}"]`);
            swiper.lazy.loadImagesInSlide(duplicatedSlide.index(), false);
          }
        }
        swiper.emit('lazyImageReady', $slideEl[0], $imageEl[0]);
      });

      swiper.emit('lazyImageLoad', $slideEl[0], $imageEl[0]);
    });
  },
  load() {
    const swiper = this;
    const { $wrapperEl, params: swiperParams, slides, activeIndex } = swiper;
    const params = swiperParams.lazy;

    let slidesPerView = swiperParams.slidesPerView;
    if (slidesPerView === 'auto') {
      slidesPerView = 0;
    }

    if (!swiper.lazy.initialImageLoaded) swiper.lazy.initialImageLoaded = true;
    if (swiper.params.watchSlidesVisibility) {
      $wrapperEl.children(`.${swiperParams.slideVisibleClass}`).each((index, slideEl) => {
        swiper.lazy.loadImagesInSlide($(slideEl).index());
      });
    } else if (slidesPerView > 1) {
      for (let i = activeIndex; i < activeIndex + slidesPerView; i += 1) {
        if (slides[i]) swiper.lazy.loadImagesInSlide(i);
      }
    } else {
      swiper.lazy.loadImagesInSlide(activeIndex);
    }
    if (params.loadPrevNext) {
      if (slidesPerView > 1 || (params.loadPrevNextAmount && params.loadPrevNextAmount > 1)) {
        const amount = params.loadPrevNextAmount;
        const spv = slidesPerView;
        const maxIndex = Math.min(activeIndex + spv + Math.max(amount, spv), slides.length);
        const minIndex = Math.max(activeIndex - Math.max(spv, amount), 0);
        // Next Slides
        for (let i = activeIndex + slidesPerView; i < maxIndex; i += 1) {
          if (slides[i]) swiper.lazy.loadImagesInSlide(i);
        }
        // Prev Slides
        for (let i = minIndex; i < activeIndex; i += 1) {
          if (slides[i]) swiper.lazy.loadImagesInSlide(i);
        }
      } else {
        const nextSlide = $wrapperEl.children(`.${swiperParams.slideNextClass}`);
        if (nextSlide.length > 0) swiper.lazy.loadImagesInSlide(nextSlide.index());

        const prevSlide = $wrapperEl.children(`.${swiperParams.slidePrevClass}`);
        if (prevSlide.length > 0) swiper.lazy.loadImagesInSlide(prevSlide.index());
      }
    }
  },
};

export default {
  name: 'lazy',
  params: {
    lazy: {
      enabled: true,
      loadPrevNext: false,
      loadPrevNextAmount: 1,
      loadOnTransitionStart: false,

      elementClass: 'swiper-lazy',
      loadingClass: 'swiper-lazy-loading',
      loadedClass: 'swiper-lazy-loaded',
      preloaderClass: 'swiper-lazy-preloader',
    },
  },
  create() {
    const swiper = this;
    Utils.extend(swiper, {
      lazy: {
        initialImageLoaded: false,
        load: Lazy.load.bind(swiper),
        loadImagesInSlide: Lazy.loadImagesInSlide.bind(swiper),
      },
    });
  },
  on: {
    beforeInit() {
      const swiper = this;
      if (swiper.params.preloadImages) swiper.params.preloadImages = false;
    },
    init() {
      const swiper = this;
      if (swiper.params.lazy.enabled && !swiper.params.loop && swiper.params.initialSlide === 0) {
        swiper.lazy.load();
      }
    },
    scroll() {
      const swiper = this;
      if (swiper.params.freeMode && !swiper.params.freeModeSticky) {
        swiper.lazy.load();
      }
    },
    resize() {
      const swiper = this;
      if (swiper.params.lazy.enabled) {
        swiper.lazy.load();
      }
    },
    transitionStart() {
      const swiper = this;
      if (swiper.params.lazy.enabled) {
        if (swiper.params.lazy.loadOnTransitionStart || (!swiper.params.lazy.loadOnTransitionStart && !swiper.lazy.initialImageLoaded)) {
          swiper.lazy.load();
        }
      }
    },
    transitionEnd() {
      const swiper = this;
      if (swiper.params.lazy.enabled && !swiper.params.lazy.loadOnTransitionStart) {
        swiper.lazy.load();
      }
    },
  },
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { reduxForm } from 'redux-form';
import { createPost } from '../actions/index';
import { Link }  from 'react-router';

class PostsNew extends Component {
  render() {
    const {fields:{title,category,content}, handleSubmit } = this.props;

    return(
      <form onSubmit={handleSubmit(this.props.createPost)}>

Create a New Post

        <div className={`form-group ${title.touched && title.invalid ? "has-danger" : ''}`}>
          Title
          <input type="text" className="form-control" {...title}/>

            {title.touched ? title.error : ""}

        <div className={`form-group ${category.touched && category.invalid ? "has-danger" : ''}`}>
          Categories
          <input type="text" className="form-control" {...category}/>

            {category.touched ? category.error : ""}

        <div className={`form-group ${content.touched && content.invalid ? "has-danger" : ''}`}>
          Content
          <textarea className="form-control" {...content}/>

            {content.touched ? content.error : ""}

        <button type="submit" className="btn btn-primary">Submit</button>
        <Link to="/" className="btn btn-danger">
          Cancel
        </Link>
      </form>
    );
  }
}

// Validation on the form inputs.
function validate(value){
  const error = {};

    if(!value.title){
      error.title = 'Enter a blog title!';

    }

    if(!value.category){
      error.category = 'Enter a category!';
    }

    if(!value.content){
      error.content = 'Type in some content!';
    }
  return error;
}

// Connnect: first arguement is mapStateToProps, Second is mapDispatchToProps.

//reduxForm: 1st is  form config, 2nd is mapStateToProps, 3rd is mapDispatchToProps.

export default reduxForm({
  form: 'PostNew',
  fields:['title', 'category', 'content'],
  validate
}, null, { createPost })(PostsNew);

/// Whenever a user types something in.... record it on app state.
<commit_msg>Feat: Added context to grab routes prop, factored out the onSubmit handler. Now when post is successfully created, send user back to index page<commit_after>import React, { Component, PropTypes } from 'react';
import { reduxForm } from 'redux-form';
import { createPost } from '../actions/index';
import { Link }  from 'react-router';

class PostsNew extends Component {
  static contextTypes = {
    router: PropTypes.object
  }

  onSubmit(props) {
    this.props.createPost(props)
      .then( () => {
        //blog post has been created, navigate user to the index.
        //Navigate by calling this.context.router.push
        //with the new path to navigate to.
        this.context.router.push('/');
      });
  }

  render() {
    const {fields:{title,category,content}, handleSubmit } = this.props;

    return(
      <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>

Create a New Post

        <div className={`form-group ${title.touched && title.invalid ? "has-danger" : ''}`}>
          Title
          <input type="text" className="form-control" {...title}/>

            {title.touched ? title.error : ""}

        <div className={`form-group ${category.touched && category.invalid ? "has-danger" : ''}`}>
          Categories
          <input type="text" className="form-control" {...category}/>

            {category.touched ? category.error : ""}

        <div className={`form-group ${content.touched && content.invalid ? "has-danger" : ''}`}>
          Content
          <textarea className="form-control" {...content}/>

            {content.touched ? content.error : ""}

        <button type="submit" className="btn btn-primary">Submit</button>
        <Link to="/" className="btn btn-danger">
          Cancel
        </Link>
      </form>
    );
  }
}

// Validation on the form inputs.
function validate(value){
  const error = {};

    if(!value.title){
      error.title = 'Enter a blog title!';

    }

    if(!value.category){
      error.category = 'Enter a category!';
    }

    if(!value.content){
      error.content = 'Type in some content!';
    }
  return error;
}

// Connnect: first arguement is mapStateToProps, Second is mapDispatchToProps.

//reduxForm: 1st is  form config, 2nd is mapStateToProps, 3rd is mapDispatchToProps.

export default reduxForm({
  form: 'PostNew',
  fields:['title', 'category', 'content'],
  validate
}, null, { createPost })(PostsNew);

/// Whenever a user types something in.... record it on app state.
<|endoftext|>


<commit_before>import React, { Component } from 'react';

const UserList = (props) => {
  const users = props.users.map((user) => {
    return (

{ `${ user.name.first } ${ user.name.last }`}

{ `DOB: ${ user.dob }` }

{ `City: ${ user.location.city  }` }

    );
  });

  return (

      { users }

  )
}

export default UserList;<commit_msg>render by group instead of user sort group by name<commit_after>import React, { PropTypes } from 'react';
import  { groupUsersByName } from '../filters/filters';
import UserGroup from './user_group';

const UserList = ({ list }) => {
  const groups = groupUsersByName(list);

  const groupAndSortByName = Object.keys(groups)
    .sort()
    .map((letter) => {
      return (

          <UserGroup groups={ groups[letter] } letter={ letter } />

      );
  });

  return (

      { groupAndSortByName }

  );
};

UserList.propTypes = {
  list: PropTypes.array.isRequired
};

export default UserList;<|endoftext|>


<commit_before>import { ref, computed, isRef, nextTick } from "vue";
import { IMAGE_POLL_INTERVAL, IMAGE_ASPECT_RATIO } from "../constants";

export const useImage = (element) => {
  const image = new Image();
  const width = ref(0);
  const height = ref(0);

  const aspectRatio = computed(() => {
    return width.value ? height.value / width.value : IMAGE_ASPECT_RATIO;
  });

  const pollImageData = setInterval(() => {
    if (image && image.width) {
      clearInterval(pollImageData);

      width.value = image.width;
      height.value = image.height;
    }
  }, IMAGE_POLL_INTERVAL);

  const imageRenderer = (imageNode) => {
    const canvas = document.createElement("canvas");

    canvas.setAttribute("hidden", true);
    canvas.setAttribute("data-src", imageNode.src);
    canvas.width = 1;
    canvas.height = 1;

    document.body.appendChild(canvas);

    canvas.getContext("2d").drawImage(imageNode, 0, 0);

    document.body.removeChild(canvas);
  };

  const loadImage = () => {
    const imageNode = isRef(element) ? element.value : element;
    const src = imageNode.src;

    image.src = src;

    if (image.complete) {
      return Promise.resolve();
    }

    return new Promise((resolve, reject) => {
      image.onload = () => {
        imageRenderer(imageNode);
        nextTick(resolve);
      };

      image.onerror = reject;
    });
  };

  return {
    width,
    height,
    aspectRatio,
    loadImage,
  };
};

export default useImage;
<commit_msg>chore: remove canvas attribute<commit_after>import { ref, computed, isRef, nextTick } from "vue";
import { IMAGE_POLL_INTERVAL, IMAGE_ASPECT_RATIO } from "../constants";

export const useImage = (element) => {
  const image = new Image();
  const width = ref(0);
  const height = ref(0);

  const aspectRatio = computed(() => {
    return width.value ? height.value / width.value : IMAGE_ASPECT_RATIO;
  });

  const pollImageData = setInterval(() => {
    if (image && image.width) {
      clearInterval(pollImageData);

      width.value = image.width;
      height.value = image.height;
    }
  }, IMAGE_POLL_INTERVAL);

  const imageRenderer = (imageNode) => {
    const canvas = document.createElement("canvas");

    canvas.width = 1;
    canvas.height = 1;

    canvas.setAttribute("hidden", true);

    document.body.appendChild(canvas);

    canvas.getContext("2d").drawImage(imageNode, 0, 0);

    document.body.removeChild(canvas);
  };

  const loadImage = () => {
    const imageNode = isRef(element) ? element.value : element;
    const src = imageNode.src;

    image.src = src;

    if (image.complete) {
      return Promise.resolve();
    }

    return new Promise((resolve, reject) => {
      image.onload = () => {
        imageRenderer(imageNode);
        nextTick(resolve);
      };

      image.onerror = reject;
    });
  };

  return {
    width,
    height,
    aspectRatio,
    loadImage,
  };
};

export default useImage;
<|endoftext|>


<commit_before>import React from 'react'
import parse from 'url-parse'
import {
  visit,
  remote,
  setInPage,
  delInPage,
  extendInPage,
  setInJoint,
  delInJoint,
  extendInJoint,
} from '../action_creators'
import {withoutBZParams} from './url'
import PropTypes from 'prop-types'

export class Nav extends React.Component {
  constructor (props) {
    super(props)
    this.navigateTo = this.navigateTo.bind(this)

    if (this.props.history) {
      this.history = this.props.history
      this.onHistoryChange = this.onHistoryChange.bind(this)
      this.unsubscribeHistory = this.history.listen(this.onHistoryChange)
    }
    this.mapping = props.mapping
    this.state = this.props.initialState || {}
  }

  navigateTo (screen, pageKey, {action} = {action: 'push'}) {
    pageKey = withoutBZParams(pageKey)
    if (this.history) {
      const historyArgs = [pageKey, {
        screen,
        pageKey,
        breezy: true
      }]

      if(action === 'push') {
        this.history.push(...historyArgs)
      }

      if(action === 'replace') {
        const {store} = this.context
        const oldPageKey = history.location.state.pageKey
        this.history.replace(...historyArgs)
        store.dispatch({type: 'BREEZY_REMOVE_PAGE', pageKey: oldPageKey})
      }
    }

    this.setState({pageKey, screen})
  }

  onHistoryChange (location, action) {
    const {store} = this.context
    if (store) {
      store.dispatch({
        type: 'BREEZY_HISTORY_CHANGE',
        url: parse(location.pathname).href
      })
    }

    if (action === 'POP') {
      const {screen, pageKey} = location.state
      const wasNotRefreshed = !!store.getState().pages[pageKey]

      if(location.state && location.state.breezy && wasNotRefreshed) {
        this.setState({screen, pageKey})
      } else {
        // load previous page
        window.location = location.pathname
      }
    }
  }

  notFound (screen) {
    const {store} = this.context
    store.dispatch({type: 'BREEZY_ERROR', message: `Could not find screen ${screen}`})
    throw new Error(`Breezy Nav component was looking for ${screen} but could not find it in your mapping.`)
  }

  render () {
    const Component = this.mapping[this.state.screen]

    if (Component) {
      return <Component pageKey={this.state.pageKey} navigateTo={this.navigateTo} />
    } else {
      this.notFound(this.state.screen)
    }
  }
}

Nav.contextTypes = {store: PropTypes.object}

export function mapStateToProps (state = {pages:{}, breezy: {}}, ownProps) {
  let pageKey
  // support for react navigation
  let params
  if (ownProps.navigation && ownProps.navigation.state && ownProps.navigation.state.params &&  ownProps.navigation.state.params.pageKey && !pageKey) {
    pageKey = ownProps.navigation.state.params.pageKey
    params = ownProps.navigation.state.params
  } else {
    pageKey = ownProps.pageKey
    params = ownProps
  }
  const csrfToken = state.breezy.csrfToken
  pageKey = withoutBZParams(pageKey)
  const {data} = state.pages[pageKey] || {data:{}}
  return {...data, ...params, pageKey, csrfToken}
}

export const mapDispatchToProps = {
  visit,
  remote,
  setInPage,
  delInPage,
  extendInPage,
  setInJoint,
  delInJoint,
  extendInJoint,
}

export function withBrowserBehavior (visit, remote) {
  const wrappedVisit = (function (...args) {
    return visit(...args).then(rsp => {
      if (rsp.needsRefresh) {
        window.location = rsp.url
        return
      }

      if (rsp.canNavigate) {
        return this.props.navigateTo(rsp.screen, rsp.pageKey)
      } else {
        // There can only be one visit at a time, if `canNavigate`
        // is false, then this request is being ignored for a more
        // recent visit. Do Nothing.
        console.info('\
          `visit` was called more recently somewhere else.\
          The results of this request have been saved to \
          the store, but no navigation will take place')
        return
      }
    }).catch(err => {
      const response = err.response
      if(response.ok) {
        // err gets thrown, but if the response is ok,
        // it must be an html body that
        // breezy can't parse, just go to the location
        window.location = response.url
      } else {

        if (response.status >= 400 && response.status < 500) {
          window.location = '/400.html'
          return
        }

        if (response.status >= 500) {
          window.location = '/500.html'
          return
        }
      }
    })
  })

  const wrappedRemote = (function (...args) {
    if (args.length == 1) {
      args.push(undefined)
    }

    return remote(...args, this.props.pageKey)
  })

  return {visit: wrappedVisit, remote: wrappedRemote}
}
<commit_msg>Add reminder test to error message<commit_after>import React from 'react'
import parse from 'url-parse'
import {
  visit,
  remote,
  setInPage,
  delInPage,
  extendInPage,
  setInJoint,
  delInJoint,
  extendInJoint,
} from '../action_creators'
import {withoutBZParams} from './url'
import PropTypes from 'prop-types'

export class Nav extends React.Component {
  constructor (props) {
    super(props)
    this.navigateTo = this.navigateTo.bind(this)

    if (this.props.history) {
      this.history = this.props.history
      this.onHistoryChange = this.onHistoryChange.bind(this)
      this.unsubscribeHistory = this.history.listen(this.onHistoryChange)
    }
    this.mapping = props.mapping
    this.state = this.props.initialState || {}
  }

  navigateTo (screen, pageKey, {action} = {action: 'push'}) {
    pageKey = withoutBZParams(pageKey)
    if (this.history) {
      const historyArgs = [pageKey, {
        screen,
        pageKey,
        breezy: true
      }]

      if(action === 'push') {
        this.history.push(...historyArgs)
      }

      if(action === 'replace') {
        const {store} = this.context
        const oldPageKey = history.location.state.pageKey
        this.history.replace(...historyArgs)
        store.dispatch({type: 'BREEZY_REMOVE_PAGE', pageKey: oldPageKey})
      }
    }

    this.setState({pageKey, screen})
  }

  onHistoryChange (location, action) {
    const {store} = this.context
    if (store) {
      store.dispatch({
        type: 'BREEZY_HISTORY_CHANGE',
        url: parse(location.pathname).href
      })
    }

    if (action === 'POP') {
      const {screen, pageKey} = location.state
      const wasNotRefreshed = !!store.getState().pages[pageKey]

      if(location.state && location.state.breezy && wasNotRefreshed) {
        this.setState({screen, pageKey})
      } else {
        // load previous page
        window.location = location.pathname
      }
    }
  }

  notFound (screen) {
    const {store} = this.context
    store.dispatch({type: 'BREEZY_ERROR', message: `Could not find screen ${screen}`})
    let reminder
    if (!screen) {
      reminder = 'Did you forget to use_breezy in your controllers?'
    }
    throw new Error(`Breezy Nav component was looking for ${screen} but could not find it in your mapping. ${reminder}`)
  }

  render () {
    const Component = this.mapping[this.state.screen]

    if (Component) {
      return <Component pageKey={this.state.pageKey} navigateTo={this.navigateTo} />
    } else {
      this.notFound(this.state.screen)
    }
  }
}

Nav.contextTypes = {store: PropTypes.object}

export function mapStateToProps (state = {pages:{}, breezy: {}}, ownProps) {
  let pageKey
  // support for react navigation
  let params
  if (ownProps.navigation && ownProps.navigation.state && ownProps.navigation.state.params &&  ownProps.navigation.state.params.pageKey && !pageKey) {
    pageKey = ownProps.navigation.state.params.pageKey
    params = ownProps.navigation.state.params
  } else {
    pageKey = ownProps.pageKey
    params = ownProps
  }
  const csrfToken = state.breezy.csrfToken
  pageKey = withoutBZParams(pageKey)
  const {data} = state.pages[pageKey] || {data:{}}
  return {...data, ...params, pageKey, csrfToken}
}

export const mapDispatchToProps = {
  visit,
  remote,
  setInPage,
  delInPage,
  extendInPage,
  setInJoint,
  delInJoint,
  extendInJoint,
}

export function withBrowserBehavior (visit, remote) {
  const wrappedVisit = (function (...args) {
    return visit(...args).then(rsp => {
      if (rsp.needsRefresh) {
        window.location = rsp.url
        return
      }

      if (rsp.canNavigate) {
        return this.props.navigateTo(rsp.screen, rsp.pageKey)
      } else {
        // There can only be one visit at a time, if `canNavigate`
        // is false, then this request is being ignored for a more
        // recent visit. Do Nothing.
        console.info('\
          `visit` was called more recently somewhere else.\
          The results of this request have been saved to \
          the store, but no navigation will take place')
        return
      }
    }).catch(err => {
      const response = err.response
      if(response.ok) {
        // err gets thrown, but if the response is ok,
        // it must be an html body that
        // breezy can't parse, just go to the location
        window.location = response.url
      } else {

        if (response.status >= 400 && response.status < 500) {
          window.location = '/400.html'
          return
        }

        if (response.status >= 500) {
          window.location = '/500.html'
          return
        }
      }
    })
  })

  const wrappedRemote = (function (...args) {
    if (args.length == 1) {
      args.push(undefined)
    }

    return remote(...args, this.props.pageKey)
  })

  return {visit: wrappedVisit, remote: wrappedRemote}
}
<|endoftext|>


<commit_before>const {dirname, resolve} = require("path");

const isLocal = s => s.trim()[0] === ".";

const createPlugin = (defaultOptions = {}) => babel => {
    const {types: t} = babel;
    var componentCreatorNames = null;

    const addCreatorName = name => {
        if (!componentCreatorNames) {
            componentCreatorNames = {};
        }
        componentCreatorNames[name] = true;
    };

    const isComponentCreator = (importedName, path, state) => {
        var modules = state.opts.modules;

        modules = Object.assign({}, defaultOptions.modules, modules);

        const importDeclaration = path.findParent(p => t.isImportDeclaration(p.node));
        const moduleString = importDeclaration.node.source.value;

        if (!isLocal(moduleString)) {
            return modules[moduleString] && modules[moduleString][importedName];
        }

        const sourcePath = resolve(dirname(state.file.opts.filename), moduleString);
        const sourceRoot = state.file.opts.sourceRoot || process.cwd();

        const localModuleString = Object.keys(modules).find(configPath => {
            if (isLocal(configPath)) {
                const fullConfigPath = resolve(sourceRoot, configPath);
                return fullConfigPath === sourcePath;
            }
        });

        return modules[localModuleString] && modules[localModuleString][importedName];
    };

    return {
        visitor: {
            Program() {
                componentCreatorNames = null;
            },

            ImportSpecifier(path, state) {
                if (isComponentCreator(path.node.imported.name, path, state)) {
                    addCreatorName(path.node.local.name);
                }
            },

            ImportDefaultSpecifier(path, state) {
                if (isComponentCreator("default", path, state)) {
                    addCreatorName(path.node.local.name);
                }
            },

            VariableDeclaration(path) {
                if (!componentCreatorNames) return;

                if (!path.node.declarations[0].init) return;
                if (path.node.declarations[0].init.type !== "CallExpression") return;

                const creatorName = path.node.declarations[0].init.callee.name;

                if (!componentCreatorNames[creatorName]) return;

                var scope = path.scope;
                var usingImportedCreator = false;

                while (scope) {
                    if (scope.bindings[creatorName]) {
                        usingImportedCreator = scope.bindings[creatorName].kind === "module";
                        break;
                    }
                    scope = scope.parent;
                }

                if (!usingImportedCreator) return;

                const name = path.node.declarations[0].id.name;

                var sibling = path;

                if (path.parent.type === "ExportNamedDeclaration") {
                    sibling = path.findParent(p => p.node === path.parent);
                }

                const left = t.memberExpression(t.identifier(name), t.identifier("displayName"));
                const right = t.stringLiteral(name);

                sibling.insertAfter(
                    t.expressionStatement(t.assignmentExpression("=", left, right)),
                );
            },
        },
    };
};

const plugin = createPlugin();
plugin.createPlugin = createPlugin;
module.exports = plugin;
<commit_msg>Fix traling comma<commit_after>const {dirname, resolve} = require("path");

const isLocal = s => s.trim()[0] === ".";

const createPlugin = (defaultOptions = {}) => babel => {
    const {types: t} = babel;
    var componentCreatorNames = null;

    const addCreatorName = name => {
        if (!componentCreatorNames) {
            componentCreatorNames = {};
        }
        componentCreatorNames[name] = true;
    };

    const isComponentCreator = (importedName, path, state) => {
        var modules = state.opts.modules;

        modules = Object.assign({}, defaultOptions.modules, modules);

        const importDeclaration = path.findParent(p => t.isImportDeclaration(p.node));
        const moduleString = importDeclaration.node.source.value;

        if (!isLocal(moduleString)) {
            return modules[moduleString] && modules[moduleString][importedName];
        }

        const sourcePath = resolve(dirname(state.file.opts.filename), moduleString);
        const sourceRoot = state.file.opts.sourceRoot || process.cwd();

        const localModuleString = Object.keys(modules).find(configPath => {
            if (isLocal(configPath)) {
                const fullConfigPath = resolve(sourceRoot, configPath);
                return fullConfigPath === sourcePath;
            }
        });

        return modules[localModuleString] && modules[localModuleString][importedName];
    };

    return {
        visitor: {
            Program() {
                componentCreatorNames = null;
            },

            ImportSpecifier(path, state) {
                if (isComponentCreator(path.node.imported.name, path, state)) {
                    addCreatorName(path.node.local.name);
                }
            },

            ImportDefaultSpecifier(path, state) {
                if (isComponentCreator("default", path, state)) {
                    addCreatorName(path.node.local.name);
                }
            },

            VariableDeclaration(path) {
                if (!componentCreatorNames) return;

                if (!path.node.declarations[0].init) return;
                if (path.node.declarations[0].init.type !== "CallExpression") return;

                const creatorName = path.node.declarations[0].init.callee.name;

                if (!componentCreatorNames[creatorName]) return;

                var scope = path.scope;
                var usingImportedCreator = false;

                while (scope) {
                    if (scope.bindings[creatorName]) {
                        usingImportedCreator = scope.bindings[creatorName].kind === "module";
                        break;
                    }
                    scope = scope.parent;
                }

                if (!usingImportedCreator) return;

                const name = path.node.declarations[0].id.name;

                var sibling = path;

                if (path.parent.type === "ExportNamedDeclaration") {
                    sibling = path.findParent(p => p.node === path.parent);
                }

                const left = t.memberExpression(t.identifier(name), t.identifier("displayName"));
                const right = t.stringLiteral(name);

                sibling.insertAfter(
                    t.expressionStatement(t.assignmentExpression("=", left, right))
                );
            },
        },
    };
};

const plugin = createPlugin();
plugin.createPlugin = createPlugin;
module.exports = plugin;
<|endoftext|>


<commit_before>#!/usr/bin/env node
var VERSION = "v0.0.9";

var fs = require('fs');
var os = require('os');
var path = require('path');
var Zip = require('./extern/adm-zip/adm-zip.js');
var process = require('process');
var querystring = require('querystring');
var child_process = require('child_process');

var parseCLI = require('./base/cli/cliParser.js');
var coreHttp = require('./base/core/httpUtils.js');
var CURRENT = process.cwd();
var TARGET = require('./base/compiler/target.js');
var PLATFORM = os.platform();
var ARCH = os.arch();

var CLI = parseCLI(process.argv);

if(CLI.error)
{
  console.log(CLI.msg);
  return;
}

var ACTION = "build";
if(CLI.cli["--help"] || CLI.cli["-h"]) ACTION = "help";
else if(CLI.cli['--version'] || CLI.cli["-v"]) ACTION = "version";

switch(ACTION)
{
  case "version":
    console.log("Nectar " + VERSION);
    break;

  case "help":
    Help();
    break;

  case "build":
    Build(CLI);
    break;

  default:
    Help();
    break;
}

function Build()
{
  var target;
  var preset;
  if(CLI.cli["--target"] && CLI.cli["--target"].argument) target = CLI.cli["--target"].argument;
  if(CLI.cli["--preset"] && CLI.cli["--preset"].argument) preset = CLI.cli["--preset"].argument;

  if(!target)
  {
    switch(PLATFORM)
    {
      case "linux":
        if(ARCH == "x64") target = "linux-x86-32";
        else if(ARCH == "x32") target = "linux-x86-64";
        else if(ARCH == "arm") target = "linux-arm32v7";
        break;

      case "win32":
        if(ARCH == "x64") target = "win-x86-32";
        else if(ARCH == "x32") target = "win-x86-64";
        break;

      default:
        target = "null";
        break;
    }
  }

  if(!preset) preset = "speed";

  if(!CLI.stack || CLI.stack.length < 1)
  {
    console.log("Missing file to compile");
    return;
  }
  else if(!target || TARGET.indexOf(target) < 0)
  {
    console.log("\nBad target");
    Help();
    return;
  }
  else
  {
    var fName = CLI.stack[CLI.stack.length - 1];

    fs.readFile(fName, function(err, data)
    {
      if(err)
      {
        console.log("Error : " + err);
        return;
      }
      else
      {
          var zipFolder = fName.split(path.sep);
          var main = fName.split(path.sep);
          main = main[main.length - 1];
          zipFolder = zipFolder.slice(0, zipFolder.length - 1).join(path.sep) + path.sep;
          fs.writeFileSync(zipFolder + path.sep + "project.json", '{"main": "' + main + '", "target":"' + target + '", "preset":"' + preset + '"}');
          var zip = new Zip();
          zip.addLocalFolder(zipFolder);
          var zipBuffer = Buffer.from(zip.toBuffer()).toString("base64");

          var data = "{ \"project\" : \"" + zipBuffer + "\"}";

          var apiOption =
          {
            port: 8080,
            hostname: "api.nectarjs.com",
            method: "POST",
            path: "/compile/" + "project" + "/",
            data: data,
          };

          function Compiled(data)
          {
            var result = JSON.parse(data);
            if(result.success == false)
            {
              console.log(result.message);
            }
            else
            {
              var bin;
              if (typeof Buffer.from === "function")
              {
                  bin = Buffer.from(result.data, 'base64');
              }
              else
              {
                  bin = new Buffer(result.data, 'base64');
              }
              var tmp = fName.split("/");
              var to = "";
              if(CLI.cli["-o"])
              {
                to = CLI.cli["-o"].argument;
              }
              else
              {
                var end = ".bin";
                if(PLATFORM == "win32") end = ".exe";
                to = tmp[tmp.length-1].split(".")[0] + end;
              }
              fs.writeFile(to, bin, function(err, data)
              {
                if(err)
                {
                  console.log(err);
                }
                else
                {
                  if(CLI.cli["--run"])
                  {
                    if(PLATFORM == "win32")
                    {
                      console.log(child_process.execSync(to).toString());
                    }
                    else
                    {
                      child_process.execSync("chmod +x " + to);
                      console.log(child_process.execSync("." + path.sep + to).toString());
                    }
                  }
                }
              });
            }
          }
          coreHttp.httpUtil.httpReq(apiOption, function(err){console.log(err);}, Compiled)
      }
    });
  }
}

function Help()
{
  console.log("\nnectar [--target the_target] [--run] source.js\n");
  console.log("Targets :");
  for(var i = 0; i < TARGET.length; i++)
  {
    console.log("-> " + TARGET[i]);
  }
  console.log();
}
<commit_msg>Updated<commit_after>#!/usr/bin/env node
var VERSION = "0.0.9";

var fs = require('fs');
var os = require('os');
var path = require('path');
var Zip = require('./extern/adm-zip/adm-zip.js');
var process = require('process');
var querystring = require('querystring');
var child_process = require('child_process');

var parseCLI = require('./base/cli/cliParser.js');
var coreHttp = require('./base/core/httpUtils.js');
var CURRENT = process.cwd();
var TARGET = require('./base/compiler/target.js');
var PLATFORM = os.platform();
var ARCH = os.arch();

var CLI = parseCLI(process.argv);

if(CLI.error)
{
  console.log(CLI.msg);
  return;
}

var ACTION = "build";
if(CLI.cli["--help"] || CLI.cli["-h"]) ACTION = "help";
else if(CLI.cli['--version'] || CLI.cli["-v"]) ACTION = "version";

switch(ACTION)
{
  case "version":
    console.log("Nectar v" + VERSION);
    break;

  case "help":
    Help();
    break;

  case "build":
    Build(CLI);
    break;

  default:
    Help();
    break;
}

function Build()
{
  var target;
  var preset;
  if(CLI.cli["--target"] && CLI.cli["--target"].argument) target = CLI.cli["--target"].argument;
  if(CLI.cli["--preset"] && CLI.cli["--preset"].argument) preset = CLI.cli["--preset"].argument;

  if(!target)
  {
    switch(PLATFORM)
    {
      case "linux":
        if(ARCH == "x64") target = "linux-x86-32";
        else if(ARCH == "x32") target = "linux-x86-64";
        else if(ARCH == "arm") target = "linux-arm32v7";
        break;

      case "win32":
        if(ARCH == "x64") target = "win-x86-32";
        else if(ARCH == "x32") target = "win-x86-64";
        break;

      default:
        target = "null";
        break;
    }
  }

  if(!preset) preset = "speed";

  if(!CLI.stack || CLI.stack.length < 1)
  {
    console.log("Missing file to compile");
    return;
  }
  else if(!target || TARGET.indexOf(target) < 0)
  {
    console.log("\nBad target");
    Help();
    return;
  }
  else
  {
    var fName = CLI.stack[CLI.stack.length - 1];

    fs.readFile(fName, function(err, data)
    {
      if(err)
      {
        console.log("Error : " + err);
        return;
      }
      else
      {
          var zipFolder = fName.split(path.sep);
          var main = fName.split(path.sep);
          main = main[main.length - 1];
          zipFolder = zipFolder.slice(0, zipFolder.length - 1).join(path.sep) + path.sep;
          fs.writeFileSync(zipFolder + path.sep + "project.json", '{"main": "' + main + '", "target":"' + target + '", "preset":"' + preset + '"}');
          var zip = new Zip();
          zip.addLocalFolder(zipFolder);
          var zipBuffer = Buffer.from(zip.toBuffer()).toString("base64");

          var data = '{ "project" : "' + zipBuffer + '", "version":"' + VERSION + '"}';

          var apiOption =
          {
            port: 8080,
            hostname: "api.nectarjs.com",
            method: "POST",
            path: "/compile/" + "project" + "/",
            data: data,
          };

          function Compiled(data)
          {
            var result = JSON.parse(data);
            if(result.success == false)
            {
              console.log(result.message);
            }
            else
            {
              var bin;
              if (typeof Buffer.from === "function")
              {
                  bin = Buffer.from(result.data, 'base64');
              }
              else
              {
                  bin = new Buffer(result.data, 'base64');
              }
              var tmp = fName.split("/");
              var to = "";
              if(CLI.cli["-o"])
              {
                to = CLI.cli["-o"].argument;
              }
              else
              {
                var end = ".bin";
                if(PLATFORM == "win32") end = ".exe";
                to = tmp[tmp.length-1].split(".")[0] + end;
              }
              fs.writeFile(to, bin, function(err, data)
              {
                if(err)
                {
                  console.log(err);
                }
                else
                {
                  if(CLI.cli["--run"])
                  {
                    if(PLATFORM == "win32")
                    {
                      console.log(child_process.execSync(to).toString());
                    }
                    else
                    {
                      child_process.execSync("chmod +x " + to);
                      console.log(child_process.execSync("." + path.sep + to).toString());
                    }
                  }
                }
              });
            }
          }
          coreHttp.httpUtil.httpReq(apiOption, function(err){console.log(err);}, Compiled)
      }
    });
  }
}

function Help()
{
  console.log("\nnectar [--target the_target] [--run] source.js\n");
  console.log("Targets :");
  for(var i = 0; i < TARGET.length; i++)
  {
    console.log("-> " + TARGET[i]);
  }
  console.log();
}
<|endoftext|>


<commit_before>const format = require("util").format;
const inspect = require("util").inspect;
const Promise = require("bluebird");
const anyRegex = /.*/;
const names = ["nickname", "username", "hostname"];
const adminKeys = names.concat("identifiedas");
// Hostmask :: {nickname: String, username: String, hostname: String}
// Privmsg :: tennu::IRCMessage::Privmsg
// Admin :: {nickname: RegExp, username: RegExp, hostname: RegExp, identifiedas: String?}

function notHasIdentifiedasProperty (admin) {
    return !admin["identifiedas"];
}

function cloneOnlyAdminKeys (object) {
    const clone = {};

    adminKeys.forEach(function (key) {
        clone[key] = object[key];
    });

    return clone;
}

module.exports = AdminModule = {
    init: function (client, imports) {
        const isIdentifiedAs = imports.user.isIdentifiedAs;
        var admins;

        const deniedResponse = (client.config("admin-failed-attempt-response") || "Permission denied.");
        const forcedAdminCommands = client.config("admin-commands") || [];

        // tennu.Client! -> {nickname: String?, username: String?, hostname: String?, identifiedas: String?} -> Admin
        function regexify (admin) {
            client.note("PluginAdmin", format("Adding admin: %j", admin));

            names.forEach(function (name) {
                if (admin[name]) {
                    admin[name] = new RegExp(admin[name], "i");
                } else {
                    admin[name] = anyRegex;
                }
            });

            return admin;
        }

        // tennu.Client! -> [Admin] throws Error
        function initalizeAdmins (adminConfigObject) {

            const admins = adminConfigObject || client.config("admins");

            if (!Array.isArray(admins)) {
                const errormsg = "\"admins\" property in configuration must be an array";
                client.error(errormsg);
                throw new Error(errormsg);
            }

            return admins.map(cloneOnlyAdminKeys).map(regexify);
        }

        // tennu.Client! -> Hostmask -> Admin -> boolean
        function checkHostmask (hostmask, admin) {
            return names.every(function (name) {
                const result = admin[name].test(hostmask[name]);

                client.debug("PluginAdmin", format("%s: %s, %s (%s)",
                    name, hostmask[name], admin[name], result));

                return result;
            });
        }

        // Module Initialization
        admins = initalizeAdmins();

        // Hostmask -> Promise boolean
        const isAdmin = function (hostmask, customAdmins) {
            return Promise.try(function () {
                const hostmask_passed = (customAdmins || admins).filter(function (admin) {
                    return checkHostmask(hostmask, admin);
                });

                if (hostmask_passed.some(notHasIdentifiedasProperty)) {
                    client.debug("PluginAdmin", "Admin object w/o identifiedas property (true)");
                    return true;
                }

                client.debug("PluginAdmin", "Admin object w/o identifiedas property (false)");

                return (function recur () {
                    if (hostmask_passed.length === 0) {
                        client.debug("PluginAdmin", "User passes an identifiedas check (false)");
                        return false;
                    }

                    return Promise.try(function () {
                        const hostmask = hostmask_passed.pop();
                        return hostmask.identifiedas;
                    })
                    .then(function (accountname) {
                        return isIdentifiedAs(hostmask.nickname, accountname);
                    })
                    .then(function (isIdentifiedAs) {
                        if (isIdentifiedAs) {
                            client.debug("PluginAdmin", "User passes an identifiedas check (true)");
                            return true;
                        } else {
                            return recur();
                        }
                    });
                }());
            });
        };

        // (Privmsg -> Response) -> (Privmsg -> Response)
        const requiresAdmin = function (fn) {
            return function (privmsg) {
                return isAdmin(privmsg.hostmask)
                .then(function (isAdmin) {
                    if (isAdmin) {
                        return fn(privmsg);
                    } else {
                        return deniedResponse;
                    }
                });
            };
        };

        // (Privmsg, () -> Response) -> Response
        const checkAdmin = function (privmsg, adminOnlyCallback) {
            return isAdmin(privmsg.hostmask)
            .then(function (isAdmin) {
                if (isAdmin) {
                    return adminOnlyCallback();
                } else {
                    client.note("PluginAdmin", format("'%s' tried to execute admin-only functionality", privmsg.nickname));
                    return deniedResponse;
                }
            });
        }

        return {
            commandMiddleware: function(command) {
                if (forcedAdminCommands.indexOf(command.command) === -1) {
                    return command;
                }

                return isAdmin(command.hostmask)
                .then(function(isAdmin) {
                    if (isAdmin) {
                        return command;
                    }
                    client.note("PluginAdmin", format("'%s' tried to run user-defined admin command '%s'", command.nickname, command.command));
                    return deniedResponse;
                });
            },
            exports: {
                isAdmin: isAdmin,
                checkAdmin: checkAdmin,
                requiresAdmin: requiresAdmin,

                initalizeAdmins: initalizeAdmins,
                regexify: regexify,
                checkHostmask: checkHostmask
            }
        };
    },
    name: "admin",
    role: "admin",
    requires: ["user"]
};<commit_msg>Added: Use whois memoization, Changed: opts into object<commit_after>const format = require("util").format;
const inspect = require("util").inspect;
const Promise = require("bluebird");
const anyRegex = /.*/;
const names = ["nickname", "username", "hostname"];
const adminKeys = names.concat("identifiedas");
// Hostmask :: {nickname: String, username: String, hostname: String}
// Privmsg :: tennu::IRCMessage::Privmsg
// Admin :: {nickname: RegExp, username: RegExp, hostname: RegExp, identifiedas: String?}

function notHasIdentifiedasProperty (admin) {
    return !admin["identifiedas"];
}

function cloneOnlyAdminKeys (object) {
    const clone = {};

    adminKeys.forEach(function (key) {
        clone[key] = object[key];
    });

    return clone;
}

module.exports = AdminModule = {
    configDefaults: {
        "admin-failed-attempt-response": "Permission denied.",
        "admin-commands": []
    },

    init: function (client, imports) {
        const isIdentifiedAs = imports.user.isIdentifiedAs;
        var admins;

        const deniedResponse = client.config("admin-failed-attempt-response");
        const forcedAdminCommands = client.config("admin-commands");

        // tennu.Client! -> {nickname: String?, username: String?, hostname: String?, identifiedas: String?} -> Admin
        function regexify (admin) {
            client.note("PluginAdmin", format("Adding admin: %j", admin));

            names.forEach(function (name) {
                if (admin[name]) {
                    admin[name] = new RegExp(admin[name], "i");
                } else {
                    admin[name] = anyRegex;
                }
            });

            return admin;
        }

        // tennu.Client! -> [Admin] throws Error
        function initalizeAdmins (adminConfigObject) {

            const admins = adminConfigObject || client.config("admins");

            if (!Array.isArray(admins)) {
                const errormsg = "\"admins\" property in configuration must be an array";
                client.error(errormsg);
                throw new Error(errormsg);
            }

            return admins.map(cloneOnlyAdminKeys).map(regexify);
        }

        // tennu.Client! -> Hostmask -> Admin -> boolean
        function checkHostmask (hostmask, admin) {
            return names.every(function (name) {
                const result = admin[name].test(hostmask[name]);

                client.debug("PluginAdmin", format("%s: %s, %s (%s)",
                    name, hostmask[name], admin[name], result));

                return result;
            });
        }

        // Module Initialization
        admins = initalizeAdmins();

        // Hostmask -> Promise boolean
        const isAdmin = function (hostmask, opts) {
            return Promise.try(function () {
                const customAdmins = opts && opts.customAdmins;
                const memoizationKey = opts && opts.memoizeOver;
                const hostmask_passed = (customAdmins || admins).filter(function (admin) {
                    return checkHostmask(hostmask, admin);
                });

                if (hostmask_passed.some(notHasIdentifiedasProperty)) {
                    client.debug("PluginAdmin", "Admin object w/o identifiedas property (true)");
                    return true;
                }

                client.debug("PluginAdmin", "Admin object w/o identifiedas property (false)");

                return (function recur () {
                    if (hostmask_passed.length === 0) {
                        client.debug("PluginAdmin", "User passes an identifiedas check (false)");
                        return false;
                    }

                    return Promise.try(function () {
                        const hostmask = hostmask_passed.pop();
                        return hostmask.identifiedas;
                    })
                    .then(function (accountname) {
                        return isIdentifiedAs(hostmask.nickname, accountname, {memoizeOver: memoizationKey});
                    })
                    .then(function (isIdentifiedAs) {
                        if (isIdentifiedAs) {
                            client.debug("PluginAdmin", "User passes an identifiedas check (true)");
                            return true;
                        } else {
                            return recur();
                        }
                    });
                }());
            });
        };

        // (Privmsg -> Response) -> (Privmsg -> Response)
        const requiresAdmin = function (fn) {
            return function (privmsg) {
                // If the "command" property is set, it's a command, and not a privmsg.
                // The prototype of a command is the privmsg though.
                const memoizeOver = privmsg.command ? Object.getPrototypeOf(privmsg.command) : privmsg.command;

                return isAdmin(privmsg.hostmask, {memoizeOver: memoizeOver})
                .then(function (isAdmin) {
                    if (isAdmin) {
                        return fn(privmsg);
                    } else {
                        return deniedResponse;
                    }
                });
            };
        };

        // (Privmsg, () -> Response) -> Response
        const checkAdmin = function (privmsg, adminOnlyCallback) {
            // If the "command" property is set, it's a command, and not a privmsg.
            // The prototype of a command is the privmsg though.
            const memoizeOver = privmsg.command ? Object.getPrototypeOf(privmsg.command) : privmsg.command;

            return isAdmin(privmsg.hostmask, {memoizeOver: memoizeOver})
            .then(function (isAdmin) {
                if (isAdmin) {
                    return adminOnlyCallback();
                } else {
                    client.note("PluginAdmin", format("'%s' tried to execute admin-only functionality", privmsg.nickname));
                    return deniedResponse;
                }
            });
        }

        return {
            commandMiddleware: function(command) {
                if (forcedAdminCommands.indexOf(command.command) === -1) {
                    return command;
                }

                return isAdmin(command.hostmask, {memoizeOver: Object.getPrototypeOf(command)})
                .then(function(isAdmin) {
                    if (isAdmin) {
                        return command;
                    }
                    client.note("PluginAdmin", format("'%s' tried to run user-defined admin command '%s'", command.nickname, command.command));
                    return deniedResponse;
                });
            },
            exports: {
                isAdmin: isAdmin,
                checkAdmin: checkAdmin,
                requiresAdmin: requiresAdmin,

                initalizeAdmins: initalizeAdmins,
                regexify: regexify,
                checkHostmask: checkHostmask
            }
        };
    },
    name: "admin",
    role: "admin",
    requires: ["config", "user"]
};<|endoftext|>


<commit_before>/*
 msbuild.js

 copyright (c) 2014 jonathan haker
 Licensed under the MIT license.
 https://github.com/jhaker/nodejs-msbuild

*/

var events = require('events'),
	async = require('async'),
	colors = require('colors');

var args = [];
for(var arg in process.argv) { args.push(process.argv[arg]); }
var help = args.splice(2,1);
var x = function(){};
var _ = new x();
_.isPlainObject = function(obj){
  var ctor, key;
  if (typeof obj != 'object' || !obj || toString.call(obj) != '[object Object]') {
    return false;
  }
  ctor = typeof obj.constructor == 'function' && obj.constructor.prototype;
  if (!ctor || !hasOwnProperty.call(ctor, 'isPrototypeOf')) {
    return false;
  }
  for (key in obj) {}
  return key === void 0 || hasOwnProperty.call(obj, key);
};

var validateCmdParameter = function(param){
	param += "";
	param = param.trim();
	if (param.length <= 2)  return false;
	if (param.substring(0, 1) !== "/")  return false;
	if (param.indexOf(":")  < 1)  return false;
	return true;
}

var defaultPath = process.cwd();

var defaultValues = function(){
		this.os 									= 'windows';  // currently only support windows
		this.processor 						=	'x86';  //   'x86', 'x64'
		this.version							= '4.0';  //  tools version; determines local path to msbuild.exe
		this.sourcePath 					= defaultPath;  //  'c:/mypath/mysolution.sln'   or   'c:/mypath/myproject.csproj
		this.configuration 					= 'myconfiguration';   // solution configurations; targets an environment (debug,release)
		this.publishProfile 				= 'mypublishprofile';   //publish profiles; targets a specific machine (app01,app02)
		this.outputPath 						= '';  //  'c:/deploys/release'
		this.overrideParams		 		= []; /***
																		property overrides (example: ['/clp:ErrorsOnly;', '/p:WarningLevel=2','/p:OutputDir=bin\Debug']  )
																		target framework overrides (example:  ['/tv:4.0'] )
																***/
		this.verbose							= true;
}

var msbuild = function(){
	events.EventEmitter.call(this);
	this.showHelp = help == '?';
	this.processors = { 	'x86': 'Framework', 'x64': 'Framework64'	};
	this.toolsVersion = {
		'2.0': '2.0.50727',  // can only target 2.0
		'3.0':'3.0',
		'3.5': '3.5',
		'4.0': '4.0.30319', // can target 2.0, 3.0, 3.5 and 4
		'4.5': '4.0.30319'
	};
};

msbuild.prototype = new defaultValues();

msbuild.prototype.__proto__ = events.EventEmitter.prototype;

msbuild.prototype.getMSBuildPath = function(os,processor,framework){
	if(os === 'linux') return;

	var windir = process.env.WINDIR;
	var frameworkprocessorDirectory = processor === 'x64' ? 'framework64' : 'framework';
	var frameworkDirectory = 'v' + this.toolsVersion[framework];
	return (windir + '\\Microsoft.NET\\' + frameworkprocessorDirectory + '\\' + frameworkDirectory + '\\msbuild.exe').toLowerCase();
}

msbuild.prototype.buildexe = function(){
	return this.getMSBuildPath(this.os,this.processor,this.version)
}

msbuild.prototype.config =  function(name, value) {

	if(name.toLowerCase() === 'targetframework')
	{
		console.log('\n * CONFIG WARNING: \''.concat(name,'\'  has been deprecated\n   Please use overrideParams (example: overrideParams = [\'/tv:4.0\'] )\n'));
		return;
	}

	var map;

	if (_.isPlainObject(name)) { map = name; }
	else if (value !== undefined) { this[name] = value; return this;	}
	else if (name === undefined) { return this.values; }
	else { return this[name]; }

	for (var key in map) { this.values[name] = map[key]; }
	return this;
};

msbuild.prototype.setConfig = function(cg){
		this.os = 								cg.os 										|| this.os;
		this.processor =					cg.processor 						|| this.processor;
		this.version =						  	cg.version 								|| this.version;
		this.sourcePath = 					cg.sourcePath 						|| this.sourcePath;
		this.configuration = 			  	cg.configuration 					|| this.configuration;
		this.publishProfile =			  	cg.publishProfile 					|| this.publishProfile;
		this.overrideParams = 	  		cg.overrideParams 				|| this.overrideParams;
		this.outputPath  =  				cg.outputPath 						|| this.outputPath;
}

msbuild.prototype.exec = function (cmd) {
	var self = this;
	if(self.showHelp) { self.printHelp(); return; } //abort

	var childProcess = require('child_process'), ls;
	ls = childProcess.exec(cmd, function (error, stdout, stderr) {
		var msg = '';
		if (error) {
			msg = ('\nstack...\n' + error.stack).grey+('\n failed - errors'.white.redBG);
			self.emit('error',error.code,msg);
			return;
		}
		else{
			msg = stdout.grey+('\n finished - no errors'.white.greenBG);
			self.emit('done',null,msg);
		}
	});
}

msbuild.prototype.getDeployOnBuildParam = function(shouldDeploy){
		if(!shouldDeploy){
			shouldDeploy = false;
		}
		return ' /p:deployonbuild='.concat(shouldDeploy);
}

msbuild.prototype.getBuildParams = function(params){
		if(!params){
			params = '';
		}
		params += "";

		if(params.indexOf('configuration') === -1 && this.configuration){
			params += (' /p:configuration='+this.configuration+' ');
		}
		if(params.indexOf('publishprofile') === -1 && this.publishProfile){
			params += (' /p:publishprofile=' + this.publishProfile + ' ');
		}
		return params;
}

msbuild.prototype.getPackageParams = function(params){
		if(!params){
			params = '';
		}
		params += "";

		if(params.indexOf('deployonbuild') === -1){
				var deployOnBuildParam = this.getDeployOnBuildParam(false);
				params += deployOnBuildParam;
		}
		if(params.indexOf('package') === -1){
			params += (' /t:package ');
		}
		if(params.indexOf('outputpath') === -1 && this.outputPath){
			params += (' /p:outputpath='+this.outputPath+' ');
		}
		return params;
}

msbuild.prototype.getPublishParams = function(params){
		if(!params){
			params = '';
		}
		params += "";

		if(params.indexOf('deployonbuild') === -1){
				var deployOnBuildParam = this.getDeployOnBuildParam(true);
				params += (deployOnBuildParam);
		}
		return params;
}

msbuild.prototype.getOverrideParams = function(params){
		if(!params){
			params = '';
		}
		params += "";

		this.overrideParams.forEach(function (param) {
		    if (!validateCmdParameter(param)) return;
		    params += (' ' + param + ' ');
		});
		return params;
}

msbuild.prototype.build = function(){
	this.emit('status',null,'build starting');
	var params = this.getDeployOnBuildParam(false);
		 params = this.getBuildParams(params);
	var buildpath = this.buildexe();
	var cmd = buildpath.concat(' ',this.sourcePath,' ',params);
	return this.exec(cmd);
}

msbuild.prototype.package = function(){
	this.emit('status',null,'package starting');
	var params = this.getBuildParams();
		 params = this.getOverrideParams(params);
		 params = this.getPackageParams(params);
	var cmd = this.buildexe().concat(' ',this.sourcePath,' ',params);
	return this.exec(cmd);
}

msbuild.prototype.publish = function(){
	this.emit('status',null,'publish starting');
	var params = this.getBuildParams();
		 params = this.getOverrideParams(params);
		 params = this.getPublishParams(params);
	var buildpath = this.buildexe();
	var cmd = buildpath.concat(' ',this.sourcePath,' ',params);
	return this.exec(cmd);
}

/****  help section ****/
msbuild.prototype.printHelp = function(){
	var o = this;
	var helpFunctionsToIgnore = ['exec','path','buildexe','on','once','emit','addListener','removeListener','removeAllListeners','listeners','setMaxListeners','printHelp'];
	console.log("\nfunctions".cyan.bold);
	console.log('*******************'.cyan);

	for(var p in o){
		if(typeof(o[p]) == 'function'){
			if(helpFunctionsToIgnore.indexOf(p) > -1) continue;
			if(p == 'printOptions') continue;
			if(p == '?') continue;
			console.log(p.redBG);
		}
	}

	console.log("\nevents".cyan.bold + ' [err,results]'.grey);
	console.log('*******************'.cyan);
	console.log('status'.redBG+' // msbuild.on(\'status\',myfunc)'.grey);
	console.log('error'.redBG+' // msbuild.on(\'error\',myfunc)'.grey);
	console.log('done'.redBG+' // msbuild.on(\'done\',myfunc)'.grey);
}

var msb = new msbuild();
msb.on('status',function(err,results){ if(this.showHelp || !this.verbose) return; if(err){ console.log(err.redBG);}; console.log(results.cyan);});
msb.on('error',function(err,results){ console.log('error'.red); if(err){ console.log(err.redBG);}; console.log(results.red);});
msb.on('done',function(err,results){
	if(this.verbose) {
		console.log(results);}
		else{
		console.log('done'.grey);
		}
	});
module.exports = msb;
<commit_msg>added optional callback param in constructor<commit_after>/*
 msbuild.js

 copyright (c) 2014 jonathan haker
 Licensed under the MIT license.
 https://github.com/jhaker/nodejs-msbuild

*/

var events = require('events'),
	async = require('async'),
	colors = require('colors');

var args = [];
for(var arg in process.argv) { args.push(process.argv[arg]); }
var help = args.splice(2,1);
var x = function(){};
var _ = new x();
_.isPlainObject = function(obj){
  var ctor, key;
  if (typeof obj != 'object' || !obj || toString.call(obj) != '[object Object]') {
    return false;
  }
  ctor = typeof obj.constructor == 'function' && obj.constructor.prototype;
  if (!ctor || !hasOwnProperty.call(ctor, 'isPrototypeOf')) {
    return false;
  }
  for (key in obj) {}
  return key === void 0 || hasOwnProperty.call(obj, key);
};

var validateCmdParameter = function(param){
	param += "";
	param = param.trim();
	if (param.length <= 2)  return false;
	if (param.substring(0, 1) !== "/")  return false;
	if (param.indexOf(":")  < 1)  return false;
	return true;
}

var defaultPath = process.cwd();
var lineBreak = '\n- - - - - - - - - - - - - - - -';

var defaultValues = function(){
		this.os 									= 'windows';  // currently only support windows
		this.processor 						=	'x86';  //   'x86', 'x64'
		this.version							= '4.0';  //  tools version; determines local path to msbuild.exe
		this.sourcePath 					= defaultPath;  //  'c:/mypath/mysolution.sln'   or   'c:/mypath/myproject.csproj
		this.configuration 					= 'myconfiguration';   // solution configurations; targets an environment (debug,release)
		this.publishProfile 				= 'mypublishprofile';   //publish profiles; targets a specific machine (app01,app02)
		this.outputPath 						= '';  //  'c:/deploys/release'
		this.overrideParams		 		= []; /***
																		property overrides (example: ['/clp:ErrorsOnly;', '/p:WarningLevel=2','/p:OutputDir=bin\Debug']  )
																		target framework overrides (example:  ['/tv:4.0'] )
																***/
		this.verbose							= true;
}

var msbuild = function(){
	events.EventEmitter.call(this);
	this.showHelp = help == '?';
	this.processors = { 	'x86': 'Framework', 'x64': 'Framework64'	};
	this.toolsVersion = {
		'2.0': '2.0.50727',  // can only target 2.0
		'3.0':'3.0',
		'3.5': '3.5',
		'4.0': '4.0.30319', // can target 2.0, 3.0, 3.5 and 4
		'4.5': '4.0.30319'
	};
};

msbuild.prototype = new defaultValues();

msbuild.prototype.__proto__ = events.EventEmitter.prototype;

msbuild.prototype.getMSBuildPath = function(os,processor,framework){
	if(os === 'linux') return;

	var windir = process.env.WINDIR;
	var frameworkprocessorDirectory = processor === 'x64' ? 'framework64' : 'framework';
	var frameworkDirectory = 'v' + this.toolsVersion[framework];
	return (windir + '\\Microsoft.NET\\' + frameworkprocessorDirectory + '\\' + frameworkDirectory + '\\msbuild.exe').toLowerCase();
}

msbuild.prototype.buildexe = function(){
	return this.getMSBuildPath(this.os,this.processor,this.version)
}

msbuild.prototype.config =  function(name, value) {

	if(name.toLowerCase() === 'targetframework')
	{
		console.log('\n * CONFIG WARNING: \''.concat(name,'\'  has been deprecated\n   Please use overrideParams (example: overrideParams = [\'/tv:4.0\'] )\n'));
		return;
	}

	var map;

	if (_.isPlainObject(name)) { map = name; }
	else if (value !== undefined) { this[name] = value; return this;	}
	else if (name === undefined) { return this.values; }
	else { return this[name]; }

	for (var key in map) { this.values[name] = map[key]; }
	return this;
};

msbuild.prototype.setConfig = function(cg){
		this.os = 								cg.os 										|| this.os;
		this.processor =					cg.processor 						|| this.processor;
		this.version =						  	cg.version 								|| this.version;
		this.sourcePath = 					cg.sourcePath 						|| this.sourcePath;
		this.configuration = 			  	cg.configuration 					|| this.configuration;
		this.publishProfile =			  	cg.publishProfile 					|| this.publishProfile;
		this.overrideParams = 	  		cg.overrideParams 				|| this.overrideParams;
		this.outputPath  =  				cg.outputPath 						|| this.outputPath;
}

msbuild.prototype.exec = function (cmd) {
	var self = this;
	if(self.showHelp) { self.printHelp(); return; } //abort

	var childProcess = require('child_process'), ls;
	ls = childProcess.exec(cmd, function (error, stdout, stderr) {
		var msg = '';
		if (error) {
			msg = ('\nstack...\n' + error.stack).grey+('\n failed - errors'.white.redBG);
			self.emit('error',error.code,msg);
			return;
		}
		else{
			if(self.verbose){ msg = msg+(stdout.grey); }
			msg = msg+('finished - no errors'.white.greenBG);
			self.emit('done',null,msg);
		}
	});
}

msbuild.prototype.getDeployOnBuildParam = function(shouldDeploy){
		if(!shouldDeploy){
			shouldDeploy = false;
		}
		return ' /p:deployonbuild='.concat(shouldDeploy);
}

msbuild.prototype.getBuildParams = function(params){
		if(!params){
			params = '';
		}
		params += "";

		if(params.indexOf('configuration') === -1 && this.configuration){
			params += (' /p:configuration='+this.configuration+' ');
		}
		if(params.indexOf('publishprofile') === -1 && this.publishProfile){
			params += (' /p:publishprofile=' + this.publishProfile + ' ');
		}
		return params;
}

msbuild.prototype.getPackageParams = function(params){
		if(!params){
			params = '';
		}
		params += "";

		if(params.indexOf('deployonbuild') === -1){
				var deployOnBuildParam = this.getDeployOnBuildParam(false);
				params += deployOnBuildParam;
		}
		if(params.indexOf('package') === -1){
			params += (' /t:package ');
		}
		if(params.indexOf('outputpath') === -1 && this.outputPath){
			params += (' /p:outputpath='+this.outputPath+' ');
		}
		return params;
}

msbuild.prototype.getPublishParams = function(params){
		if(!params){
			params = '';
		}
		params += "";

		if(params.indexOf('deployonbuild') === -1){
				var deployOnBuildParam = this.getDeployOnBuildParam(true);
				params += (deployOnBuildParam);
		}
		return params;
}

msbuild.prototype.getOverrideParams = function(params){
		if(!params){
			params = '';
		}
		params += "";

		this.overrideParams.forEach(function (param) {
		    if (!validateCmdParameter(param)) return;
		    params += (' ' + param + ' ');
		});
		return params;
}
msbuild.prototype.emitStatusStart = function(action){
	var startingMsg = (action+' starting').cyan;
	this.emit('status',null,startingMsg);
}
msbuild.prototype.build = function(){
	this.emitStatusStart('build');
	var params = this.getDeployOnBuildParam(false);
		 params = this.getBuildParams(params);
	var buildpath = this.buildexe();
	var cmd = buildpath.concat(' ',this.sourcePath,' ',params);
	return this.exec(cmd);
}

msbuild.prototype.package = function(){
	this.emitStatusStart('package');
	var params = this.getBuildParams();
		 params = this.getOverrideParams(params);
		 params = this.getPackageParams(params);
	var cmd = this.buildexe().concat(' ',this.sourcePath,' ',params);
	return this.exec(cmd);
}

msbuild.prototype.publish = function(){
	this.emitStatusStart('publish');
	var params = this.getBuildParams();
		 params = this.getOverrideParams(params);
		 params = this.getPublishParams(params);
	var buildpath = this.buildexe();
	var cmd = buildpath.concat(' ',this.sourcePath,' ',params);
	return this.exec(cmd);
}

/****  help section ****/
msbuild.prototype.printHelp = function(){
	var o = this;
	var helpFunctionsToIgnore = ['exec','path','buildexe','on','once','emit','addListener','removeListener','removeAllListeners','listeners','setMaxListeners','printHelp'];
	console.log("\nfunctions".cyan.bold);
	console.log('*******************'.cyan);

	for(var p in o){
		if(typeof(o[p]) == 'function'){
			if(helpFunctionsToIgnore.indexOf(p) > -1) continue;
			if(p == 'printOptions') continue;
			if(p == '?') continue;
			console.log(p.redBG);
		}
	}

	console.log("\nevents".cyan.bold + ' [err,results]'.grey);
	console.log('*******************'.cyan);
	console.log('status'.redBG+' // msbuild.on(\'status\',myfunc)'.grey);
	console.log('error'.redBG+' // msbuild.on(\'error\',myfunc)'.grey);
	console.log('done'.redBG+' // msbuild.on(\'done\',myfunc)'.grey);
}

module.exports = function(callback){
	var msb = new msbuild(callback);
	msb.on('status',function(err,results){
		if(this.showHelp) return;
		if(err){ console.log(err.redBG);};
			console.log(results);}
		);
	msb.on('error',function(err,results){ console.log('error'.red); if(err){ console.log(err.redBG);}; console.log(results.red);});
	msb.on('done',function(err,results){
		console.log(results);
		console.log('done'.cyan);
		console.log(lineBreak);
		if(typeof callback == 'function') callback();
		}
	);
	return msb;
};
<|endoftext|>


<commit_before>var manifest = require('./static/manifest.json')
var lib = require('./library.json')
var url = require('url')
var cuid = require('cuid')

var engine = require('engine.io-stream')
var ws = engine('/ws')

var db = require('multilevel').client(manifest)
           .on('error', Errs)

ws.pipe(db.createRpcStream()).pipe(ws)

var loc = url.parse(window.location.origin)

var user = (loc.host.split('.').length>1) ? loc.host.split('.')[0] : 'unuser'

var canvas = (loc.hash) ? loc.hash : 'home'

var bricoleur = require('./_bricoleur')(db, user, lib)
                  .on('error', Errs)

bricoleur.write('!'+canvas)

if (user==='edit') {
  var omni = require('./lib/omni.js')({id:cuid()})
  omni.pipe(bricoleur).pipe(omni)
}

window.addEventListener('hashchange', function (e) {
  e.preventDefault()
  loc = url.parse(e.newURL)
  canvas = (loc.hash) ? loc.hash : 'home'
  bricoleur.write('!'+canvas)
}, false)

function Errs (err) {
  if (err.code===1) { // failed auth!
    if (omni.write) omni.write({code:1})
  }
}
<commit_msg>remove log spam<commit_after>var manifest = require('./static/manifest.json')
var lib = require('./library.json')
var url = require('url')
var cuid = require('cuid')
var bindshim = require('bindshim')

// read config for socket connection / engine
lib.env = (!lib.env)
  ? {port:80,host:window.location.hostname}
  : lib.env

if (!lib.env.soc) lib.env.soc = 'ws'

var ws = (lib.env.soc==='ws')
  ? require('websocket-stream')('ws://'+lib.env.host+':'+lib.env.port)
  : require('engine.io-stream')('/ws')

var db = require('multilevel').client(manifest)
           .on('error', Errs)

ws.pipe(db.createRpcStream()).pipe(ws)

var loc = url.parse(window.location.origin)

var user = (loc.host.split('.').length>1) ? loc.host.split('.')[0] : 'unuser'

var canvas = (loc.hash) ? loc.hash : '#home'

var bricoleur = require('./_bricoleur')(db, user, lib)
                  .on('error', Errs)

if (user==='edit') {
  var omni = require('./lib/omni.js')({id:cuid()})
  omni.pipe(bricoleur).pipe(omni)
}

window.addEventListener('hashchange', function (e) {
  e.preventDefault()
  loc = url.parse(e.newURL)
  canvas = (loc.hash) ? loc.hash : '#home'
  bricoleur.write('!'+canvas)
}, false)

function Errs (err) {
  if (err.code===1) {
    if (omni.write) omni.write({code:1})
  }
}

bricoleur.write('!'+canvas)

ws.on('error', Errs)
<|endoftext|>


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

    var REG_CHECK_EMPTY_STRING = /^(\u200B|\ufeff)*$/;
    var REG_REPLACE_EMPTY_CHAR = /\u200B|\ufeff/g;
    var REG_CHECK_LINK = /(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|mailto:)/i;
    var REG_CHECK_LINK_START = /^(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|mailto:)/i;
    var REG_PROTO_HTTP = /^(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|mailto:)/i;
    var REG_MAILTO = /^mailto:([^\?]+)/i;
    var REG_EMAIL = /^[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9!#$%&'*+\/=?.^_`{|}~-]+?@(?:[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9](?:[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9-_]*?[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9])?\.)+?(?:xn--[-a-z0-9]+|[a-zа-яё]{2,}|\d{1,3})$/i;
    var REG_CHECK_EMAIL = /(?:^|\s+)[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9!#$%&'*+\/=?.^_`{|}~-]+?@(?:[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9](?:[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9-_]*?[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9])?\.)+?(?:xn--[-a-z0-9]+|[a-zа-яё]{2,}|\d{1,3})(?:$|\s+)/i;
    var REG_CHECK_EMAIL_START = /^[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9!#$%&'*+\/=?.^_`{|}~-]+?@(?:[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9](?:[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9-_]*?[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9])?\.)+?(?:xn--[-a-z0-9]+|[a-zа-яё]{2,}|\d{1,3})/i;
    var TRAILING_PUNCTUATION = /([,.!:;?]+)$/;
    var CKEDITOR_SPACE = 32;
    var CKEDITOR_ENTER = 13;
    var CKEDITOR_SHIFT_ENTER = 2228237;
    var CKEDITOR_LINK_GENERATE_KEYS = [ CKEDITOR_SPACE, CKEDITOR_ENTER, CKEDITOR_SHIFT_ENTER ];

    CKEDITOR.plugins.add('autolink2', {
        'modes': { 'wysiwyg': 1 },

        'init': function(editor) {
            editor.addCommand('autolink2', {
                'modes': { 'wysiwyg': 1 },
                'editorFocus': false,
                'exec': autolink
            } );

            editor.on('key', function(event) {
                if (this.mode !== 'wysiwyg') {
                    return;
                }

                var ckeditorKeyCode = event.data.keyCode;

                if (CKEDITOR_LINK_GENERATE_KEYS.indexOf(ckeditorKeyCode) > -1) {
                    this.execCommand('autolink2');
                }
            });
        }
    });

    function autolink(editor) {
        var context = editor.editable().$;
        var selection = editor.getSelection();
        var rangeNative = selection.getNative().getRangeAt(0).cloneRange();
        var offset;
        var charCode;
        var start = rangeNative.startContainer;
        var diff;
        var savedCursorPosition = saveCursorPosition(selection);

        while (start.nodeType === Node.ELEMENT_NODE && rangeNative.startOffset > 0) {
            start = rangeNative.startContainer.childNodes[ rangeNative.startOffset - 1 ];
            if (!start) {
                break;
            }

            rangeNative.setStart(start, getOffsetNode(start));
            rangeNative.collapse(true);
            start = rangeNative.startContainer;
        }

        do {
            diff = -1;

            if (rangeNative.startOffset === 0) {
                start = rangeNative.startContainer.previousSibling;

                while (start && start.nodeType === Node.ELEMENT_NODE) {
                    if (isEmptyNode(start)) {
                        break;
                    }

                    if (!(CKEDITOR.env.gecko && (start = start.firstChild))) {
                        start = start.lastChild;
                    }
                }

                if (!start) {
                    break;
                }

                var defaultOffset = start.nodeType === Node.ELEMENT_NODE ? 0 : 1

                offset = getOffsetNode(start) || defaultOffset;
                var isLineBreak = start && start.nodeType === Node.TEXT_NODE &&
                    REG_CHECK_EMPTY_STRING.test(start.nodeValue);

                if (!offset || isLineBreak) {
                    break;
                }

            } else {
                start = rangeNative.startContainer;
                offset = rangeNative.startOffset;
            }

            offset = offset + diff;

            if (offset < 0) {
                break;
            }

            rangeNative.setStart(start, offset);
            charCode = rangeNative.toString().charCodeAt(0);

        } while (charCode !== 160 && charCode !== 32);

        var rangeString = rangeNative.toString().replace(REG_REPLACE_EMPTY_CHAR, '');
        var isLink = REG_CHECK_LINK.test(rangeString);
        var isEmail = REG_CHECK_EMAIL.test(rangeString);

        if (!isLink && !isEmail) {
            return;
        }

        var next;
        while ((rangeString = rangeNative.toString())) {
            if (isLink && REG_CHECK_LINK_START.test(rangeString)) {
                break;
            }

            if (isEmail && REG_CHECK_EMAIL_START.test(rangeString)) {
                break;
            }

            try {
                rangeNative.setStart(rangeNative.startContainer, rangeNative.startOffset + 1);

            } catch (error) {
                start = rangeNative.startContainer;

                while (!(next = start.nextSibling)) {
                    if (!context.contains(start)) {
                        return;
                    }

                    start = start.parentNode;
                }

                rangeNative.setStart(next, 0);
            }
        }

        var mailto = rangeNative.toString().match(REG_MAILTO);
        if (mailto) {
            if (!REG_EMAIL.test(mailto[ 1 ])) {
                return;
            }
        }

        var parent = rangeNative.startContainer;
        do {
            if (!context.contains(parent)) {
                break;
            }

            if (parent.tagName === 'A') {
                return;
            }

        } while ((parent = parent.parentNode));

        // Excluding of punctuation mark at the end of link.
        var linkEndsWithPunctuationMark = isLink && TRAILING_PUNCTUATION.exec(rangeString);
        if (linkEndsWithPunctuationMark) {
            var changedEndOffset = rangeNative.endOffset - linkEndsWithPunctuationMark[1].length;
            // changedEndOffset will less then 0 if rangeNative contains not only TextNodes(e.g. HTMLImageElement)
            if (changedEndOffset >= 0) {
                rangeNative.setEnd(rangeNative.endContainer, changedEndOffset);
            }
        }

        applyLink(rangeNative, editor, savedCursorPosition);
    }

    function applyLink(rangeNative, editor, savedCursorPosition) {
        editor.fire('saveSnapshot');

        var range = editor.createRange();
        var startNode = new CKEDITOR.dom.node(rangeNative.startContainer);
        var endNode = new CKEDITOR.dom.node(rangeNative.endContainer);

        range.setStart(startNode, rangeNative.startOffset);
        range.setEnd(endNode, rangeNative.endOffset);

        var href = rangeNative.toString().replace(REG_REPLACE_EMPTY_CHAR, '');
        href = CKEDITOR.tools.htmlDecodeAttr(href);

        if (!REG_PROTO_HTTP.test(href)) {
            if (REG_EMAIL.test(href)) {
                href = 'mailto:' + href;

            } else {
                href = 'http://' + href;
            }
        }

        var style = new CKEDITOR.style({
            'element': 'a',
            'attributes': { 'href': href }
        });

        style.type = CKEDITOR.STYLE_INLINE;
        style.applyToRange(range, editor);

        editor.fire('saveSnapshot');
        restoreCursorPosition(editor, savedCursorPosition);
    }

    function saveCursorPosition(selection) {
        var savedCursorPosition = new CKEDITOR.dom.text('');
        var tempRange = selection.getRanges()[0].clone();
        tempRange.collapse();
        tempRange.insertNode(savedCursorPosition);
        return savedCursorPosition;
    }

    function restoreCursorPosition(editor, savedCursorPosition) {
        var range = editor.createRange();
        range.setStart(savedCursorPosition);
        range.collapse();
        editor.getSelection().selectRanges([ range ]);
    }

    function isEmptyNode(node) {
        if (CKEDITOR.dtd.$inline[ node.tagName.toLowerCase() ] &&
            !node.textContent.replace(REG_REPLACE_EMPTY_CHAR, '').length) {

            return true;
        }

        return false;
    }

    function getOffsetNode(node) {
        return node.nodeType === Node.ELEMENT_NODE ?
            node.childNodes.length :
            node.nodeValue.length;
    }

}());
<commit_msg>Перемещение курсора после элемента ссылки при SHIFT+ENTER для IE<commit_after>(function() {
    'use strict';

    var REG_CHECK_EMPTY_STRING = /^(\u200B|\ufeff)*$/;
    var REG_REPLACE_EMPTY_CHAR = /\u200B|\ufeff/g;
    var REG_CHECK_LINK = /(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|mailto:)/i;
    var REG_CHECK_LINK_START = /^(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|mailto:)/i;
    var REG_PROTO_HTTP = /^(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|mailto:)/i;
    var REG_MAILTO = /^mailto:([^\?]+)/i;
    var REG_EMAIL = /^[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9!#$%&'*+\/=?.^_`{|}~-]+?@(?:[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9](?:[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9-_]*?[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9])?\.)+?(?:xn--[-a-z0-9]+|[a-zа-яё]{2,}|\d{1,3})$/i;
    var REG_CHECK_EMAIL = /(?:^|\s+)[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9!#$%&'*+\/=?.^_`{|}~-]+?@(?:[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9](?:[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9-_]*?[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9])?\.)+?(?:xn--[-a-z0-9]+|[a-zа-яё]{2,}|\d{1,3})(?:$|\s+)/i;
    var REG_CHECK_EMAIL_START = /^[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9!#$%&'*+\/=?.^_`{|}~-]+?@(?:[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9](?:[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9-_]*?[a-zа-яёÇçĞğIıİiÖöŞşÜüẞß0-9])?\.)+?(?:xn--[-a-z0-9]+|[a-zа-яё]{2,}|\d{1,3})/i;
    var TRAILING_PUNCTUATION = /([,.!:;?]+)$/;
    var CKEDITOR_SPACE = 32;
    var CKEDITOR_ENTER = 13;
    var CKEDITOR_SHIFT_ENTER = 2228237;
    var CKEDITOR_LINK_GENERATE_KEYS = [ CKEDITOR_SPACE, CKEDITOR_ENTER, CKEDITOR_SHIFT_ENTER ];

    CKEDITOR.plugins.add('autolink2', {
        'modes': { 'wysiwyg': 1 },

        'init': function(editor) {
            editor.addCommand('autolink2', {
                'modes': { 'wysiwyg': 1 },
                'editorFocus': false,
                'exec': autolink
            } );

            editor.on('key', function(event) {
                if (this.mode !== 'wysiwyg') {
                    return;
                }

                var ckeditorKeyCode = event.data.keyCode;

                if (CKEDITOR_LINK_GENERATE_KEYS.indexOf(ckeditorKeyCode) > -1) {
                    this.execCommand('autolink2');
                }
            });
        }
    });

    function autolink(editor) {
        var context = editor.editable().$;
        var selection = editor.getSelection();
        var rangeNative = selection.getNative().getRangeAt(0).cloneRange();
        var offset;
        var charCode;
        var start = rangeNative.startContainer;
        var diff;
        var savedCursorPosition = saveCursorPosition(selection);

        while (start.nodeType === Node.ELEMENT_NODE && rangeNative.startOffset > 0) {
            start = rangeNative.startContainer.childNodes[ rangeNative.startOffset - 1 ];
            if (!start) {
                break;
            }

            rangeNative.setStart(start, getOffsetNode(start));
            rangeNative.collapse(true);
            start = rangeNative.startContainer;
        }

        do {
            diff = -1;

            if (rangeNative.startOffset === 0) {
                start = rangeNative.startContainer.previousSibling;

                while (start && start.nodeType === Node.ELEMENT_NODE) {
                    if (isEmptyNode(start)) {
                        break;
                    }

                    if (!(CKEDITOR.env.gecko && (start = start.firstChild))) {
                        start = start.lastChild;
                    }
                }

                if (!start) {
                    break;
                }

                var defaultOffset = start.nodeType === Node.ELEMENT_NODE ? 0 : 1

                offset = getOffsetNode(start) || defaultOffset;
                var isLineBreak = start && start.nodeType === Node.TEXT_NODE &&
                    REG_CHECK_EMPTY_STRING.test(start.nodeValue);

                if (!offset || isLineBreak) {
                    break;
                }

            } else {
                start = rangeNative.startContainer;
                offset = rangeNative.startOffset;
            }

            offset = offset + diff;

            if (offset < 0) {
                break;
            }

            rangeNative.setStart(start, offset);
            charCode = rangeNative.toString().charCodeAt(0);

        } while (charCode !== 160 && charCode !== 32);

        var rangeString = rangeNative.toString().replace(REG_REPLACE_EMPTY_CHAR, '');
        var isLink = REG_CHECK_LINK.test(rangeString);
        var isEmail = REG_CHECK_EMAIL.test(rangeString);

        if (!isLink && !isEmail) {
            return;
        }

        var next;
        while ((rangeString = rangeNative.toString())) {
            if (isLink && REG_CHECK_LINK_START.test(rangeString)) {
                break;
            }

            if (isEmail && REG_CHECK_EMAIL_START.test(rangeString)) {
                break;
            }

            try {
                rangeNative.setStart(rangeNative.startContainer, rangeNative.startOffset + 1);

            } catch (error) {
                start = rangeNative.startContainer;

                while (!(next = start.nextSibling)) {
                    if (!context.contains(start)) {
                        return;
                    }

                    start = start.parentNode;
                }

                rangeNative.setStart(next, 0);
            }
        }

        var mailto = rangeNative.toString().match(REG_MAILTO);
        if (mailto) {
            if (!REG_EMAIL.test(mailto[ 1 ])) {
                return;
            }
        }

        var parent = rangeNative.startContainer;
        do {
            if (!context.contains(parent)) {
                break;
            }

            if (parent.tagName === 'A') {
                return;
            }

        } while ((parent = parent.parentNode));

        // Excluding of punctuation mark at the end of link.
        var linkEndsWithPunctuationMark = isLink && TRAILING_PUNCTUATION.exec(rangeString);
        if (linkEndsWithPunctuationMark) {
            var changedEndOffset = rangeNative.endOffset - linkEndsWithPunctuationMark[1].length;
            // changedEndOffset will less then 0 if rangeNative contains not only TextNodes(e.g. HTMLImageElement)
            if (changedEndOffset >= 0) {
                rangeNative.setEnd(rangeNative.endContainer, changedEndOffset);
            }
        }

        applyLink(rangeNative, editor, savedCursorPosition);
    }

    function applyLink(rangeNative, editor, savedCursorPosition) {
        editor.fire('saveSnapshot');

        var range = editor.createRange();

        var startNode = new CKEDITOR.dom.node(rangeNative.startContainer);
        var endNode = new CKEDITOR.dom.node(rangeNative.endContainer);

        range.setStart(startNode, rangeNative.startOffset);
        range.setEnd(endNode, rangeNative.endOffset);

        var href = rangeNative.toString().replace(REG_REPLACE_EMPTY_CHAR, '');
        href = CKEDITOR.tools.htmlDecodeAttr(href);

        if (!REG_PROTO_HTTP.test(href)) {
            if (REG_EMAIL.test(href)) {
                href = 'mailto:' + href;

            } else {
                href = 'http://' + href;
            }
        }

        var style = new CKEDITOR.style({
            'element': 'a',
            'attributes': { 'href': href }
        });

        style.type = CKEDITOR.STYLE_INLINE;
        style.applyToRange(range, editor);

        editor.fire('saveSnapshot');
        restoreCursorPosition(editor, savedCursorPosition, rangeNative);
    }

    function saveCursorPosition(selection) {
        var savedCursorPosition = new CKEDITOR.dom.text('');
        var tempRange = selection.getRanges()[0].clone();
        tempRange.collapse();
        tempRange.insertNode(savedCursorPosition);
        return savedCursorPosition;
    }

    function restoreCursorPosition(editor, savedCursorPosition, linkNativeRange) {
        var range = editor.createRange();
        range.setStart(savedCursorPosition);
        range.collapse();

        editor.getSelection().selectRanges([ range ]);

        var restoredNativeRange = editor.getSelection().getNative().getRangeAt(0);

        var restoredParent = restoredNativeRange.startContainer && restoredNativeRange.startContainer.parentNode;
        var linkTextParent = linkNativeRange.startContainer && linkNativeRange.startContainer.parentNode;

        // IE special cases
        // Cursor must be outside of link (a) element
        if (restoredParent && linkTextParent && restoredParent === linkTextParent) {
            var newRestoredRange = editor.createRange();
            newRestoredRange.setEndAfter(new CKEDITOR.dom.node(linkTextParent));
            newRestoredRange.collapse();
            editor.getSelection().selectRanges([ newRestoredRange ]);
        }
    }

    function isEmptyNode(node) {
        if (CKEDITOR.dtd.$inline[ node.tagName.toLowerCase() ] &&
            !node.textContent.replace(REG_REPLACE_EMPTY_CHAR, '').length) {

            return true;
        }

        return false;
    }

    function getOffsetNode(node) {
        return node.nodeType === Node.ELEMENT_NODE ?
            node.childNodes.length :
            node.nodeValue.length;
    }

}());
<|endoftext|>