<commit_before>jQuery(document).ready(function($){
    var $menu_navigation = $('#main-nav'),
        $cart_trigger = $('#link-to-cart'),
        $close_cart = $('#close_cart'),
        $lateral_cart = $('#cd-cart'),
        $shadow_layer = $('#cd-shadow-layer'),
        $button_add_to_cart = $('#add-to-cart-button'),
        item = '',
        divs = $('#product-variants .variant-options'),
        selected = divs.find('a.selected');

    if (selected.length == divs.length) {
        // Open Cart
        $button_add_to_cart.on('click', function(){
            toggle_panel_visibility($lateral_cart, $shadow_layer, $('body'));
            $("#progress").slideDown();
        });
    }

    $cart_trigger.on('click', function(event){
        event.preventDefault();
        toggle_panel_visibility($lateral_cart, $shadow_layer, $('body'));
    });

    // Close Cart
    $close_cart.on('click', function(event){
        //close lateral menu (if it's open)
        $menu_navigation.removeClass('speed-in');
        toggle_panel_visibility($lateral_cart, $shadow_layer, $('body'));
    });

    // Close lateral cart or lateral menu
    $shadow_layer.on('click', function(){
        $shadow_layer.removeClass('is-visible');
        // firefox transitions break when parent overflow is changed, so we need to wait for the end of the trasition to give the body an overflow hidden
        if( $lateral_cart.hasClass('speed-in') ) {
            $lateral_cart.removeClass('speed-in').on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
                $('body').removeClass('overflow-hidden');
            });
            $menu_navigation.removeClass('speed-in');
        } else {
            $menu_navigation.removeClass('speed-in').on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
                $('body').removeClass('overflow-hidden');
            });
            $lateral_cart.removeClass('speed-in');
        }
    });

    /* remove item from cart  */
    $(document).on('click', 'form#update-minicart a.minicart_remove', function(e){
        $(this).parent().siblings('div[data-hook="minicart_item_quantity"]').find("input.line_item_quantity").val(0);
        $(this).parents('form').first().submit();
        e.preventDefault();
        $("#progress").slideDown();

        if(document.location.pathname == '/cart') {
            document.location.reload();
        }
    });

    $(document).on('click', 'form#update-minicart input.line_item_quantity', function(e){
        item = $(this);
        console.info("minicart click to change quantity item");
        var value = $(this).val();
        $(this).parent().siblings('div[data-hook="minicart_item_quantity"]').find("input.line_item_quantity").val(value);
        $(this).parents('form').first().submit();
        e.preventDefault();

        if(document.location.pathname == '/cart') {
            document.location.reload();
        }
    });

    $(document).on("ajax:beforeSend", "form[data-remote]", function(){
        if(item.length > 0) {
            item.parent().children($("div.loading")).css({"display": " inline-block", "visibility": "visible"});
            item.css({"visibility": "hidden", "display": "none"});
        }
    })

    $(document).on("ajax:success", "form[data-remote]", function(){
        if(item.length > 0) {
            item.parent().children($("div.loading")).css({"display": "none", "visibility": "hidden"});
            item.css({"visibility": "visible", "display": "inline"});
            console.log('Item:', item );
        } else {
            $("#progress").slideUp();
        }
        console.log('Ajax:after');
        item = '';
    })
});

function toggle_panel_visibility ($lateral_panel, $background_layer, $body) {
    if( $lateral_panel.hasClass('speed-in') ) {
        // firefox transitions break when parent overflow is changed, so we need to wait for the end of the trasition to give the body an overflow hidden
        $lateral_panel.removeClass('speed-in').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
            $body.removeClass('overflow-hidden');
        });
        $background_layer.removeClass('is-visible');
    } else {
        $lateral_panel.addClass('speed-in').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
            $body.addClass('overflow-hidden');
        });
        $background_layer.addClass('is-visible');
    }
}<commit_msg>corrected conflict with variant_options<commit_after>jQuery(document).ready(function($){
    var $menu_navigation = $('#main-nav'),
        $cart_trigger = $('#link-to-cart'),
        $close_cart = $('#close_cart'),
        $lateral_cart = $('#cd-cart'),
        $shadow_layer = $('#cd-shadow-layer'),
        $form_add_to_cart = $('div#cart-form form'),
        item = '',
        divs = $('#product-variants .variant-options'),
        selected = divs.find('a.selected');

    $form_add_to_cart.on('submit', function(event){
        var selected = divs.find('a.selected');
        if (selected.length == divs.length) {
            toggle_panel_visibility($lateral_cart, $shadow_layer, $('body'));
            $("#progress").slideDown();
        }
    });

    $cart_trigger.on('click', function(event){
        event.preventDefault();
        toggle_panel_visibility($lateral_cart, $shadow_layer, $('body'));
    });

    // Close Cart
    $close_cart.on('click', function(event){
        //close lateral menu (if it's open)
        $menu_navigation.removeClass('speed-in');
        toggle_panel_visibility($lateral_cart, $shadow_layer, $('body'));
    });

    // Close lateral cart or lateral menu
    $shadow_layer.on('click', function(){
        $shadow_layer.removeClass('is-visible');
        // firefox transitions break when parent overflow is changed, so we need to wait for the end of the trasition to give the body an overflow hidden
        if( $lateral_cart.hasClass('speed-in') ) {
            $lateral_cart.removeClass('speed-in').on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
                $('body').removeClass('overflow-hidden');
            });
            $menu_navigation.removeClass('speed-in');
        } else {
            $menu_navigation.removeClass('speed-in').on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
                $('body').removeClass('overflow-hidden');
            });
            $lateral_cart.removeClass('speed-in');
        }
    });

    /* remove item from cart  */
    $(document).on('click', 'form#update-minicart a.minicart_remove', function(e){
        $(this).parent().siblings('div[data-hook="minicart_item_quantity"]').find("input.line_item_quantity").val(0);
        $(this).parents('form').first().submit();
        e.preventDefault();
        $("#progress").slideDown();

        if(document.location.pathname == '/cart') {
            document.location.reload();
        }
    });

    $(document).on('click', 'form#update-minicart input.line_item_quantity', function(e){
        item = $(this);
        console.info("minicart click to change quantity item");
        var value = $(this).val();
        $(this).parent().siblings('div[data-hook="minicart_item_quantity"]').find("input.line_item_quantity").val(value);
        $(this).parents('form').first().submit();
        e.preventDefault();

        if(document.location.pathname == '/cart') {
            document.location.reload();
        }
    });

    $(document).on("ajax:beforeSend", "form[data-remote]", function(){
        if(item.length > 0) {
            item.parent().children($("div.loading")).css({"display": " inline-block", "visibility": "visible"});
            item.css({"visibility": "hidden", "display": "none"});
        }
    })

    $(document).on("ajax:success", "form[data-remote]", function(){
        if(item.length > 0) {
            item.parent().children($("div.loading")).css({"display": "none", "visibility": "hidden"});
            item.css({"visibility": "visible", "display": "inline"});
            console.log('Item:', item );
        } else {
            $("#progress").slideUp();
        }
        item = '';
    })
});

function toggle_panel_visibility ($lateral_panel, $background_layer, $body) {
    if( $lateral_panel.hasClass('speed-in') ) {
        // firefox transitions break when parent overflow is changed, so we need to wait for the end of the trasition to give the body an overflow hidden
        $lateral_panel.removeClass('speed-in').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
            $body.removeClass('overflow-hidden');
        });
        $background_layer.removeClass('is-visible');
    } else {
        $lateral_panel.addClass('speed-in').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
            $body.addClass('overflow-hidden');
        });
        $background_layer.addClass('is-visible');
    }
}<|endoftext|>


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

    angular.module("blocktrail.setup")
        .controller("LostLockCtrl", LostLockCtrl);

    function LostLockCtrl($scope, $stateParams, $window) {
        if ($stateParams.refresh === "1") {
            $window.location.replace("/#/lostlock?refresh=0");
            $window.location.reload();
        }
    }

})();
<commit_msg>fix redirect spam<commit_after>(function () {
    "use strict";

    angular.module("blocktrail.setup")
        .controller("LostLockCtrl", LostLockCtrl);

    function LostLockCtrl($scope, $stateParams, $timeout, $window) {
        if ($stateParams.refresh === "1") {
            $window.location.replace("/#/lostlock?refresh=0");
            // short timeout to avoid redirect loop
            $timeout(function() {
                $window.location.reload();
            }, 100);
        }
    }

})();
<|endoftext|>


<commit_before>import React, { useState, useEffect } from "react";
import styled from "styled-components";

import style from "@agir/front/genericComponents/_variables.scss";
import axios from "@agir/lib/utils/axios";
import { Hide } from "@agir/front/genericComponents/grid";

import Button from "@agir/front/genericComponents/Button";
import { RawFeatherIcon } from "@agir/front/genericComponents/FeatherIcon";

const Container = styled.div`
  padding: 25px 85px;

  @media (max-width: ${style.collapse}px) {
    padding: 20px;
  }
`;

const BlockTitle = styled.div`
  display: flex;
  justify-content: space-between;
  margin-bottom: 23px;

  > div:first-child {
    display: flex;
    align-items: center;
  }

  ${RawFeatherIcon} {
    margin-right: 6px;
  }
`;

const BlockContent = styled.div`
  margin-bottom: 20px;
`;

const Title = styled.div`
  font-weight: 700;
  font-size: 26px;
`;

const Subtitle = styled.div`
  font-weight: 600;
  font-size: 1rem;
  margin: 20px 0;
`;

const StyledButton = styled(Button)`
  height: 40px;
  font-size: 16px;
  font-weight: 500;
  border-radius: 0.5rem;
`;

const ItemActionContainer = styled.div`
  box-shadow: 0px 0px 2px rgb(0 0 0 / 50%), 0px 3px 3px rgb(0 35 44 / 10%);
  border-radius: 8px;
  overflow: hidden;
  width: 340px;
  display: inline-flex;
  flex-direction: column;
  margin-right: 24px;
  margin-bottom: 24px;

  > div:first-child {
    ${({ img }) => `
      background-image: url(${img});
      background-position: center;
      background-size: cover;
      height: 190px;
    `}
  }

  > div:last-child {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    flex-grow: 1;
    height: 82px;
    overflow: hidden;
    padding: 6px 16px;
  }
`;

const ListItemAction = styled.div`
  display: flex;
  flex-wrap: wrap;
`;

const ItemAction = ({ image, title }) => {
  return (
    <ItemActionContainer img={image}>

{title}

    </ItemActionContainer>
  );
};

const ToolsPage = () => {
  const [categories, setCategories] = useState([]);
  const [pages, setPages] = useState([]);

  const getPagesByCategory = async (id) => {
    const url = `https://infos.actionpopulaire.fr/wp-json/wp/v2/pages?per_page=100&_fields=categories,title,featured_media&categories=${id}`;
    const { data } = await axios.get(url);

    // Add featured image to pages
    let pages = [];
    let requests = data.map(async (p) => {
      const imageUrl = `https://infos.actionpopulaire.fr/wp-json/wp/v2/media/${p.featured_media}`;
      return axios.get(imageUrl).then((res) => {
        pages.push({
          ...p,
          img: res.data.guid.rendered,
          title: p.title.rendered,
        });
      });
    });

    return Promise.all(requests).then(() => {
      return pages;
    });
  };

  const getWPCategories = async () => {
    // TODO: filter by categories in query possible ?
    const url =
      "https://infos.actionpopulaire.fr/wp-json/wp/v2/categories/?per_page=100";
    let { data } = await axios.get(url);

    // Get only categories 15, 16, 17
    data = data.filter((e) => ([15, 16, 17].includes(e.id) ? e : null));
    setCategories(data);

    // Fill Pages by categories
    let pagesSorted = [];
    let requests = data.map(async (c) => {
      return getPagesByCategory(c.id).then((data) => {
        pagesSorted[c.id] = data;
      });
    });

    Promise.all(requests).then(() => {
      setPages(pagesSorted);
    });
  };

  useEffect(() => {
    getWPCategories();
  }, []);

  return (
    <Container>
      <BlockTitle>

          <RawFeatherIcon name="shopping-bag" color={style.black1000} />
          <Title>Commandez du matériel</Title>

        <Hide under>

        </Hide>
      </BlockTitle>

      <BlockContent></BlockContent>

      <BlockTitle>

          <RawFeatherIcon name="book-open" color={style.black1000} />
          <Title>Se former à l'action</Title>

        <Hide under>

        </Hide>
      </BlockTitle>

      <BlockContent>
        {categories.map((category) => (
          <>
            <Subtitle key={category.id}>{category.name}</Subtitle>

            <ListItemAction>
              {pages[category.id]?.map((page) => (
                <ItemAction image={page.img} title={page.title} />
              ))}
            </ListItemAction>
          </>
        ))}
      </BlockContent>

      <BlockTitle>

          <RawFeatherIcon name="mouse-pointer" color={style.black1000} />
          <Title>Je m'informe en ligne</Title>

      </BlockTitle>

      <BlockContent></BlockContent>

      <BlockTitle>

          <RawFeatherIcon name="help-circle" color={style.black1000} />
          <Title>Besoin d'aide ?</Title>

      </BlockTitle>

      <BlockContent></BlockContent>
    </Container>
  );
};

export default ToolsPage;
<commit_msg>feat: add scroll, link, html decode<commit_after>import React, { useState, useEffect } from "react";
import styled from "styled-components";

import axios from "@agir/lib/utils/axios";
import style from "@agir/front/genericComponents/_variables.scss";
import { Hide } from "@agir/front/genericComponents/grid";

import Link from "@agir/front/app/Link";
import Button from "@agir/front/genericComponents/Button";
import { RawFeatherIcon } from "@agir/front/genericComponents/FeatherIcon";

const Container = styled.div`
  padding: 25px 85px;

  @media (max-width: ${style.collapse}px) {
    padding: 20px;
  }
`;

const BlockTitle = styled.div`
  display: flex;
  justify-content: space-between;
  margin-bottom: 23px;

  > div:first-child {
    display: flex;
    align-items: center;
  }

  ${RawFeatherIcon} {
    margin-right: 6px;
  }
`;

const BlockContent = styled.div`
  margin-bottom: 20px;
`;

const Title = styled.div`
  font-weight: 700;
  font-size: 26px;
`;

const Subtitle = styled.div`
  font-weight: 600;
  font-size: 1rem;
  margin: 20px 0;
`;

const StyledButton = styled(Button)`
  height: 40px;
  font-size: 16px;
  font-weight: 500;
  border-radius: 0.5rem;
`;

const ItemActionContainer = styled.div`
  box-shadow: 0px 0px 2px rgb(0 0 0 / 50%), 0px 3px 3px rgb(0 35 44 / 10%);
  border-radius: 8px;
  overflow: hidden;
  width: 340px;
  display: inline-flex;
  flex-direction: column;
  margin-right: 24px;
  margin-bottom: 24px;
  color: ${style.black1000};

  > div:first-child {
    ${({ img }) => `
      background-image: url(${img});
      background-position: center;
      background-size: cover;
      height: 190px;
    `}
  }

  > div:last-child {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    flex-grow: 1;
    height: 82px;
    overflow: hidden;
    padding: 6px 16px;
  }
`;

const ListItemAction = styled.div`
  display: flex;
  // flex-wrap: wrap;
  max-width: 100%;
  overflow-y: hidden;
  overflow-x: auto;
`;

const ItemAction = ({ image, title }) => {
  return (
    <ItemActionContainer img={image}>

    </ItemActionContainer>
  );
};

const ToolsPage = () => {
  const [categories, setCategories] = useState([]);
  const [pages, setPages] = useState([]);

  const getPagesByCategory = async (id) => {
    const url = `https://infos.actionpopulaire.fr/wp-json/wp/v2/pages?per_page=100&_fields=categories,title,link,featured_media&categories=${id}`;
    const { data } = await axios.get(url);

    // Add featured image to pages
    let pages = [];
    let requests = data.map(async (p) => {
      const imageUrl = `https://infos.actionpopulaire.fr/wp-json/wp/v2/media/${p.featured_media}`;
      return axios.get(imageUrl).then((res) => {
        pages.push({
          ...p,
          img: res.data.guid.rendered,
          title: p.title.rendered,
        });
      });
    });

    return Promise.all(requests).then(() => {
      return pages;
    });
  };

  const getWPCategories = async () => {
    // TODO: filter by categories in query possible ?
    const url =
      "https://infos.actionpopulaire.fr/wp-json/wp/v2/categories/?per_page=100";
    let { data } = await axios.get(url);

    // Get only categories 15, 16, 17
    data = data.filter((e) => ([15, 16, 17].includes(e.id) ? e : null));
    setCategories(data);

    // Fill Pages by categories
    let pagesSorted = [];
    let requests = data.map(async (c) => {
      return getPagesByCategory(c.id).then((data) => {
        pagesSorted[c.id] = data;
      });
    });

    Promise.all(requests).then(() => {
      setPages(pagesSorted);
    });
  };

  useEffect(() => {
    getWPCategories();
  }, []);

  return (
    <Container>
      <BlockTitle>

          <RawFeatherIcon name="shopping-bag" color={style.black1000} />
          <Title>Commandez du matériel</Title>

        <Hide under>

        </Hide>
      </BlockTitle>

      <BlockContent></BlockContent>

      <BlockTitle>

          <RawFeatherIcon name="book-open" color={style.black1000} />
          <Title>Se former à l'action</Title>

        <Hide under>

        </Hide>
      </BlockTitle>

      <BlockContent>
        {categories.map((category) => (
          <>
            <Subtitle key={category.id}>{category.name}</Subtitle>

            <ListItemAction>
              {pages[category.id]?.map((page) => (
                <Link href={page.link}>
                  <ItemAction image={page.img} title={page.title} />
                </Link>
              ))}
            </ListItemAction>
          </>
        ))}
      </BlockContent>

      <BlockTitle>

          <RawFeatherIcon name="mouse-pointer" color={style.black1000} />
          <Title>Je m'informe en ligne</Title>

      </BlockTitle>

      <BlockContent></BlockContent>

      <BlockTitle>

          <RawFeatherIcon name="help-circle" color={style.black1000} />
          <Title>Besoin d'aide ?</Title>

      </BlockTitle>

      <BlockContent></BlockContent>
    </Container>
  );
};

export default ToolsPage;
<|endoftext|>


<commit_before>import { Component, PropTypes } from "react";
import ReactMixin from "react-mixin";
import { connect } from "react-redux";
import { graphql } from "react-apollo";
import gql from "graphql-tag";

// loading state
import Loading from "../../components/loading";
import Headerable from "../../mixins/mixins.Header";
import Likeable from "../../mixins/mixins.Likeable";
import Shareable from "../../mixins/mixins.Shareable";

// action helpers
import {
  nav as navActions,
  audio as audioActions,
} from "../../store";

import Track from "./music.Track";

const ALBUM_QUERY = gql`
  query getAlbum($id: ID!) {
    content: node(id: $id) {
      id
      ... on Content {
        entryId: id
        title
        status
        channelName
        meta {
          urlTitle
          siteId
          date
          channelId
        }
        content {
          tracks {
            title
            duration
            file: s3
          }
          images(sizes: ["large", "medium", "small", "xsmall"]) {
            fileName
            fileType
            fileLabel
            size
            url
          }
          colors {
            value
            description
          }
          isLight
        }
      }
    }
  }
`;

const withAlbum = graphql(ALBUM_QUERY, {
  name: "album",
  options: ownProps => ({
    variables: { id: ownProps.params.id },
  }),
});

@withAlbum
@connect(mapQueriesToProps)
@ReactMixin.decorate(Likeable)
@ReactMixin.decorate(Shareable)
@ReactMixin.decorate(Headerable)
export default class MusicAlbum extends Component {

  static propTypes = {
    dispatch: PropTypes.func.isRequired,
    album: PropTypes.oneOfType([
      PropTypes.func,
      PropTypes.object,
    ]).isRequired,
    modalVisible: PropTypes.bool,
    albumArtist: PropTypes.string,
  }

  state = {
    currentTrack: null,
    repeatPattern: "next",
    force: false,
  }

  componentWillMount() {
    if (process.env.WEB) return;
    this.props.dispatch(navActions.setLevel("CONTENT"));
    this.props.dispatch(navActions.setAction("CONTENT", {
      id: 2,
      action: this.likeableAction,
    }));
  }

  componentWillUnmount() {
    this.props.dispatch(navActions.setLevel("TOP"));
    this.props.dispatch(audioActions.dock());
  }

  shuffle = () => {
    if (this.state.repeatPattern === "shuffle") {
      this.setState({ repeatPattern: "next" });
      return;
    }
    this.setState({ repeatPattern: "shuffle" });
  }

  repeat = () => {
    if (this.state.repeatPattern === "repeat") {
      this.setState({ repeatPattern: "repeatAll" });
      return;
    }

    if (this.state.repeatPattern === "repeatAll") {
      this.setState({ repeatPattern: "next" });
      return;
    }

    this.setState({ repeatPattern: "repeat" });
  }

  render() {
    const { content } = this.props.album;

    if (!content) {
      // loading
      return (

            <Loading />

      );
    }

    const getStyle = () => {
      if (this.props.modalVisible) {
        return {
          WebkitFilter: "blur(2px)",
        };
      }

      return {};
    };

    const getUrl = (image) => {
      let url = image.url;

      if (!url) {
        return url;
      }

      if (url.indexOf("http") === -1) {
        url = `https:${url}`;
      }

      return url;
    };

    const album = content;
    const tracks = _.filter(album.content.tracks, track => (!!track.file));

    const xsmallBlurImage = _.find(album.content.images, image => (
      image.fileName.indexOf("blur") > -1 && image.size === "xsmall"
    ));
    const mediumImage = _.find(album.content.images, image => (
      image.fileName.indexOf("blur") === -1 && image.size === "medium"
    ));

    return (

        {/* XXX need a get blurred image helper here */}
        <div
          className={
            "one-whole soft soft-double@palm-wide-and-up overlay floating " +
            "background--dark-primary background--fill"
          }
          style={{ backgroundImage: `url(${getUrl(xsmallBlurImage)})` }}
        >
          <div
            className={
              "one-third floating__item display-inline overlay__item " +
              "ratio--square background--fill"
            }
            style={{ backgroundImage: `url(${getUrl(mediumImage)})` }}
          />

{album.title}

            <h7>{this.props.albumArtist || "NewSpring"}</h7>

            {tracks.map((track, i) => (
              <Track
                track={track}
                album={album}
                key={i}
                trackNumber={i}
              />
            ))}

    );
  }
}
<commit_msg>reorder connect<commit_after>import { Component, PropTypes } from "react";
import ReactMixin from "react-mixin";
import { connect } from "react-redux";
import { graphql } from "react-apollo";
import gql from "graphql-tag";

// loading state
import Loading from "../../components/loading";
import Headerable from "../../mixins/mixins.Header";
import Likeable from "../../mixins/mixins.Likeable";
import Shareable from "../../mixins/mixins.Shareable";

// action helpers
import {
  nav as navActions,
  audio as audioActions,
} from "../../store";

import Track from "./music.Track";

const ALBUM_QUERY = gql`
  query getAlbum($id: ID!) {
    content: node(id: $id) {
      id
      ... on Content {
        entryId: id
        title
        status
        channelName
        meta {
          urlTitle
          siteId
          date
          channelId
        }
        content {
          tracks {
            title
            duration
            file: s3
          }
          images(sizes: ["large", "medium", "small", "xsmall"]) {
            fileName
            fileType
            fileLabel
            size
            url
          }
          colors {
            value
            description
          }
          isLight
        }
      }
    }
  }
`;

const withAlbum = graphql(ALBUM_QUERY, {
  name: "album",
  options: ownProps => ({
    variables: { id: ownProps.params.id },
  }),
});

@connect()
@withAlbum
@ReactMixin.decorate(Likeable)
@ReactMixin.decorate(Shareable)
@ReactMixin.decorate(Headerable)
export default class MusicAlbum extends Component {

  static propTypes = {
    dispatch: PropTypes.func.isRequired,
    album: PropTypes.oneOfType([
      PropTypes.func,
      PropTypes.object,
    ]).isRequired,
    modalVisible: PropTypes.bool,
    albumArtist: PropTypes.string,
  }

  state = {
    currentTrack: null,
    repeatPattern: "next",
    force: false,
  }

  componentWillMount() {
    if (process.env.WEB) return;
    this.props.dispatch(navActions.setLevel("CONTENT"));
    this.props.dispatch(navActions.setAction("CONTENT", {
      id: 2,
      action: this.likeableAction,
    }));
  }

  componentWillUnmount() {
    this.props.dispatch(navActions.setLevel("TOP"));
    this.props.dispatch(audioActions.dock());
  }

  shuffle = () => {
    if (this.state.repeatPattern === "shuffle") {
      this.setState({ repeatPattern: "next" });
      return;
    }
    this.setState({ repeatPattern: "shuffle" });
  }

  repeat = () => {
    if (this.state.repeatPattern === "repeat") {
      this.setState({ repeatPattern: "repeatAll" });
      return;
    }

    if (this.state.repeatPattern === "repeatAll") {
      this.setState({ repeatPattern: "next" });
      return;
    }

    this.setState({ repeatPattern: "repeat" });
  }

  render() {
    const { content } = this.props.album;

    if (!content) {
      // loading
      return (

            <Loading />

      );
    }

    const getStyle = () => {
      if (this.props.modalVisible) {
        return {
          WebkitFilter: "blur(2px)",
        };
      }

      return {};
    };

    const getUrl = (image) => {
      let url = image.url;

      if (!url) {
        return url;
      }

      if (url.indexOf("http") === -1) {
        url = `https:${url}`;
      }

      return url;
    };

    const album = content;
    const tracks = _.filter(album.content.tracks, track => (!!track.file));

    const xsmallBlurImage = _.find(album.content.images, image => (
      image.fileName.indexOf("blur") > -1 && image.size === "xsmall"
    ));
    const mediumImage = _.find(album.content.images, image => (
      image.fileName.indexOf("blur") === -1 && image.size === "medium"
    ));

    return (

        {/* XXX need a get blurred image helper here */}
        <div
          className={
            "one-whole soft soft-double@palm-wide-and-up overlay floating " +
            "background--dark-primary background--fill"
          }
          style={{ backgroundImage: `url(${getUrl(xsmallBlurImage)})` }}
        >
          <div
            className={
              "one-third floating__item display-inline overlay__item " +
              "ratio--square background--fill"
            }
            style={{ backgroundImage: `url(${getUrl(mediumImage)})` }}
          />

{album.title}

            <h7>{this.props.albumArtist || "NewSpring"}</h7>

            {tracks.map((track, i) => (
              <Track
                track={track}
                album={album}
                key={i}
                trackNumber={i}
              />
            ))}

    );
  }
}
<|endoftext|>


<commit_before>self.port.on('log', function log(arguments){
    if (unsafeWindow && unsafeWindow.console){
        unsafeWindow.console.log.call(unsafeWindow, arguments);
    }else{
        console.log('cannot call browser logging: ' + unsafeWindow);
    }
});

self.port.on('connection', function(connection){
    if (unsafeWindow && unsafeWindow.currentVisualization){
        // var connection = JSON.parse(message);
        connection.timestamp = new Date(connection.timestamp);
        unsafeWindow.allConnections.push(connection);
        unsafeWindow.currentVisualization.emit('connection', connection);
    }else{
        console.log('cannot call unsafeWindow.currentVisualization: '  + unsafeWindow);
    }
});

self.port.on('init', function(collusionToken){
    localStorage.collusionToken = collusionToken;

    if (unsafeWindow && unsafeWindow.currentVisualization){
        if ( localStorage.connections && localStorage.connections != "[]" ){
            unsafeWindow.allConnections = JSON.parse(localStorage.connections);
        }
        unsafeWindow.currentVisualization.emit('init', unsafeWindow.allConnections);
    }else{
        console.log('cannot call unsafeWindow.currentVisualization: ' + unsafeWindow);
    }
});

self.port.on("sendTempConnections", function(message){
    // message is an array of connection [ [],[],[] ]
    localStorage.tempConnections = JSON.stringify(message);
    localStorage.tempConnectionsSize = message.length;
    self.port.emit("tempConnectionTransferred", true);

    localStorage.lastSaved = Date.now();
    if ( localStorage.connections & localStorage.connections != "[]" ){
        var allConnectionsAsString = localStorage.connections.slice(0,-1) + "," + localStorage.tempConnections.slice(1);
        localStorage.connections = allConnectionsAsString;
        unsafeWindow.allConnections = JSON.parse(allConnectionsAsString);
    }else{
        var parsedTempConnections = localStorage.tempConnections ? JSON.parse(localStorage.tempConnections) : [ [] ] ;
        localStorage.connections = localStorage.tempConnections;
        unsafeWindow.allConnections = parsedTempConnections;
    }
    localStorage.totalNumConnections = unsafeWindow.allConnections.length;
});

unsafeWindow.addon = self.port;
<commit_msg>fixed typo<commit_after>self.port.on('log', function log(arguments){
    if (unsafeWindow && unsafeWindow.console){
        unsafeWindow.console.log.call(unsafeWindow, arguments);
    }else{
        console.log('cannot call browser logging: ' + unsafeWindow);
    }
});

self.port.on('connection', function(connection){
    if (unsafeWindow && unsafeWindow.currentVisualization){
        // var connection = JSON.parse(message);
        connection.timestamp = new Date(connection.timestamp);
        unsafeWindow.allConnections.push(connection);
        unsafeWindow.currentVisualization.emit('connection', connection);
    }else{
        console.log('cannot call unsafeWindow.currentVisualization: '  + unsafeWindow);
    }
});

self.port.on('init', function(collusionToken){
    localStorage.collusionToken = collusionToken;

    if (unsafeWindow && unsafeWindow.currentVisualization){
        if ( localStorage.connections && localStorage.connections != "[]" ){
            unsafeWindow.allConnections = JSON.parse(localStorage.connections);
        }
        unsafeWindow.currentVisualization.emit('init', unsafeWindow.allConnections);
    }else{
        console.log('cannot call unsafeWindow.currentVisualization: ' + unsafeWindow);
    }
});

self.port.on("sendTempConnections", function(message){
    // message is an array of connection [ [],[],[] ]
    localStorage.tempConnections = JSON.stringify(message);
    localStorage.tempConnectionsSize = message.length;
    self.port.emit("tempConnectionTransferred", true);

    localStorage.lastSaved = Date.now();
    if ( localStorage.connections && localStorage.connections != "[]" ){
        var allConnectionsAsString = localStorage.connections.slice(0,-1) + "," + localStorage.tempConnections.slice(1);
        localStorage.connections = allConnectionsAsString;
        unsafeWindow.allConnections = JSON.parse(allConnectionsAsString);
    }else{
        var parsedTempConnections = localStorage.tempConnections ? JSON.parse(localStorage.tempConnections) : [ [] ] ;
        localStorage.connections = localStorage.tempConnections;
        unsafeWindow.allConnections = parsedTempConnections;
    }
    localStorage.totalNumConnections = unsafeWindow.allConnections.length;
});

unsafeWindow.addon = self.port;
<|endoftext|>


<commit_before>// this scripts helps to find the trigger for MOZILLA_COND_OF_USE
// details: https://github.com/ipfs-shipyard/ipfs-companion/issues/369

// the file with the problem
const problem = '../add-on/dist/bundles/backgroundPage.bundle.js'

/*
   download https://github.com/mozilla/addons-linter/blob/master/src/badwords.json
   in version matching active addons-linter:
   grep version ../node_modules/addons-linter/package.json
 */
const badwords = require('./badwords.json')

const Fs = require('fs')
const file = Fs.readFileSync(problem, 'utf8')

const BADWORDS_RE = {
  en: new RegExp(`\\b(?:${badwords.en.join('|')})\\b`, 'gi')
}

console.log('finding badwords...')

const matches = file.match(BADWORDS_RE.en)

console.log(matches)
<commit_msg>chore: remove find-badwords.js (#990)<commit_after><|endoftext|>


<commit_before>(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
	typeof define === 'function' && define.amd ? define(['exports'], factory) :
	(factory((global.bcombinatorPrelude = global.bcombinatorPrelude || {})));
}(this, function (exports) { 'use strict';

	// curry :: ((a, b, c, ...) -> z) -> a -> b -> c -> ... -> z
	var curry = function (fn) {
		var args = [], len = arguments.length - 1;
		while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];

		return args.length === fn.length ? fn.apply(void 0, args) : curry.bind.apply(curry, [ null, fn ].concat( args ));
	}

	// decode :: String -> String
	var decode = decodeURIComponent

	// _compose :: (b -> c) -> (a -> b) -> (a -> c)
	var _compose = function (f, g) { return function () {
		var args = [], len = arguments.length;
		while ( len-- ) args[ len ] = arguments[ len ];

		return f(g.apply(void 0, args));
	; }	}

	// compose :: (a -> c) -> [(a -> a)] -> (a -> c)
	var compose = function () {
		var fns = [], len = arguments.length;
		while ( len-- ) fns[ len ] = arguments[ len ];

		return fns.reduce(_compose);
	}

	// replace :: Regex -> String -> String -> String
	var replace = curry(function (pattern, substr, str) { return str.replace(pattern, substr); })

	// toLower :: String -> String
	var toLower = function (str) { return str.toLowerCase(); }

	// append :: String -> String -> String
	var append = curry(function (a, b) { return b.concat(a); })

	// contains ::  Eq a => a -> [a] -> Bool
	var contains = curry(function (x, xs) { return xs.indexOf(x) >= 0; })

	// uniq :: Eq a => [a] -> [a]
	var uniq = function (xs) { return xs.reduce(function (list, x) { return !contains(x, list) ? list.concat(x) : list; }, []); }

	// concat :: [a] -> [a] -> [a]
	var concat = curry(function (xs, list) { return xs.concat(list); })

	// union :: Eq a => [a] -> [a] -> [a]
	var union = compose(uniq, concat)

	// join :: String -> [a] -> String
	var join = curry(function (separator, xs) { return xs.join(separator); })

	// split :: String | RegExp → String → [String]
	var split = curry(function (separator, str) { return str.split(separator); })

	// chain :: (a -> [b]) -> [a] -> [b]
	var chain = function (fn, xs) { return [].concat.apply([], xs.map(fn)); }

	// of :: a -> [b]
	var of = Array.of.bind(Array)

	// filter :: (a -> Bool) -> [a] -> [a]
	var filter = curry(function (pred, xs) { return xs.filter(pred); })

	// prepend :: String -> String -> String
	var prepend = curry(function (a, b) { return a.concat(b); })

	// id :: a -> a
	var id = function (x) { return x; }

	exports.curry = curry;
	exports.decode = decode;
	exports.compose = compose;
	exports.replace = replace;
	exports.toLower = toLower;
	exports.append = append;
	exports.contains = contains;
	exports.uniq = uniq;
	exports.concat = concat;
	exports.union = union;
	exports.join = join;
	exports.split = split;
	exports.chain = chain;
	exports.of = of;
	exports.filter = filter;
	exports.prepend = prepend;
	exports.id = id;

	Object.defineProperty(exports, '__esModule', { value: true });

}));<commit_msg>update dist<commit_after>(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
	typeof define === 'function' && define.amd ? define(['exports'], factory) :
	(factory((global.bcombinatorPrelude = global.bcombinatorPrelude || {})));
}(this, function (exports) { 'use strict';

	// curry :: ((a, b, c, ...) -> z) -> a -> b -> c -> ... -> z
	var curry = function (fn) {
		var args = [], len = arguments.length - 1;
		while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];

		return args.length === fn.length ? fn.apply(void 0, args) : curry.bind.apply(curry, [ null, fn ].concat( args ));
	}

	// decode :: String -> String
	var decode = decodeURIComponent

	// _compose :: (b -> c) -> (a -> b) -> (a -> c)
	var _compose = function (f, g) { return function () {
		var args = [], len = arguments.length;
		while ( len-- ) args[ len ] = arguments[ len ];

		return f(g.apply(void 0, args));
	; }	}

	// compose :: (a -> c) -> [(a -> a)] -> (a -> c)
	var compose = function () {
		var fns = [], len = arguments.length;
		while ( len-- ) fns[ len ] = arguments[ len ];

		return fns.reduce(_compose);
	}

	// replace :: Regex -> String -> String -> String
	var replace = curry(function (pattern, substr, str) { return str.replace(pattern, substr); })

	// toLower :: String -> String
	var toLower = function (str) { return str.toLowerCase(); }

	// append :: String -> String -> String
	var append = curry(function (a, b) { return b.concat(a); })

	// contains ::  Eq a => a -> [a] -> Bool
	var contains = curry(function (x, xs) { return xs.indexOf(x) >= 0; })

	// uniq :: Eq a => [a] -> [a]
	var uniq = function (xs) { return xs.reduce(function (list, x) { return !contains(x, list) ? list.concat(x) : list; }, []); }

	// concat :: [a] -> [a] -> [a]
	var concat = curry(function (xs, list) { return xs.concat(list); })

	// union :: Eq a => [a] -> [a] -> [a]
	var union = compose(uniq, concat)

	// join :: String -> [a] -> String
	var join = curry(function (separator, xs) { return xs.join(separator); })

	// split :: String | RegExp → String → [String]
	var split = curry(function (separator, str) { return str.split(separator); })

	// chain :: (a -> [b]) -> [a] -> [b]
	var chain = curry(function (fn, xs) { return [].concat.apply([], xs.map(fn)); })

	// of :: a -> [b]
	var of = Array.of.bind(Array)

	// filter :: (a -> Bool) -> [a] -> [a]
	var filter = curry(function (pred, xs) { return xs.filter(pred); })

	// prepend :: String -> String -> String
	var prepend = curry(function (a, b) { return a.concat(b); })

	// id :: a -> a
	var id = function (x) { return x; }

	exports.curry = curry;
	exports.decode = decode;
	exports.compose = compose;
	exports.replace = replace;
	exports.toLower = toLower;
	exports.append = append;
	exports.contains = contains;
	exports.uniq = uniq;
	exports.concat = concat;
	exports.union = union;
	exports.join = join;
	exports.split = split;
	exports.chain = chain;
	exports.of = of;
	exports.filter = filter;
	exports.prepend = prepend;
	exports.id = id;

	Object.defineProperty(exports, '__esModule', { value: true });

}));<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var message = commit_messages[randomIntFromInterval(0, commit_messages.length - 1)]
    var args = ['commit', outFile, '-m', message]
    for (var counter = 0; counter < length; counter++)
    {
      var message = commit_messages[randomIntFromInterval(0, commit_messages.length - 1)]
      var args = ['commit', outFile, '-m', message]
      fs.writeSy<commit_msg>Logic error<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var message = commit_messages[randomIntFromInterval(0, commit_messages.length - 1)]
    var args = ['commit', outFile, '-m', message]
    for (var counter = 0; counter < length; counter++)
    {
      var message = commit_messages[randomIntFromInterval(0, commit_messages.length - 1)]
      var args = ['commit', outFile, '-m', message]
      fs.writeSyn<|endoftext|>


<commit_before>// LICENSE : MIT
"use strict";
var assert = require("assert");
var getTestDir = require("../lib/get-test-dir");
describe("get-test-dir-test", function () {
    context("when `pkg.directories.test` is not found", function () {
        it("should return 'test/'", function () {
            var dir = getTestDir({
                "directories": {}
            });
            assert.equal(dir, "test/");
        });
    });
    context("when `pkg.directories.test` is set", function () {
        it("should return 'test/'", function () {
            var dir = getTestDir({
                "directories": {
                    "test": "user-dir"
                }
            });
            assert.equal(dir, "user-dir/");
        });
    });
});<commit_msg>chore(test): fix wrong description<commit_after>// LICENSE : MIT
"use strict";
var assert = require("assert");
var getTestDir = require("../lib/get-test-dir");
describe("get-test-dir-test", function () {
    context("when `pkg.directories.test` is not found", function () {
        it("should return 'test/'", function () {
            var dir = getTestDir({
                "directories": {}
            });
            assert.equal(dir, "test/");
        });
    });
    context("when `pkg.directories.test` is set", function () {
        it("should return 'user-dir/'", function () {
            var dir = getTestDir({
                "directories": {
                    "test": "user-dir"
                }
            });
            assert.equal(dir, "user-dir/");
        });
    });
});<|endoftext|>


<commit_before>"use strict";

// trick UMD loader to load debug & release versions through a fake AMD define
function define (any, factory) {
    global.gpf = {};
    factory(global.gpf);
}
define.amd = true;
global.define = define;

// Not supposed to be supported
global["features:es6class"] = false;
global["features:propertydescriptor"] = false;

require("./wscript/setup.js");
require("./cscript.js");
<commit_msg>Improves simulation (#299)<commit_after>"use strict";

// trick UMD loader to load debug & release versions through a fake AMD define
function define (any, factory) {
    global.gpf = {};
    factory(global.gpf);
}
define.amd = true;
global.define = define;

// Not supposed to be supported
global["features:es6class"] = false;
Object.getOwnPropertyDescriptor = null;

require("./wscript/setup.js");
require("./cscript.js");
<|endoftext|>


<commit_before>var HTMLLinkElement = function

  // http://w3c.github.io/webcomponents/spec/imports/#h-interface-import

(tag) {

  var
    proxy = {}

  , link = document.querySelector // use CSS :any ?
      ('link#'+tag+'[rel=import], link[href*='+tag+'][rel=import]')

  , register = function (event, handler) { return (HTMLImports && !!! HTMLImports.useNative)
        // https://github.com/webcomponents/html-imports#htmlimports
        ? HTMLImports.whenReady ( function (_) { return handler ({ target: link }); } ) // eww
        : link.addEventListener (event, handler); }

    Object
      .defineProperties (proxy, {

        'addEventListener': {
          writable: false,

          value: function (event, handler) {
            !!! link
              ? handler  ({ target: proxy })
              : register (event, handler)
          }
        }

// TODO: definition for onerror
//    , 'onerror':
//        { set (handler) {} }
      })

  return proxy
}

var TokenList = function (node) {
  var this$1 = this;

  var
    tokenize = function (node) { return (node.text = node.textContent)

      && node.textContent
          .match (/{(\w+|#)}/g)
            .map (function (symbol) { return symbol.match (/(\w+|#)/g) [0]; })
            .map (insert (node)); }

  , insert = function (token) { return function (symbol) { return (this$1 [symbol] = this$1 [symbol] || [])
          && this$1 [symbol].push (token); }; }

  this
    .sift (node)
    .map(tokenize)
};

TokenList.prototype.sift = function (node) {

  var
    nodes = []

  , visit = function (node) { return node.nodeType === Node.TEXT_NODE
        ? TEXT_NODE (node)
          && NodeFilter.FILTER_ACCEPT // Accept TEXT_NODEs

        : ELEMENT_NODE (node.attributes)
          && NodeFilter.FILTER_REJECT; } // reject ELEMENT_NODEs

  , TEXT_NODE = function (node) { return /{(\w+|#)}/.test (node.textContent); }

  , ELEMENT_NODE = function (attributes) { return Array
        .from (attributes)
        .filter (function (attr) { return /{(\w+|#)}/g.test (attr.value); })
        .map (function (attribute) { return nodes.push (attribute); }); }

  , walker =
      document.createNodeIterator
        (node, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, visit)
        // by default breaks on template YAY! 🎉

  while
    (node = walker.nextNode ())
      { nodes.push (node) }

  return nodes
};

TokenList.prototype.bind = function (context) {
    var this$1 = this;

  var
    replace = function (symbol) { return this$1 [symbol]
        .map (function (token) { return token.textContent = token.text; })

      && this$1 [symbol]
        .map (replacement (symbol)); }

  , replacement = function (symbol) { return function (item) { return item.textContent = item.textContent
          .replace ('{'+symbol+'}', context [symbol]); }; }

  Object
    .keys (this)

    .filter
      (function (key) { return context [key] !== undefined; })

    .map (replace)
};

// INTERESTING! Converting `Template` to a class increases size by ~16 octets

var HTMLTemplateElement = Template = function (name) {

  return Object.assign
    (document.querySelector ('template[name='+name+']'), { bind: bind } )

  function bind (context) {
    var this$1 = this;

    contexts = (ref = []).concat.apply ( ref, [context] )

    var
      clone
    , template = this.cloneNode (false)

    void (this.dependents || [])
      .map (function (dependent) { return dependent.remove (); })

    template.innerHTML =
    contexts.map (function (context, index) {

      context =
        (typeof context  === 'object') ? context : { self: context }

      context ['#'] = index

      clone  = this$1.cloneNode (true)

      void (new TokenList (clone.content))
        .bind (context)

      return clone.innerHTML // immutable snapshot
    })
    .join ('')

    this.dependents = Array.from(template.content.childNodes)
    this.after ( template.content )

    return this
    var ref;
  }
}

var EventTarget = function (Element) { return ((function (Element) {
    function anonymous () {
      Element.apply(this, arguments);
    }

    if ( Element ) anonymous.__proto__ = Element;
    anonymous.prototype = Object.create( Element && Element.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.connectedCallback = function () {

    new HTMLLinkElement
      (this.tagName.toLowerCase ())
        .addEventListener
          ('load', this.onimport.bind (this))
  };

  anonymous.prototype.on = function ( event, handler )

    // MDN EventTarget.addEventListener
    // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
    //
    // WHATWG Living Standard EventTarget.addEventListener
    // https://dom.spec.whatwg.org/#dom-eventtarget-removeeventlistener
    //
    // DOM Level 2 EventTarget.addEventListener
    // https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget-addEventListener

    { this.addEventListener ( event, handler ) };

    return anonymous;
  }(Element))); }

var ParentNode = function (Element) { return ((function (Element) {
    function anonymous () {
      Element.apply(this, arguments);
    }

    if ( Element ) anonymous.__proto__ = Element;
    anonymous.prototype = Object.create( Element && Element.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.selectAll = function (selector)
    { return this.querySelectorAll (selector) };

  anonymous.prototype.select = function (selector)
    // watch out for clobbering `HTMLInputElement.select ()`
    // https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select
    { return this.selectAll (selector) [0] };

    return anonymous;
  }(Element))); }

//function comb
//  // ElementTraversal interface
//  // https://www.w3.org/TR/ElementTraversal/#interface-elementTraversal
//
//(parent) {
//  if (parent.hasChildNodes())
//    for (let node = parent.firstChild; node; node = node.nextSibling)
//      comb (node)
//}

var GlobalEventHandlers = function (Element) { return ((function (Element) {
    function anonymous () {
      Element.apply(this, arguments);
    }

    if ( Element ) anonymous.__proto__ = Element;
    anonymous.prototype = Object.create( Element && Element.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.onimport = function (event, root) {
    if ( root === void 0 ) root = event.target.import;

    root &&
      this.clone
        (root.querySelector ('template'))

    // dispatch `import`
    // and captured from `EventTarget`
    Element.onconnect &&
      Element.onconnect.call (this)

    // dispatch `render`
    // and captured from `EventTarget`
    this.render ()
  };

  anonymous.prototype.register = function (onevents) {
    var this$1 = this;
    if ( onevents === void 0 ) onevents = function (attr) { return /^on/.test (attr.name || attr); };

    var
      mirror = function (handler) { return (this$1 [handler] === null) && // ensure W3C on event
          (this$1 [handler] = Element [handler].bind (this$1)); }

    , nodes = // CSS :not negation https://developer.mozilla.org/en-US/docs/Web/CSS/:not
        // How can we select elements with on* attribute? (i.e. <... onclick=foo onblur=bar>)
        // If we can do this we can only retrieve the elements that have a traditional inline event.
        // This is theoretically more performant as most elements won't need traditional event registration.
        ':not(script):not(template):not(style):not(link)' // remove metadata elements

    , children =
        Array.from (this.querySelectorAll (nodes))

    , registered =
        function (node) { return Array
            .from   (node.attributes)
            .filter (onevents); }

    , reflect =
        function (node) { return Array
            .from   (node.attributes)
            .filter (onevents)
            .map (reflection (node)); }

    , reflection =
        function (node) { return function (event) { return (node [event] = handle (node [event])); }; }

    , handle =
        function (handler, ref) {
            if ( ref === void 0 ) ref = (/{\s*(\w+)\s*}/.exec (handler) || []);
            var _ = ref[0];
            var event = ref[1];

            return event
            && Element [event]
            && Element [event].bind (this$1)
            || handler // existing handler
            || null;
    }  // default for W3C on* event handlers

    Object // mirror class events to element
      .getOwnPropertyNames (Element)
      .filter (onevents)
      .map (mirror)

    void [this]
      .concat (children)
      .filter (registered)
      .map (reflect)
  };

    return anonymous;
  }(Element))); }

var Component = function (Element) { return ( (function (superclass) {
    function anonymous () { superclass.call (this)

    this.context = {}

    // dispatch `initialize`
    // and captured from `EventTarget`
    this.initialize
      && this.initialize ()

    this.tokens = new TokenList (this)
  }

    if ( superclass ) anonymous.__proto__ = superclass;
    anonymous.prototype = Object.create( superclass && superclass.prototype );
    anonymous.prototype.constructor = anonymous;

  anonymous.prototype.render = function () {

    this.tokens
      .bind (this)

//  Array
//    .from // templates with `name` attribute
//      (this.selectAll ('template[name]'))

//    .map
//      (template => template.getAttribute ('name'))

//    .map
//      (name => (new Template (name)).bind (this [name]))

    this.register ()

    // dispatch `idle`
    // and captured from `EventTarget`
    Element.onidle
//    Element.onidle.call (this) // TODO: Migrate to `EventTarget`
  };

  // This doesn't go here. Perhaps SlotList / Template / TokenList (in that order)
  anonymous.prototype.clone = function (template) {
    var this$1 = this;

    var
      fragment = template.content
        .cloneNode (true)

    , slots =
        Array.from (fragment.querySelectorAll ('slot'))

    , replace = function (replacement) { return slots
          .filter (match (replacement))
          .map (exchange (replacement)); }

    , match = function (replacement) { return function (slot) { return replacement.getAttribute ('slot')
            === slot.getAttribute  ('name'); }; }

    , exchange = function (replacement) { return function (slot) { return slot
            // prefer to use replaceWith however support is sparse
            // https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/replaceWith
            // using `Node.parentNode` & `Node.replaceChid` as is defined in (ancient) W3C DOM Level 1,2,3
            .parentNode
            .replaceChild (replacement, slot); }; }

    Array // map attributes from template
      .from (template.attributes)
      .map  (function (attribute) { return this$1.setAttribute (attribute.name, attribute.value); })

    Array // map slots from template
      .from (this.querySelectorAll ('[slot]'))
      .map  (replace)

    this.innerHTML = template.innerHTML
  };

    return anonymous;
  }(( EventTarget ( ParentNode ( GlobalEventHandlers ( Element ))))))); }

var ElementPrototype = window.Element.prototype // see bottom of this file

var Element =
  function (tag, CustomElementRegistry ) {
      if ( CustomElementRegistry === void 0 ) CustomElementRegistry = window.customElements;

      return function (Element) { return CustomElementRegistry.define.apply
        ( CustomElementRegistry, tag.concat( [Component (Element)] )); };
}

// Assign `window.Element.prototype` in case of feature checking on `Element`
Element.prototype = ElementPrototype
  // http://2ality.com/2013/09/window.html
  // http://tobyho.com/2013/03/13/window-prop-vs-global-var
  // https://github.com/webcomponents/webcomponentsjs/blob/master/webcomponents-es5-loader.js#L19

<commit_msg>:muscle: bump distribution for dist/snuggsi.js<commit_after>var HTMLLinkElement = function

  // http://w3c.github.io/webcomponents/spec/imports/#h-interface-import

(tag) {

  var
    proxy = {}

  , link = document.querySelector // use CSS :any ?
      ('link#'+tag+'[rel=import], link[href*='+tag+'][rel=import]')

  , register = function (event, handler) { return (HTMLImports && !!! HTMLImports.useNative)
        // https://github.com/webcomponents/html-imports#htmlimports
        ? HTMLImports.whenReady ( function (_) { return handler ({ target: link }); } ) // eww
        : link.addEventListener (event, handler); }

    Object
      .defineProperties (proxy, {

        'addEventListener': {
          writable: false,

          value: function (event, handler) {
            !!! link
              ? handler  ({ target: proxy })
              : register (event, handler)
          }
        }

// TODO: definition for onerror
//    , 'onerror':
//        { set (handler) {} }
      })

  return proxy
}

var TokenList = function (node) {
  var this$1 = this;

  var
    tokenize = function (node) { return (node.text = node.textContent)

      && node.textContent
          .match (/{(\w+|#)}/g)
            .map (function (symbol) { return symbol.match (/(\w+|#)/g) [0]; })
            .map (insert (node)); }

  , insert = function (token) { return function (symbol) { return (this$1 [symbol] = this$1 [symbol] || [])
          && this$1 [symbol].push (token); }; }

  this
    .sift (node)
    .map(tokenize)
};

TokenList.prototype.sift = function (node) {

  var
    nodes = []

  , visit = function (node) { return node.nodeType === Node.TEXT_NODE
        ? TEXT_NODE (node)
          && NodeFilter.FILTER_ACCEPT // Accept TEXT_NODEs

        : ELEMENT_NODE (node.attributes)
          && NodeFilter.FILTER_REJECT; } // reject ELEMENT_NODEs

  , TEXT_NODE = function (node) { return /{(\w+|#)}/.test (node.textContent); }

  , ELEMENT_NODE = function (attributes) { return Array
        .from (attributes)
        .filter (function (attr) { return /{(\w+|#)}/g.test (attr.value); })
        .map (function (attribute) { return nodes.push (attribute); }); }

  , walker =
      document.createNodeIterator
        (node, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, visit)
        // by default breaks on template YAY! 🎉

  while
    (node = walker.nextNode ())
      { nodes.push (node) }

  return nodes
};

TokenList.prototype.bind = function (context) {
    var this$1 = this;

  var
    replace = function (symbol) { return this$1 [symbol]
        .map (function (token) { return token.textContent = token.text; })

      && this$1 [symbol]
        .map (replacement (symbol)); }

  , replacement = function (symbol) { return function (item) { return item.textContent = item.textContent
          .replace ('{'+symbol+'}', context [symbol]); }; }

  Object
    .keys (this)

    .filter
      (function (key) { return context [key] !== undefined; })

    .map (replace)
};

// INTERESTING! Converting `Template` to a class increases size by ~16 octets

var HTMLTemplateElement = Template = function (name) {

  return Object.assign
    (document.querySelector ('template[name='+name+']'), { bind: bind } )

  function bind (context) {
    var this$1 = this;

    contexts = (ref = []).concat.apply ( ref, [context] )

    var
      clone
    , template = this.cloneNode (false)

    void (this.dependents || [])
      .map (function (dependent) { return dependent.remove (); })

    template.innerHTML =
    contexts.map (function (context, index) {

      context =
        (typeof context  === 'object') ? context : { self: context }

      context ['#'] = index

      clone  = this$1.cloneNode (true)

      void (new TokenList (clone.content))
        .bind (context)

      return clone.innerHTML // immutable snapshot
    })
    .join ('')

    this.dependents = Array.from(template.content.childNodes)
    this.after ( template.content )

    return this
    var ref;
  }
}

var EventTarget = function (Element) { return ((function (Element) {
    function anonymous () {
      Element.apply(this, arguments);
    }

    if ( Element ) anonymous.__proto__ = Element;
    anonymous.prototype = Object.create( Element && Element.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.connectedCallback = function () {

    new HTMLLinkElement
      (this.tagName.toLowerCase ())
        .addEventListener
          ('load', this.onimport.bind (this))
  };

  anonymous.prototype.on = function ( event, handler )

    // MDN EventTarget.addEventListener
    // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
    //
    // WHATWG Living Standard EventTarget.addEventListener
    // https://dom.spec.whatwg.org/#dom-eventtarget-removeeventlistener
    //
    // DOM Level 2 EventTarget.addEventListener
    // https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget-addEventListener

    { this.addEventListener ( event, handler ) };

    return anonymous;
  }(Element))); }

var ParentNode = function (Element) { return ((function (Element) {
    function anonymous () {
      Element.apply(this, arguments);
    }

    if ( Element ) anonymous.__proto__ = Element;
    anonymous.prototype = Object.create( Element && Element.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.selectAll = function (selector)
    { return this.querySelectorAll (selector) };

  anonymous.prototype.select = function (selector)
    // watch out for clobbering `HTMLInputElement.select ()`
    // https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select
    { return this.selectAll (selector) [0] };

    return anonymous;
  }(Element))); }

//function comb
//  // ElementTraversal interface
//  // https://www.w3.org/TR/ElementTraversal/#interface-elementTraversal
//
//(parent) {
//  if (parent.hasChildNodes())
//    for (let node = parent.firstChild; node; node = node.nextSibling)
//      comb (node)
//}

var GlobalEventHandlers = function (Element) { return ((function (Element) {
    function anonymous () {
      Element.apply(this, arguments);
    }

    if ( Element ) anonymous.__proto__ = Element;
    anonymous.prototype = Object.create( Element && Element.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.onimport = function (event, root) {
    if ( root === void 0 ) root = event.target.import;

    root &&
      this.clone
        (root.querySelector ('template'))

    // dispatch `import`
    // and captured from `EventTarget`
    Element.onconnect &&
      Element.onconnect.call (this)

    // dispatch `render`
    // and captured from `EventTarget`
    this.render ()
  };

  anonymous.prototype.register = function (onevents) {
    var this$1 = this;
    if ( onevents === void 0 ) onevents = function (attr) { return /^on/.test (attr.name || attr); };

    var
      mirror = function (handler) { return (this$1 [handler] === null) && // ensure W3C on event
          (this$1 [handler] = Element [handler].bind (this$1)); }

    , nodes = // CSS :not negation https://developer.mozilla.org/en-US/docs/Web/CSS/:not
        // How can we select elements with on* attribute? (i.e. <... onclick=foo onblur=bar>)
        // If we can do this we can only retrieve the elements that have a traditional inline event.
        // This is theoretically more performant as most elements won't need traditional event registration.
        ':not(script):not(template):not(style):not(link)' // remove metadata elements

    , children =
        Array.from (this.querySelectorAll (nodes))

    , registered =
        function (node) { return Array
            .from   (node.attributes)
            .filter (onevents); }

    , reflect =
        function (node) { return Array
            .from   (node.attributes)
            .filter (onevents)
            .map (reflection (node)); }

    , reflection =
        function (node) { return function (event) { return (node [event] = handle (node [event])); }; }

    , handle =
        function (handler, ref) {
            if ( ref === void 0 ) ref = (/{\s*(\w+)\s*}/.exec (handler) || []);
            var _ = ref[0];
            var event = ref[1];

            return event
            && Element [event]
            && Element [event].bind (this$1)
            || handler // existing handler
            || null;
    }  // default for W3C on* event handlers

    Object // mirror class events to element
      .getOwnPropertyNames (Element)
      .filter (onevents)
      .map (mirror)

    void [this]
      .concat (children)
      .filter (registered)
      .map (reflect)
  };

    return anonymous;
  }(Element))); }

var Component = function (Element) { return ( (function (superclass) {
    function anonymous () { superclass.call (this)

    this.context = {}

    // dispatch `initialize`
    // and captured from `EventTarget`
    this.initialize
      && this.initialize ()

    this.tokens = new TokenList (this)
  }

    if ( superclass ) anonymous.__proto__ = superclass;
    anonymous.prototype = Object.create( superclass && superclass.prototype );
    anonymous.prototype.constructor = anonymous;

  anonymous.prototype.render = function () {
    var this$1 = this;

    this.tokens
      .bind (this)

    Array
      .from // templates with `name` attribute
        (this.selectAll ('template[name]'))

      .map
        (function (template) { return template.getAttribute ('name'); })

      .map
        (function (name) { return (new Template (name)).bind (this$1 [name]); })

    this.register ()

    // dispatch `idle`
    // and captured from `EventTarget`
    Element.onidle
//    Element.onidle.call (this) // TODO: Migrate to `EventTarget`
  };

  // This doesn't go here. Perhaps SlotList / Template / TokenList (in that order)
  anonymous.prototype.clone = function (template) {
    var this$1 = this;

    var
      fragment = template.content
        .cloneNode (true)

    , slots =
        Array.from (fragment.querySelectorAll ('slot'))

    , replace = function (replacement) { return slots
          .filter (match (replacement))
          .map (exchange (replacement)); }

    , match = function (replacement) { return function (slot) { return replacement.getAttribute ('slot')
            === slot.getAttribute  ('name'); }; }

    , exchange = function (replacement) { return function (slot) { return slot
            // prefer to use replaceWith however support is sparse
            // https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/replaceWith
            // using `Node.parentNode` & `Node.replaceChid` as is defined in (ancient) W3C DOM Level 1,2,3
            .parentNode
            .replaceChild (replacement, slot); }; }

    Array // map attributes from template
      .from (template.attributes)
      .map  (function (attribute) { return this$1.setAttribute (attribute.name, attribute.value); })

    Array // map slots from template
      .from (this.querySelectorAll ('[slot]'))
      .map  (replace)

    this.innerHTML = template.innerHTML
  };

    return anonymous;
  }(( EventTarget ( ParentNode ( GlobalEventHandlers ( Element ))))))); }

var ElementPrototype = window.Element.prototype // see bottom of this file

var Element =
  function (tag, CustomElementRegistry ) {
      if ( CustomElementRegistry === void 0 ) CustomElementRegistry = window.customElements;

      return function (Element) { return CustomElementRegistry.define.apply
        ( CustomElementRegistry, tag.concat( [Component (Element)] )); };
}

// Assign `window.Element.prototype` in case of feature checking on `Element`
Element.prototype = ElementPrototype
  // http://2ality.com/2013/09/window.html
  // http://tobyho.com/2013/03/13/window-prop-vs-global-var
  // https://github.com/webcomponents/webcomponentsjs/blob/master/webcomponents-es5-loader.js#L19

<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var args = ['commit', outFile, '-m', 'Update character']
    for (var counter = 0; counter < length; counter++)
    {
      fs.writeSync(outFD, data.slice(counter, counter+1), 0, 1)
      sleep(Math.random() * max_sleep)
      child_process.execFileSync('/usr/bin/git', args)
    }
  })
}

function sleep(seconds) {
  var endTime = new Date().getTime() + (second<commit_msg>Update character<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var args = ['commit', outFile, '-m', 'Update character']
    for (var counter = 0; counter < length; counter++)
    {
      fs.writeSync(outFD, data.slice(counter, counter+1), 0, 1)
      sleep(Math.random() * max_sleep)
      child_process.execFileSync('/usr/bin/git', args)
    }
  })
}

function sleep(seconds) {
  var endTime = new Date().getTime() + (seconds<|endoftext|>


<commit_before>import _ from 'lodash';
import Promise from 'bluebird';
import * as constants from '../constants';
import {ValidationError} from '../errors'

/*
 * Get all rules in all stages.
 */
const getRules = (progress, client) => {
  if (progress.rules) return Promise.resolve(progress.rules);

  return Promise.all(constants.RULES_STAGES.map(stage => client.rules.getAll({ stage })))
    .then((...rules) => {
      progress.rules = _.chain(rules)
        .flattenDeep()
        .union()
        .value();
      return progress.rules;
    });
}

/*
 * Delete a rule.
 */
const deleteRule = (progress, client, rules, existingRule) => {
  const rule = _.find(rules, { name: existingRule.name });
  if (!rule) {
    progress.rulesDeleted++;
    progress.log(`Deleting rule ${existingRule.name} (${existingRule.id})`);
    return client.rules.delete({ id: existingRule.id });
  }

  return null;
};

/*
 * Delete all rules.
 */
export const deleteRules = (progress, client, rules) => {
  if (rules.length === 0) {
    return Promise.resolve(true);
  }

  progress.log('Deleting rules that no longer exist in the repository...');

  return getRules(progress, client)
    .then(existingRules => {
      console.log(arguments);
      progress.log(`Existing rules: ${JSON.stringify(existingRules.map(rule => ({ id: rule.id, name: rule.name, stage: rule.stage, order: rule.order })), null, 2)}`);
      return Promise.map(existingRules, (rule) => deleteRule(progress, client, rules, rule), { concurrency: constants.CONCURRENT_CALLS });
    });
};

/*
 * Update a single rule.
 */
const updateRule = (progress, client, existingRules, ruleName, ruleData) => {
  progress.log(`Processing rule '${ruleName}'`);

  const rule = _.find(existingRules, { name: ruleName });
  if (!rule) {
    const payload = {
      enabled: true,
      stage: 'login_success',
      ...ruleData.metadata,
      name: ruleName,
      script: ruleData.script
    };

    progress.rulesCreated++;
    progress.log(`Creating rule ${ruleName}: ${JSON.stringify(payload, null, 2)}`);

    return client.rules.create(payload);
  }

  const payload = {
    ...ruleData.metadata,
    script: ruleData.script || rule.script
  };

  // Remove properties that are not allowed during update.
  delete payload.stage;

  // Update the rule.
  progress.rulesUpdated++;
  progress.log(`Updating rule ${ruleName} (${rule.id}): ${JSON.stringify(payload, null, 2)}`);
  return client.rules.update({ id: rule.id }, payload);
};

/*
 * Update all rules.
 */
export const updateRules = (progress, client, rules) => {
  if (rules.length === 0) {
    return Promise.resolve(true);
  }

  progress.log('Updating rules...');

  return getRules(progress, client)
    .then(existingRules => {
      progress.log(`Existing rules: ${JSON.stringify(existingRules.map(rule => ({ id: rule.id, name: rule.name, stage: rule.stage, order: rule.order })), null, 2)}`);
      return Promise.map(rules, (rule) => updateRule(progress, client, existingRules, rule.name, rule), { concurrency: constants.CONCURRENT_CALLS });
    });
};

const validateRulesStages = (progress, client, rules, existingRules) => new Promise((resolve, reject) => {
  // Rules with invalid state
  const invalidStages = _.filter(rules, (rule) => rule.metadata && rule.metadata.stage && constants.RULES_STAGES.indexOf(rule.metadata.stage)<0).map(rule=> rule.name);
  if (invalidStages.length > 0) return reject(new ValidationError(`The following rules have invalid stages set in their metadata files: ${invalidStages}. Go to https://auth0.com/docs/api/management/v2#!/Rules/post_rules to find the valid stage names.`));

  // Rules that changed state
  const changeStages = _.filter(rules, (rule) => rule.metadata && rule.metadata.stage && _.some(existingRules, (existing) => existing.name === rule.name && existing.stage !== rule.metadata.stage)).map(rule => rule.name);
  if (changeStages.length > 0) return reject(new ValidationError(`The following rules changed stage which is not allowed: ${changeStages}. Rename the rules to recreate them and avoid this error.`));

  // Rules with the same order number
  const duplicatedStageOrder = _(rules)
    .filter(rule => rule.metadata && rule.metadata.order)
    .countBy(rule => `Stage: '${rule.metadata.stage || constants.DEFAULT_RULE_STAGE}' Order: ${rule.metadata.order}`)
    .omit(count => count < 2)
    .keys()
    .value();

  if (duplicatedStageOrder.length > 0) return reject(new ValidationError(`There are multiple rules for the following stage-order combinations [${duplicatedStageOrder}]. Only one rule must be defined for the same order number in a stage.`));

  resolve(true);
})

const validateRulesOrder = (progress, client, rules, existingRules) => {
};

export const validateRules = (progress, client, rules) => {
  if (rules.length === 0) {
    return Promise.resolve(true);
  }

  progress.log('Validating rules...');

  return getRules(progress, client)
    .then(existingRules => validateRulesStages(progress, client, rules, existingRules))
    .then(existingRules => validateRulesOrder(progress, client, rules, existingRules));
}
<commit_msg>Adds validation of existing orders<commit_after>import _ from 'lodash';
import Promise from 'bluebird';
import * as constants from '../constants';
import {ValidationError} from '../errors'

/*
 * Get all rules in all stages.
 */
const getRules = (progress, client) => {
  if (progress.rules) return Promise.resolve(progress.rules);

  return Promise.all(constants.RULES_STAGES.map(stage => client.rules.getAll({ stage })))
    .then((...rules) => {
      progress.rules = _.chain(rules)
        .flattenDeep()
        .union()
        .value();
      return progress.rules;
    });
}

/*
 * Delete a rule.
 */
const deleteRule = (progress, client, rules, existingRule) => {
  const rule = _.find(rules, { name: existingRule.name });
  if (!rule) {
    progress.rulesDeleted++;
    progress.log(`Deleting rule ${existingRule.name} (${existingRule.id})`);
    return client.rules.delete({ id: existingRule.id });
  }

  return null;
};

/*
 * Delete all rules.
 */
export const deleteRules = (progress, client, rules) => {
  if (rules.length === 0) {
    return Promise.resolve(true);
  }

  progress.log('Deleting rules that no longer exist in the repository...');

  return getRules(progress, client)
    .then(existingRules => {
      progress.log(`Existing rules: ${JSON.stringify(existingRules.map(rule => ({ id: rule.id, name: rule.name, stage: rule.stage, order: rule.order })), null, 2)}`);
      return Promise.map(existingRules, (rule) => deleteRule(progress, client, rules, rule), { concurrency: constants.CONCURRENT_CALLS });
    });
};

/*
 * Update a single rule.
 */
const updateRule = (progress, client, existingRules, ruleName, ruleData) => {
  progress.log(`Processing rule '${ruleName}'`);

  const rule = _.find(existingRules, { name: ruleName });
  if (!rule) {
    const payload = {
      enabled: true,
      stage: 'login_success',
      ...ruleData.metadata,
      name: ruleName,
      script: ruleData.script
    };

    progress.rulesCreated++;
    progress.log(`Creating rule ${ruleName}: ${JSON.stringify(payload, null, 2)}`);

    return client.rules.create(payload);
  }

  const payload = {
    ...ruleData.metadata,
    script: ruleData.script || rule.script
  };

  // Remove properties that are not allowed during update.
  delete payload.stage;

  // Update the rule.
  progress.rulesUpdated++;
  progress.log(`Updating rule ${ruleName} (${rule.id}): ${JSON.stringify(payload, null, 2)}`);
  return client.rules.update({ id: rule.id }, payload);
};

/*
 * Update all rules.
 */
export const updateRules = (progress, client, rules) => {
  if (rules.length === 0) {
    return Promise.resolve(true);
  }

  progress.log('Updating rules...');

  return getRules(progress, client)
    .then(existingRules => {
      progress.log(`Existing rules: ${JSON.stringify(existingRules.map(rule => ({ id: rule.id, name: rule.name, stage: rule.stage, order: rule.order })), null, 2)}`);
      return Promise.map(rules, (rule) => updateRule(progress, client, existingRules, rule.name, rule), { concurrency: constants.CONCURRENT_CALLS });
    });
};

const validateRulesStages = (progress, client, rules, existingRules) => new Promise((resolve, reject) => {
  // Rules with invalid state
  const invalidStages = _.filter(rules, (rule) => rule.metadata && rule.metadata.stage && constants.RULES_STAGES.indexOf(rule.metadata.stage)<0).map(rule=> rule.name);
  if (invalidStages.length > 0) return reject(new ValidationError(`The following rules have invalid stages set in their metadata files: ${invalidStages}. Go to https://auth0.com/docs/api/management/v2#!/Rules/post_rules to find the valid stage names.`));

  // Rules that changed state
  const changeStages = _.filter(rules, (rule) => rule.metadata && rule.metadata.stage && _.some(existingRules, (existing) => existing.name === rule.name && existing.stage !== rule.metadata.stage)).map(rule => rule.name);
  if (changeStages.length > 0) return reject(new ValidationError(`The following rules changed stage which is not allowed: ${changeStages}. Rename the rules to recreate them and avoid this error.`));

  resolve(existingRules);
});

const validateRulesOrder = (progress, client, rules, existingRules) => new Promise((resolve, reject) => {
  const rulesWithOrder = _(rules)
    .filter(rule => rule.metadata && rule.metadata.order)
    .map(rule => ({name : rule.name, stage : (rule.metadata.stage || constants.DEFAULT_RULE_STAGE), order : rule.metadata.order}));

  // Rules with the same order number
  const duplicatedStageOrder = rulesWithOrder
    .countBy(rule => `Stage: '${rule.stage}' Order: ${rule.order}`)
    .omit(count => count < 2)
    .keys()
    .value();

  if (duplicatedStageOrder.length > 0) return reject(new ValidationError(`There are multiple rules for the following stage-order combinations [${duplicatedStageOrder}]. Only one rule must be defined for the same order number in a stage.`));

  // Rules with same order than existing rules
  const rulesRepeatingOrder = rulesWithOrder
    .filter(rule => _.some(existingRules, existing => existing.name !== rule.name && existing.stage === rule.stage && existing.order === rule.order))
    .map(rule => rule.name)
    .value();

  if (rulesRepeatingOrder.length > 0) return reject(new ValidationError(`The following rules have the same order number that other existing rule: ${rulesRepeatingOrder}. Updating them may cause a failure in deployment, use different order numbers to ensure a succesful deployment`));

  resolve(existingRules);
});

export const validateRules = (progress, client, rules) => {
  if (rules.length === 0) {
    return Promise.resolve(true);
  }

  progress.log('Validating rules...');

  return getRules(progress, client)
    .then(existingRules => validateRulesStages(progress, client, rules, existingRules))
    .then(existingRules => validateRulesOrder(progress, client, rules, existingRules));
}
<|endoftext|>