<commit_before>import React from 'react'
import introImage from '../images/main-page.jpg'
import svgVue from '../../static/vue.svg'
import svgReact from '../../static/react.svg'
import svgJS from '../../static/javascript.svg'
import PostList from '../components/PostsList'
import Link from 'gatsby-link'
import Button from '../components/Button'

const IndexPage = ({ data }) => (

      Hi, I'm Georgi and I build things on the web with{' '}
      {' '}
      JavaScript,{' '}
      {' '}
      React and{' '}
       Vue.

      I believe that however we build apps on the web, they always end up in the{' '}
      hands of humans and it's crucial that we address{' '}
      web performance and page load times.

      I write articles about 🚁 FPV quads (building and
      flying), 💻 web development,{' '}
      🏠 smart home automation,{' '}
      👨🎓 life-long learning and other topics from my personal
      experience.

      By day{' '}

        I work as a web developer
      {' '}
      and by night I learn and experiment with web tech. If you are interested
      in my skills here's{' '}

        what I have come across along the years
      .

      I hope you find interesting articles around here. If you have any
      questions, you can always find me as{' '}
      @jumpalottahigh on
      Twitter and on Github.

      This blog was a joy to build using Gatsby 💜 (a React
      based static site generator) and is hosted on Firebase 🔥.

Last 5 recent posts:

    <PostList
      showChevron="yes"
      showImage="yes"
      showCategories="no"
      showSearch="no"
      posts={data.allMarkdownRemark.edges}
    />
    <Button style={{ fontSize: '1.2rem', marginRight: '1rem' }} to="/news/">
      All blog posts
    </Button>

      Support the blog

      Additionally, the Eternal Archives section of the blog hosts a bunch of
      unedited content (fan fiction, music and programming) from the early 2000s
      when I was only 15 - 17.

)

export default IndexPage

export const HomePageQuery = graphql`
  query HomePageQuery {
    allMarkdownRemark(
      sort: { order: DESC, fields: [frontmatter___date] }
      limit: 5
      filter: { frontmatter: { draft: { ne: true } } }
    ) {
      edges {
        node {
          excerpt(pruneLength: 390)
          id
          timeToRead
          frontmatter {
            date(formatString: "MMM DD, YYYY")
            path
            title
            author
            tags
            ogImage {
              publicURL
            }
          }
        }
      }
    }
  }
`
<commit_msg>Chame home page link<commit_after>import React from 'react'
import introImage from '../images/main-page.jpg'
import svgVue from '../../static/vue.svg'
import svgReact from '../../static/react.svg'
import svgJS from '../../static/javascript.svg'
import PostList from '../components/PostsList'
import Link from 'gatsby-link'
import Button from '../components/Button'

const IndexPage = ({ data }) => (

      Hi, I'm Georgi and I build things on the web with{' '}
      {' '}
      JavaScript,{' '}
      {' '}
      React and{' '}
       Vue.

      I believe that however we build apps on the web, they always end up in the{' '}
      hands of humans and it's crucial that we address{' '}
      web performance and page load times.

      I write articles about 🚁 FPV quads (building and
      flying), 💻 web development,{' '}
      🏠 smart home automation,{' '}
      👨🎓 life-long learning and other topics from my personal
      experience.

      By day{' '}

        I work as a web developer
      {' '}
      and by night I learn and experiment with web tech. If you are interested
      in my skills here's{' '}

        what I have come across along the years
      .

      I hope you find interesting articles around here. If you have any
      questions, you can always find me as{' '}
      @jumpalottahigh on
      Twitter and on Github.

      This blog was a joy to build using Gatsby 💜 (a React
      based static site generator) and is hosted on Firebase 🔥.

Last 5 recent posts:

    <PostList
      showChevron="yes"
      showImage="yes"
      showCategories="no"
      showSearch="no"
      posts={data.allMarkdownRemark.edges}
    />
    <Button style={{ fontSize: '1.2rem', marginRight: '1rem' }} to="/news/">
      All blog posts
    </Button>

      Support the blog

      Additionally, the Eternal Archives section of the blog hosts a bunch of
      unedited content (fan fiction, music and programming) from the early 2000s
      when I was only 15 - 17.

)

export default IndexPage

export const HomePageQuery = graphql`
  query HomePageQuery {
    allMarkdownRemark(
      sort: { order: DESC, fields: [frontmatter___date] }
      limit: 5
      filter: { frontmatter: { draft: { ne: true } } }
    ) {
      edges {
        node {
          excerpt(pruneLength: 390)
          id
          timeToRead
          frontmatter {
            date(formatString: "MMM DD, YYYY")
            path
            title
            author
            tags
            ogImage {
              publicURL
            }
          }
        }
      }
    }
  }
`
<|endoftext|>


<commit_before><commit_msg>Autorestore heap.<commit_after><|endoftext|>


<commit_before>import React from "react";
import PropTypes from "prop-types";
import Helpers from "../victory-util/helpers";
import { assign } from "lodash";
import CommonProps from "./common-props";
import Path from "./path";
import * as d3Shape from "d3-shape";
import { isObject } from "util";

export default class Bar extends React.Component {

  static propTypes = {
    ...CommonProps,
    alignment: PropTypes.oneOf(["start", "middle", "end"]),
    barRatio: PropTypes.number,
    cornerRadius: PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.func,
      PropTypes.shape({
        top: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),
        bottom: PropTypes.oneOfType([PropTypes.number, PropTypes.func])
      })
    ]),
    datum: PropTypes.object,
    horizontal: PropTypes.bool,
    padding: PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.object
    ]),
    pathComponent: PropTypes.element,
    width: PropTypes.number,
    x: PropTypes.number,
    y: PropTypes.number,
    y0: PropTypes.number
  };

  static defaultProps = {
    pathComponent: <Path/>
  };

  getPosition(props, width) {
    const { x, y, y0, horizontal } = props;
    const alignment = props.alignment || "middle";
    const size = alignment === "middle" ? width / 2 : width;
    const sign = horizontal ? -1 : 1;
    return {
      x0: alignment === "start" ? x : x - (sign * size),
      x1: alignment === "end" ? x : x + (sign * size),
      y0,
      y1: y
    };
  }

  getVerticalBarPath(props, width, cornerRadius) {
    const { x0, x1, y0, y1 } = this.getPosition(props, width);
    const sign = y0 > y1 ? 1 : -1;
    const direction = sign > 0 ? "0 0 1" : "0 0 0";
    const topArc = `${cornerRadius.top} ${cornerRadius.top} ${direction}`;
    const bottomArc = `${cornerRadius.bottom} ${cornerRadius.bottom} ${direction}`;
    return `M ${x0 + cornerRadius.bottom}, ${y0}
      A ${bottomArc}, ${x0}, ${y0 - sign * cornerRadius.bottom}
      L ${x0}, ${y1 + sign * cornerRadius.top}
      A ${topArc}, ${x0 + cornerRadius.top}, ${y1}
      L ${x1 - cornerRadius.top}, ${y1}
      A ${topArc}, ${x1}, ${y1 + sign * cornerRadius.top}
      L ${x1}, ${y0 - sign * cornerRadius.bottom}
      A ${bottomArc}, ${x1 - cornerRadius.bottom}, ${y0}
      z`;
  }

  getHorizontalBarPath(props, width, cornerRadius) {
    const { x0, x1, y0, y1 } = this.getPosition(props, width);
    const sign = y1 > y0 ? 1 : -1;
    const direction = sign > 0 ? "0 0 1" : "0 0 0";
    const topArc = `${cornerRadius.top} ${cornerRadius.top} ${direction}`;
    const bottomArc = `${cornerRadius.bottom} ${cornerRadius.bottom} ${direction}`;
    return `M ${y0}, ${x1 + sign * cornerRadius.bottom}
      A ${bottomArc}, ${y0 + cornerRadius.bottom}, ${x1}
      L ${y1 - sign * cornerRadius.top}, ${x1}
      A ${topArc}, ${y1}, ${x1 + cornerRadius.top}
      L ${y1}, ${x0 - cornerRadius.top}
      A ${topArc}, ${y1 - sign * cornerRadius.top}, ${x0}
      L ${y0 + cornerRadius.bottom}, ${x0 }
      A ${bottomArc}, ${y0}, ${x1 + sign * cornerRadius.bottom}
      z`;
  }

  transformAngle(angle) {
    return -1 * angle + (Math.PI / 2);
  }

  getAngularWidth(props, width) {
    const { scale } = props;
    const range = scale.y.range();
    const r = Math.max(...range);
    const angularRange = Math.abs(scale.x.range()[1] - scale.x.range()[0]);
    return (width / (2 * Math.PI * r)) * angularRange;
  }

  getAngle(props, index) {
    const { data, scale } = props;
    const x = data[index]._x1 === undefined ? "_x" : "_x1";
    return scale.x(data[index][x]);
  }

  getStartAngle(props, index) {
    const { data, scale, alignment } = props;
    const currentAngle = this.getAngle(props, index);
    const angularRange = Math.abs(scale.x.range()[1] - scale.x.range()[0]);
    const previousAngle = index === 0 ?
      this.getAngle(props, data.length - 1) - (Math.PI * 2) :
      this.getAngle(props, index - 1);
    if (index === 0 && angularRange < (2 * Math.PI)) {
      return scale.x.range()[0];
    } else if (alignment === "start" || alignment === "end") {
      return alignment === "start" ? previousAngle : currentAngle;
    } else {
      return (currentAngle + previousAngle) / 2;
    }
  }

  getEndAngle(props, index) {
    const { data, scale, alignment } = props;
    const currentAngle = this.getAngle(props, index);
    const angularRange = Math.abs(scale.x.range()[1] - scale.x.range()[0]);
    const lastAngle = scale.x.range()[1] === (2 * Math.PI) ?
      this.getAngle(props, 0) + (Math.PI * 2) : scale.x.range()[1];
    const nextAngle = index === data.length - 1 ?
      this.getAngle(props, 0) + (Math.PI * 2) : this.getAngle(props, index + 1);
    if (index === data.length - 1 && angularRange < (2 * Math.PI)) {
      return lastAngle;
    } else if (alignment === "start" || alignment === "end") {
      return alignment === "start" ? currentAngle : nextAngle;
    } else {
      return (currentAngle + nextAngle) / 2;
    }
  }

  getPathMoves(path) {
    const moves = path.match(/[A-Z]/g);
    const coords = path.split(/[A-Z]/);
    return moves.map((m, i) => ({ command: m, coords: coords[i + 1].split(",") }));
  }

  getVerticalPolarBarPath(props, cornerRadius) { // eslint-disable-line max-statements
    const { datum, scale, style, index, alignment } = props;
    const r1 = scale.y(datum._y0 || 0);
    const r2 = scale.y(datum._y1 !== undefined ? datum._y1 : datum._y);
    const currentAngle = scale.x(datum._x1 !== undefined ? datum._x1 : datum._x);
    let start;
    let end;
    if (style.width) {
      const width = this.getAngularWidth(props, style.width);
      const size = alignment === "middle" ? width / 2 : width;
      start = alignment === "start" ? currentAngle : currentAngle - size;
      end = alignment === "end" ? currentAngle : currentAngle + size;
    } else {
      start = this.getStartAngle(props, index);
      end = this.getEndAngle(props, index);
    }
    const path = d3Shape.arc()
      .innerRadius(r1)
      .outerRadius(r2)
      .startAngle(this.transformAngle(start))
      .endAngle(this.transformAngle(end));
    if (cornerRadius) {
      const withCorners = d3Shape.arc()
        .innerRadius(r1)
        .outerRadius(r2)
        .startAngle(this.transformAngle(start))
        .endAngle(this.transformAngle(end))
        .cornerRadius(cornerRadius.top);
      const moves = this.getPathMoves(path());
      const cornerMoves = this.getPathMoves(withCorners());
      // eslint-disable-next-line no-magic-numbers
      const totalMoves = cornerMoves.slice(0, 4).concat(moves.slice(2));
      return totalMoves.reduce((memo, move) => {
        memo += `${move.command} ${move.coords.join()}`;
        return memo;
      }, "");
    }
    return path();
  }

  getBarPath(props, width, cornerRadius) {
    return this.props.horizontal ?
      this.getHorizontalBarPath(props, width, cornerRadius) :
      this.getVerticalBarPath(props, width, cornerRadius);
  }

  getPolarBarPath(props) {
    // TODO Radial bars
    return this.getVerticalPolarBarPath(props);
  }

  getBarWidth(props, style) {
    if (style.width) {
      return style.width;
    }
    const { scale, data } = props;
    const range = scale.x.range();
    const extent = Math.abs(range[1] - range[0]);
    const bars = data.length + 2;
    const barRatio = props.barRatio || 0.5;
    // eslint-disable-next-line no-magic-numbers
    const defaultWidth = data.length < 2 ? 8 : (barRatio * extent / bars);
    return Math.max(1, defaultWidth);
  }

  getCornerRadius(props) {
    const { cornerRadius, datum, active } = props;
    if (!cornerRadius) {
      return { top: 0, bottom: 0 };
    } else if (isObject(cornerRadius)) {
      return {
        top: Helpers.evaluateProp(cornerRadius.top, datum, active),
        bottom: Helpers.evaluateProp(cornerRadius.bottom, datum, active)
      };
    } else {
      return {
        top: Helpers.evaluateProp(cornerRadius, datum, active),
        bottom: 0
      };
    }
  }

  render() {
    const {
      role, datum, active, shapeRendering, className, origin, polar, pathComponent, events
    } = this.props;
    const stroke = this.props.style && this.props.style.fill || "black";
    const baseStyle = { fill: "black", stroke };
    const style = Helpers.evaluateStyle(assign(baseStyle, this.props.style), datum, active);
    const width = this.getBarWidth(this.props, style);
    const cornerRadius = this.getCornerRadius(this.props);
    const path = polar ?
      this.getPolarBarPath(this.props, cornerRadius) :
      this.getBarPath(this.props, width, cornerRadius);
    const transform = polar && origin ? `translate(${origin.x}, ${origin.y})` : undefined;
    return React.cloneElement(pathComponent, {
      d: path, transform, className, style, role, shapeRendering, events
    });
  }
}
<commit_msg>lodash isObject<commit_after>import React from "react";
import PropTypes from "prop-types";
import Helpers from "../victory-util/helpers";
import { assign, isObject } from "lodash";
import CommonProps from "./common-props";
import Path from "./path";
import * as d3Shape from "d3-shape";

export default class Bar extends React.Component {

  static propTypes = {
    ...CommonProps,
    alignment: PropTypes.oneOf(["start", "middle", "end"]),
    barRatio: PropTypes.number,
    cornerRadius: PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.func,
      PropTypes.shape({
        top: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),
        bottom: PropTypes.oneOfType([PropTypes.number, PropTypes.func])
      })
    ]),
    datum: PropTypes.object,
    horizontal: PropTypes.bool,
    padding: PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.object
    ]),
    pathComponent: PropTypes.element,
    width: PropTypes.number,
    x: PropTypes.number,
    y: PropTypes.number,
    y0: PropTypes.number
  };

  static defaultProps = {
    pathComponent: <Path/>
  };

  getPosition(props, width) {
    const { x, y, y0, horizontal } = props;
    const alignment = props.alignment || "middle";
    const size = alignment === "middle" ? width / 2 : width;
    const sign = horizontal ? -1 : 1;
    return {
      x0: alignment === "start" ? x : x - (sign * size),
      x1: alignment === "end" ? x : x + (sign * size),
      y0,
      y1: y
    };
  }

  getVerticalBarPath(props, width, cornerRadius) {
    const { x0, x1, y0, y1 } = this.getPosition(props, width);
    const sign = y0 > y1 ? 1 : -1;
    const direction = sign > 0 ? "0 0 1" : "0 0 0";
    const topArc = `${cornerRadius.top} ${cornerRadius.top} ${direction}`;
    const bottomArc = `${cornerRadius.bottom} ${cornerRadius.bottom} ${direction}`;
    return `M ${x0 + cornerRadius.bottom}, ${y0}
      A ${bottomArc}, ${x0}, ${y0 - sign * cornerRadius.bottom}
      L ${x0}, ${y1 + sign * cornerRadius.top}
      A ${topArc}, ${x0 + cornerRadius.top}, ${y1}
      L ${x1 - cornerRadius.top}, ${y1}
      A ${topArc}, ${x1}, ${y1 + sign * cornerRadius.top}
      L ${x1}, ${y0 - sign * cornerRadius.bottom}
      A ${bottomArc}, ${x1 - cornerRadius.bottom}, ${y0}
      z`;
  }

  getHorizontalBarPath(props, width, cornerRadius) {
    const { x0, x1, y0, y1 } = this.getPosition(props, width);
    const sign = y1 > y0 ? 1 : -1;
    const direction = sign > 0 ? "0 0 1" : "0 0 0";
    const topArc = `${cornerRadius.top} ${cornerRadius.top} ${direction}`;
    const bottomArc = `${cornerRadius.bottom} ${cornerRadius.bottom} ${direction}`;
    return `M ${y0}, ${x1 + sign * cornerRadius.bottom}
      A ${bottomArc}, ${y0 + cornerRadius.bottom}, ${x1}
      L ${y1 - sign * cornerRadius.top}, ${x1}
      A ${topArc}, ${y1}, ${x1 + cornerRadius.top}
      L ${y1}, ${x0 - cornerRadius.top}
      A ${topArc}, ${y1 - sign * cornerRadius.top}, ${x0}
      L ${y0 + cornerRadius.bottom}, ${x0 }
      A ${bottomArc}, ${y0}, ${x1 + sign * cornerRadius.bottom}
      z`;
  }

  transformAngle(angle) {
    return -1 * angle + (Math.PI / 2);
  }

  getAngularWidth(props, width) {
    const { scale } = props;
    const range = scale.y.range();
    const r = Math.max(...range);
    const angularRange = Math.abs(scale.x.range()[1] - scale.x.range()[0]);
    return (width / (2 * Math.PI * r)) * angularRange;
  }

  getAngle(props, index) {
    const { data, scale } = props;
    const x = data[index]._x1 === undefined ? "_x" : "_x1";
    return scale.x(data[index][x]);
  }

  getStartAngle(props, index) {
    const { data, scale, alignment } = props;
    const currentAngle = this.getAngle(props, index);
    const angularRange = Math.abs(scale.x.range()[1] - scale.x.range()[0]);
    const previousAngle = index === 0 ?
      this.getAngle(props, data.length - 1) - (Math.PI * 2) :
      this.getAngle(props, index - 1);
    if (index === 0 && angularRange < (2 * Math.PI)) {
      return scale.x.range()[0];
    } else if (alignment === "start" || alignment === "end") {
      return alignment === "start" ? previousAngle : currentAngle;
    } else {
      return (currentAngle + previousAngle) / 2;
    }
  }

  getEndAngle(props, index) {
    const { data, scale, alignment } = props;
    const currentAngle = this.getAngle(props, index);
    const angularRange = Math.abs(scale.x.range()[1] - scale.x.range()[0]);
    const lastAngle = scale.x.range()[1] === (2 * Math.PI) ?
      this.getAngle(props, 0) + (Math.PI * 2) : scale.x.range()[1];
    const nextAngle = index === data.length - 1 ?
      this.getAngle(props, 0) + (Math.PI * 2) : this.getAngle(props, index + 1);
    if (index === data.length - 1 && angularRange < (2 * Math.PI)) {
      return lastAngle;
    } else if (alignment === "start" || alignment === "end") {
      return alignment === "start" ? currentAngle : nextAngle;
    } else {
      return (currentAngle + nextAngle) / 2;
    }
  }

  getPathMoves(path) {
    const moves = path.match(/[A-Z]/g);
    const coords = path.split(/[A-Z]/);
    return moves.map((m, i) => ({ command: m, coords: coords[i + 1].split(",") }));
  }

  getVerticalPolarBarPath(props, cornerRadius) { // eslint-disable-line max-statements
    const { datum, scale, style, index, alignment } = props;
    const r1 = scale.y(datum._y0 || 0);
    const r2 = scale.y(datum._y1 !== undefined ? datum._y1 : datum._y);
    const currentAngle = scale.x(datum._x1 !== undefined ? datum._x1 : datum._x);
    let start;
    let end;
    if (style.width) {
      const width = this.getAngularWidth(props, style.width);
      const size = alignment === "middle" ? width / 2 : width;
      start = alignment === "start" ? currentAngle : currentAngle - size;
      end = alignment === "end" ? currentAngle : currentAngle + size;
    } else {
      start = this.getStartAngle(props, index);
      end = this.getEndAngle(props, index);
    }
    const path = d3Shape.arc()
      .innerRadius(r1)
      .outerRadius(r2)
      .startAngle(this.transformAngle(start))
      .endAngle(this.transformAngle(end));
    if (cornerRadius) {
      const withCorners = d3Shape.arc()
        .innerRadius(r1)
        .outerRadius(r2)
        .startAngle(this.transformAngle(start))
        .endAngle(this.transformAngle(end))
        .cornerRadius(cornerRadius.top);
      const moves = this.getPathMoves(path());
      const cornerMoves = this.getPathMoves(withCorners());
      // eslint-disable-next-line no-magic-numbers
      const totalMoves = cornerMoves.slice(0, 4).concat(moves.slice(2));
      return totalMoves.reduce((memo, move) => {
        memo += `${move.command} ${move.coords.join()}`;
        return memo;
      }, "");
    }
    return path();
  }

  getBarPath(props, width, cornerRadius) {
    return this.props.horizontal ?
      this.getHorizontalBarPath(props, width, cornerRadius) :
      this.getVerticalBarPath(props, width, cornerRadius);
  }

  getPolarBarPath(props) {
    // TODO Radial bars
    return this.getVerticalPolarBarPath(props);
  }

  getBarWidth(props, style) {
    if (style.width) {
      return style.width;
    }
    const { scale, data } = props;
    const range = scale.x.range();
    const extent = Math.abs(range[1] - range[0]);
    const bars = data.length + 2;
    const barRatio = props.barRatio || 0.5;
    // eslint-disable-next-line no-magic-numbers
    const defaultWidth = data.length < 2 ? 8 : (barRatio * extent / bars);
    return Math.max(1, defaultWidth);
  }

  getCornerRadius(props) {
    const { cornerRadius, datum, active } = props;
    if (!cornerRadius) {
      return { top: 0, bottom: 0 };
    } else if (isObject(cornerRadius)) {
      return {
        top: Helpers.evaluateProp(cornerRadius.top, datum, active),
        bottom: Helpers.evaluateProp(cornerRadius.bottom, datum, active)
      };
    } else {
      return {
        top: Helpers.evaluateProp(cornerRadius, datum, active),
        bottom: 0
      };
    }
  }

  render() {
    const {
      role, datum, active, shapeRendering, className, origin, polar, pathComponent, events
    } = this.props;
    const stroke = this.props.style && this.props.style.fill || "black";
    const baseStyle = { fill: "black", stroke };
    const style = Helpers.evaluateStyle(assign(baseStyle, this.props.style), datum, active);
    const width = this.getBarWidth(this.props, style);
    const cornerRadius = this.getCornerRadius(this.props);
    const path = polar ?
      this.getPolarBarPath(this.props, cornerRadius) :
      this.getBarPath(this.props, width, cornerRadius);
    const transform = polar && origin ? `translate(${origin.x}, ${origin.y})` : undefined;
    return React.cloneElement(pathComponent, {
      d: path, transform, className, style, role, shapeRendering, events
    });
  }
}
<|endoftext|>


<commit_before>var temp;
var random;
var img;
var answer = "CATS";
var text_before = "IT'S RAINING";
var text_after = "AND DOGS";

// This function is called when the user submits an answer
//

$(document).ready(function(){
    $('#search_tag').keypress(function(e){
      if(e.keyCode==13)
      $("button").click()(function(){
        var user_response = document.getElementById("search_tag").value;
        user_response = user_response.toUpperCase();
        if(user_response == answer){
            $('#score').html(function(i, val) {
                return val*1+1 });
            cleartext();
            clearimage();
            $('#correct').show();
            $( "#correct" ).fadeOut( 5000, function() {
            });
            display_puzzle();
        }
        else{
            document.getElementById("search_tag").value = "";
            clearimage();
            $('#wrong').show();
            $( "#wrong" ).fadeOut( 5000, function() {
            });
            display_image(search_term);
        }
      })
    });
});
$(document).ready(function() {
    $("button").click(function() {
        var user_response = document.getElementById("search_tag").value;
        user_response = user_response.toUpperCase();
        if(user_response == answer){
            $('#score').html(function(i, val) { return val*1+1 });
            cleartext();
            clearimage();
            $('#correct').show();
            $( "#correct" ).fadeOut( 5000, function() {
            });
            display_puzzle();
        }
        else{
            document.getElementById("search_tag").value = "";
            clearimage();
            $('#wrong').show();
            $( "#wrong" ).fadeOut( 5000, function() {
            });
            display_image(search_term);
        }

    });
});

function cleartext(){
    document.getElementById("search_tag").value = "";
}

function clearimage() {
    document.getElementById("gif-place").removeChild(img);
}

function newQuestion(text){
    $('#question').html(function() { return text });
}

function getRandom() {
    return Math.floor((Math.random() * 25));
}

function display_image(search_term){
    console.log("search_term = " + search_term);
    var xhr = $.get("http://api.giphy.com/v1/gifs/search?q=" + search_term + "&api_key=dc6zaTOxFJmzC&limit=25");
        xhr.done(
            function(response) {
            temp = response;
            console.log(temp);
            console.log("success got data", response);
            //var select_gif = response.data[random].images.original;
            show_image(response);
        });
}

function show_image(image_object) {

    //console.log(height, width);
    random = getRandom();
    //var width = image_object.data[random].images.original.width;
    //var height = image_object.data[random].images.original.height;
    var source = image_object.data[random].images.original.url;
    //var resized = resize(height, width);

    //height = resized[0];
    //width = resized[1];
    //console.log(height, width);

    img = document.createElement("img");
    img.src = source;
    img.width = 400; //temp.data[random].images.original.width;
    img.height = 400; //temp.data[random].images.original.height;
    img.alt = "Guess the word!";
    document.getElementById("gif-place").appendChild(img);
}

// resize is deprecated bc we chose to have all gifs be the same size for consistency's sake
/*
 *function resize(height, width) {
 *
 *    console.log(height, width);
 *
 *    var MAX_HEIGHT = 400;
 *    var MAX_WIDTH = 400;
 *
 *    var gcd = get_gcd(height, width);
 *
 *    console.log("gcd = " + gcd);
 *    width = width / gcd;
 *    height = height / gcd;
 *
 *    var width_mult = MAX_WIDTH / width;
 *    var height_mult = MAX_HEIGHT / height;
 *    var multiplier = Math.min(width_mult, height_mult);
 *    console.log("multiplier = " + multiplier);
 *    width = width * multiplier;
 *    height = height * multiplier;
 *    console.log(height, width);
 *    return [height, width];
 *}
 */

function get_gcd (a, b) {
    if ( ! b) {
        return a;
    }
    return get_gcd(b, a % b);
};

/*
 *  THIS IS FOR SPACE
 *
 */

var sentences = {
    "ROSES ARE RED": [0],
    "A BARREL OF MONKEYS":[3],
    "IT'S RAINING CATS AND DOGS":[2],
    "AS STUBBORN AS AN OX":[4],
    "TALLER THAN A TREE":[3],
    "IT TAKES TWO TO TANGO":[4],
    "HAVE YOUR CAKE AND EAT IT TOO":[2],
    "ELVIS HAS LEFT THE BUILDING":[0],
    "IN THE HEAT OF THE MOMENT":[2],
    "KILL TWO BIRDS WITH ONE STONE":[2],
    "SPEAK OF THE DEVIL":[3],
    "STEAL SOMEONE'S THUNDER":[2],
    "STRAIGHT FROM THE HORSE'S MOUTH":[3],
    "A PICTURE PAINTS A THOUSAND WORDS":[4],
    "HIT THE NAIL ON THE HEAD":[2],
    "EVERY CLOUD HAS A SILVER LINING":[4],
    "DON'T JUDGE A BOOK BY IT'S COVER":[3],
    "EVERYTHING BUT THE KITCHEN SINK":[3]

}

/* selects a random sentence from the remaining possible sentences
 * and returns an array containing both the sentence as a string
 * and the indices of the words that should be converted to gifs
 */
function getRandomSentence(possible_sentences) {

    var key = getRandomKey(possible_sentences);
    var value = possible_sentences[key];
    // remove used key so we don't repeat puzzles (TODO)
    return [key, value];
}

function getRandomKey (sentences) {
    var result;
    var count = 0;
    for (var prop in sentences)
        if (Math.random() < 1/++count)
           result = prop;
    return result;
}

function display_puzzle () {
    /* gets random sentence
     * iterates through sentence:
     * if word is regular word: put it in body of html
     * if word should be gif:
     *          convert to gif, display in body of html
     *
     * create appropriate text boxes for answers
     * returns answers to puzzle, to be checked by other function
     */

    // sentence will be an array containing a string and an array of integers
    var sentence = getRandomSentence(sentences);
    var words = sentence[0].split(" ");
    console.log("sentence is" + words);
    console.log(words[0]);

    /*
     *for (index in sentence[1]) {
     *    answers.append(words[index]);
     *}
     */

    // redefines global variable 'answer'
    answer = words[sentence[1][0]];
    var answer_index = sentence[1][0];
    console.log("answer = " + answer);

    //var toDisplay = [];
    text_before = "";
    for(i = 0; i < answer_index; i++) {
        text_before = text_before + words[i] + " ";
    }
    $('#question-before').html(function() { return text_before});
    search_term = words[answer_index];
    display_image(search_term);

    text_after = "";
    for(i = answer_index + 1; i < words.length; i++) {
        text_after = text_after + words[i] + " ";
    }
    $('#question-after').html(function() { return text_after});

    delete sentences[sentence[0]];

    /*
     *for(i = 0; i < words.length; i++) {
     *    if (words[i] == answer) {
     *        console.log("word = " + words[i]);
     *        display_image(words[i]);
     *    }
     *    else
     *        newQuestion(words[i]);
     *
     *}
     */
}

<commit_msg>fixed first cat<commit_after>var temp;
var random;
var img;
var answer = "CATS";
var text_before = "IT'S RAINING";
var text_after = "AND DOGS";

// This function is called when the user submits an answer
//

$(document).ready(function(){
    $('#search_tag').keypress(function(e){
      if(e.keyCode==13)
      $("button").click()(function(){
        var user_response = document.getElementById("search_tag").value;
        user_response = user_response.toUpperCase();
        if(user_response == answer){
            $('#score').html(function(i, val) {
                return val*1+1 });
            cleartext();
            clearimage();
            $('#correct').show();
            $( "#correct" ).fadeOut( 5000, function() {
            });
            display_puzzle();
        }
        else{
            document.getElementById("search_tag").value = "";
            clearimage();
            $('#wrong').show();
            $( "#wrong" ).fadeOut( 5000, function() {
            });
            display_image(search_term);
        }
      })
    });
});
$(document).ready(function() {
    $("button").click(function() {
        var user_response = document.getElementById("search_tag").value;
        user_response = user_response.toUpperCase();
        if(user_response == answer){
            $('#score').html(function(i, val) { return val*1+1 });
            cleartext();
            clearimage();
            $('#correct').show();
            $( "#correct" ).fadeOut( 5000, function() {
            });
            display_puzzle();
        }
        else{
            document.getElementById("search_tag").value = "";
            clearimage();
            $('#wrong').show();
            $( "#wrong" ).fadeOut( 5000, function() {
            });
            display_image(search_term);
        }

    });
});

function cleartext(){
    document.getElementById("search_tag").value = "";
}

function clearimage() {
    document.getElementById("gif-place").removeChild(img);
}

function newQuestion(text){
    $('#question').html(function() { return text });
}

function getRandom() {
    return Math.floor((Math.random() * 25));
}

function display_image(search_term){
    var counter = 0;
    console.log("search_term = " + search_term);
    if(counter == 0)
        ;
    else
        answer = search_term;
    var xhr = $.get("http://api.giphy.com/v1/gifs/search?q=" + answer + "&api_key=dc6zaTOxFJmzC&limit=25");
        xhr.done(
            function(response) {
            temp = response;
            console.log(temp);
            console.log("success got data", response);
            //var select_gif = response.data[random].images.original;
            show_image(response);
        });
}

function show_image(image_object) {

    //console.log(height, width);
    random = getRandom();
    //var width = image_object.data[random].images.original.width;
    //var height = image_object.data[random].images.original.height;
    var source = image_object.data[random].images.original.url;
    //var resized = resize(height, width);

    //height = resized[0];
    //width = resized[1];
    //console.log(height, width);

    img = document.createElement("img");
    img.src = source;
    img.width = 400; //temp.data[random].images.original.width;
    img.height = 400; //temp.data[random].images.original.height;
    img.alt = "Guess the word!";
    document.getElementById("gif-place").appendChild(img);
}

// resize is deprecated bc we chose to have all gifs be the same size for consistency's sake
/*
 *function resize(height, width) {
 *
 *    console.log(height, width);
 *
 *    var MAX_HEIGHT = 400;
 *    var MAX_WIDTH = 400;
 *
 *    var gcd = get_gcd(height, width);
 *
 *    console.log("gcd = " + gcd);
 *    width = width / gcd;
 *    height = height / gcd;
 *
 *    var width_mult = MAX_WIDTH / width;
 *    var height_mult = MAX_HEIGHT / height;
 *    var multiplier = Math.min(width_mult, height_mult);
 *    console.log("multiplier = " + multiplier);
 *    width = width * multiplier;
 *    height = height * multiplier;
 *    console.log(height, width);
 *    return [height, width];
 *}
 */

function get_gcd (a, b) {
    if ( ! b) {
        return a;
    }
    return get_gcd(b, a % b);
};

/*
 *  THIS IS FOR SPACE
 *
 */

var sentences = {
    "ROSES ARE RED": [0],
    "A BARREL OF MONKEYS":[3],
    "IT'S RAINING CATS AND DOGS":[2],
    "AS STUBBORN AS AN OX":[4],
    "TALLER THAN A TREE":[3],
    "IT TAKES TWO TO TANGO":[4],
    "HAVE YOUR CAKE AND EAT IT TOO":[2],
    "ELVIS HAS LEFT THE BUILDING":[0],
    "IN THE HEAT OF THE MOMENT":[2],
    "KILL TWO BIRDS WITH ONE STONE":[2],
    "SPEAK OF THE DEVIL":[3],
    "STEAL SOMEONE'S THUNDER":[2],
    "STRAIGHT FROM THE HORSE'S MOUTH":[3],
    "A PICTURE PAINTS A THOUSAND WORDS":[4],
    "HIT THE NAIL ON THE HEAD":[2],
    "EVERY CLOUD HAS A SILVER LINING":[4],
    "DON'T JUDGE A BOOK BY IT'S COVER":[3],
    "EVERYTHING BUT THE KITCHEN SINK":[3]

}

/* selects a random sentence from the remaining possible sentences
 * and returns an array containing both the sentence as a string
 * and the indices of the words that should be converted to gifs
 */
function getRandomSentence(possible_sentences) {

    var key = getRandomKey(possible_sentences);
    var value = possible_sentences[key];
    // remove used key so we don't repeat puzzles (TODO)
    return [key, value];
}

function getRandomKey (sentences) {
    var result;
    var count = 0;
    for (var prop in sentences)
        if (Math.random() < 1/++count)
           result = prop;
    return result;
}

function display_puzzle () {
    /* gets random sentence
     * iterates through sentence:
     * if word is regular word: put it in body of html
     * if word should be gif:
     *          convert to gif, display in body of html
     *
     * create appropriate text boxes for answers
     * returns answers to puzzle, to be checked by other function
     */

    // sentence will be an array containing a string and an array of integers
    var sentence = getRandomSentence(sentences);
    var words = sentence[0].split(" ");
    console.log("sentence is" + words);
    console.log(words[0]);

    /*
     *for (index in sentence[1]) {
     *    answers.append(words[index]);
     *}
     */

    // redefines global variable 'answer'
    answer = words[sentence[1][0]];
    var answer_index = sentence[1][0];
    console.log("answer = " + answer);

    //var toDisplay = [];
    text_before = "";
    for(i = 0; i < answer_index; i++) {
        text_before = text_before + words[i] + " ";
    }
    $('#question-before').html(function() { return text_before});
    search_term = words[answer_index];
    display_image(search_term);

    text_after = "";
    for(i = answer_index + 1; i < words.length; i++) {
        text_after = text_after + words[i] + " ";
    }
    $('#question-after').html(function() { return text_after});

    delete sentences[sentence[0]];

    /*
     *for(i = 0; i < words.length; i++) {
     *    if (words[i] == answer) {
     *        console.log("word = " + words[i]);
     *        display_image(words[i]);
     *    }
     *    else
     *        newQuestion(words[i]);
     *
     *}
     */
}

<|endoftext|>


<commit_before>import { assign } from "lodash";

// *
// * Colors
// *
const yellow200 = "#FFF59D";
const deepOrange600 = "#F4511E";
const lime300 = "#DCE775";
const lightGreen500 = "#8BC34A";
const teal700 = "#00796B";
const cyan900 = "#006064";
const colors = [
  deepOrange600,
  yellow200,
  lime300,
  lightGreen500,
  teal700,
  cyan900
];
const blueGrey50 = "#ECEFF1";
const blueGrey300 = "#90A4AE";
const blueGrey700 = "#455A64";
const grey900 = "#212121";
// *
// * Typography
// *
const sansSerif = "'Roboto', 'Helvetica Neue', Helvetica, sans-serif";
const letterSpacing = "normal";
const fontSize = 12;
// *
// * Layout
// *
const padding = 8;
const baseProps = {
  width: 350,
  height: 350
};
// *
// * Labels
// *
const baseLabelStyles = {
  fontFamily: sansSerif,
  fontSize,
  letterSpacing,
  padding,
  fill: blueGrey700
};
// *
// * Strokes
// *
const strokeDasharray = "10, 5";
const strokeLinecap = "round";
const strokeLinejoin = "round";

export default {
  area: {
    data: {
      fill: grey900
    },
    labels: baseLabelStyles,
    parent: {}
  },
  axis: {
    axis: {
      fill: "none",
      stroke: blueGrey300,
      strokeWidth: 2,
      strokeLinecap,
      strokeLinejoin
    },
    axisLabel: assign({}, baseLabelStyles,
      {
        padding,
        stroke: "transparent"
      }),
    grid: {
      fill: "none",
      stroke: blueGrey50,
      strokeDasharray,
      strokeLinecap,
      strokeLinejoin
    },
    ticks: {
      fill: "none",
      padding,
      size: 5,
      stroke: blueGrey300,
      strokeWidth: 1,
      strokeLinecap,
      strokeLinejoin
    },
    tickLabels: assign({}, baseLabelStyles,
      {
        fill: blueGrey700,
        stroke: "transparent"
      })
  },
  bar: {
    data: {
      fill: blueGrey700,
      opacity: 1,
      padding,
      stroke: "transparent",
      strokeWidth: 0,
      width: 5
    },
    labels: baseLabelStyles,
    parent: {}
  },
  candlestick: {
    data: {
      stroke: blueGrey700
    },
    labels: baseLabelStyles,
    parent: {},
    props: assign({}, baseProps,
      {
        candeColors: {
          positive: "#ffffff",
          negative: blueGrey700
        }
      })
  },
  errorbar: {
    data: {
      fill: "none",
      opacity: 1,
      stroke: blueGrey700,
      strokeWidth: 2
    },
    labels: assign({}, baseLabelStyles,
      {
        stroke: "transparent",
        strokeWidth: 0,
        textAnchor: "start"
      }),
    parent: {}
  },
  line: {
    data: {
      fill: "none",
      opacity: 1,
      stroke: blueGrey700,
      strokeWidth: 2
    },
    labels: assign({}, baseLabelStyles,
      {
        stroke: "transparent",
        strokeWidth: 0,
        textAnchor: "start"
      }),
    parent: {}
  },
  pie: {
    props: assign({}, baseProps,
      {
        colorScale: colors
      }),
    style: {
      data: {
        padding,
        stroke: blueGrey50,
        strokeWidth: 1
      },
      labels: assign({}, baseLabelStyles,
        {
          padding: 200,
          stroke: "transparent",
          strokeWidth: 0,
          textAnchor: "middle"
        }),
      parent: {}
    }
  },
  scatter: {
    data: {
      fill: blueGrey700,
      opacity: 1,
      stroke: "transparent",
      strokeWidth: 0
    },
    labels: Object.assign({}, baseLabelStyles,
      {
        stroke: "transparent",
        textAnchor: "middle"
      }),
    parent: {}
  },
  props: Object.assign({}, baseProps,
    {
      colorScale: colors
    }
  )
};
<commit_msg>fix candleColors typo<commit_after>import { assign } from "lodash";

// *
// * Colors
// *
const yellow200 = "#FFF59D";
const deepOrange600 = "#F4511E";
const lime300 = "#DCE775";
const lightGreen500 = "#8BC34A";
const teal700 = "#00796B";
const cyan900 = "#006064";
const colors = [
  deepOrange600,
  yellow200,
  lime300,
  lightGreen500,
  teal700,
  cyan900
];
const blueGrey50 = "#ECEFF1";
const blueGrey300 = "#90A4AE";
const blueGrey700 = "#455A64";
const grey900 = "#212121";
// *
// * Typography
// *
const sansSerif = "'Roboto', 'Helvetica Neue', Helvetica, sans-serif";
const letterSpacing = "normal";
const fontSize = 12;
// *
// * Layout
// *
const padding = 8;
const baseProps = {
  width: 350,
  height: 350
};
// *
// * Labels
// *
const baseLabelStyles = {
  fontFamily: sansSerif,
  fontSize,
  letterSpacing,
  padding,
  fill: blueGrey700
};
// *
// * Strokes
// *
const strokeDasharray = "10, 5";
const strokeLinecap = "round";
const strokeLinejoin = "round";

export default {
  area: {
    data: {
      fill: grey900
    },
    labels: baseLabelStyles,
    parent: {}
  },
  axis: {
    axis: {
      fill: "none",
      stroke: blueGrey300,
      strokeWidth: 2,
      strokeLinecap,
      strokeLinejoin
    },
    axisLabel: assign({}, baseLabelStyles,
      {
        padding,
        stroke: "transparent"
      }),
    grid: {
      fill: "none",
      stroke: blueGrey50,
      strokeDasharray,
      strokeLinecap,
      strokeLinejoin
    },
    ticks: {
      fill: "none",
      padding,
      size: 5,
      stroke: blueGrey300,
      strokeWidth: 1,
      strokeLinecap,
      strokeLinejoin
    },
    tickLabels: assign({}, baseLabelStyles,
      {
        fill: blueGrey700,
        stroke: "transparent"
      })
  },
  bar: {
    data: {
      fill: blueGrey700,
      opacity: 1,
      padding,
      stroke: "transparent",
      strokeWidth: 0,
      width: 5
    },
    labels: baseLabelStyles,
    parent: {}
  },
  candlestick: {
    data: {
      stroke: blueGrey700
    },
    labels: baseLabelStyles,
    parent: {},
    props: assign({}, baseProps,
      {
        candleColors: {
          positive: "#ffffff",
          negative: blueGrey700
        }
      })
  },
  errorbar: {
    data: {
      fill: "none",
      opacity: 1,
      stroke: blueGrey700,
      strokeWidth: 2
    },
    labels: assign({}, baseLabelStyles,
      {
        stroke: "transparent",
        strokeWidth: 0,
        textAnchor: "start"
      }),
    parent: {}
  },
  line: {
    data: {
      fill: "none",
      opacity: 1,
      stroke: blueGrey700,
      strokeWidth: 2
    },
    labels: assign({}, baseLabelStyles,
      {
        stroke: "transparent",
        strokeWidth: 0,
        textAnchor: "start"
      }),
    parent: {}
  },
  pie: {
    props: assign({}, baseProps,
      {
        colorScale: colors
      }),
    style: {
      data: {
        padding,
        stroke: blueGrey50,
        strokeWidth: 1
      },
      labels: assign({}, baseLabelStyles,
        {
          padding: 200,
          stroke: "transparent",
          strokeWidth: 0,
          textAnchor: "middle"
        }),
      parent: {}
    }
  },
  scatter: {
    data: {
      fill: blueGrey700,
      opacity: 1,
      stroke: "transparent",
      strokeWidth: 0
    },
    labels: Object.assign({}, baseLabelStyles,
      {
        stroke: "transparent",
        textAnchor: "middle"
      }),
    parent: {}
  },
  props: Object.assign({}, baseProps,
    {
      colorScale: colors
    }
  )
};
<|endoftext|>


<commit_before>(function (Framework7, $$, T7, moment, hnapi) {
	'use strict';

	// Helpers
	T7.registerHelper('time_ago', function (time) {
		return moment.unix(time).fromNow();
	});
	T7.registerHelper('array_length', function (arr) {
		return arr ? arr.length : 0;
	});

	// Init App
	var app = new Framework7({
		modalTitle: 'HackerNews7',

		animateNavBackIcon: true,

		precompileTemplates: true,
		template7Pages: true
	});

	// Add View
	var mainView = app.addView('.view-main', {
		dynamicNavbar: true
	});

	// Update data
	function updateStories(stories) {
		app.template7Data.stories = stories;
		$$('.page[data-page="index"] .page-content .list-block').html(T7.templates.storiesTemplate(stories));
	}
	// Fetch Stories
	function getStories(refresh) {
		var results = refresh ? [] : JSON.parse(window.localStorage.getItem('stories')) || [];
		if (results.length === 0) {
			if (!refresh) app.showIndicator();
			hnapi.topStories(function (data) {
				data = JSON.parse(data);
				data.forEach(function(id) {
					hnapi.item(id, function(data) {
						data = JSON.parse(data);
						data.domain = data.url.split('/')[2];
						results.push(data);
						if (results.length === 100) {
							if (!refresh) app.hideIndicator();
							// Update local storage data
							window.localStorage.setItem('stories', JSON.stringify(results));
							// PTR Done
							app.pullToRefreshDone();
							// Clear searchbar
							$$('.searchbar-input input')[0].value = '';
							// Update T7 data and render home page stories
							updateStories(results);
						}
					});
				});
			});
		}
		else {
			// Update T7 data and render home page stories
			updateStories(results);
		}
		return results;
	}

	// Update stories on PTR
	$$('.pull-to-refresh-content').on('refresh', function () {
		getStories(true);
	});

	// Comments
	var allowCommentsInsert;
	app.onPageAfterAnimation('item', function (page) {
		allowCommentsInsert = true;
		var id = $$(page.container).attr('data-story-id');
		var comments = [];
		var story;
		for (var i = 0; i < app.template7Data.stories.length; i++) {
			if (app.template7Data.stories[i].id === parseInt(id, 10)) {
				story = app.template7Data.stories[i];
			}
		}
		var commentsCount = 0;
		story.kids.forEach(function (child) {
			hnapi.item(child, function(data) {
				var comment = JSON.parse(data);
				if (comment.text && comment.text.length && !comment.deleted) comments.push(comment);
				commentsCount ++;

				$$(page.container).find('.preloader-progress').text(Math.floor(commentsCount/story.kids.length*100));
				if (commentsCount === story.kids.length && allowCommentsInsert) {
					$$(page.container).find('.story-comments .messages').html(T7.templates.commentsTemplate(comments));
				}
			});
		});
	});
	app.onPageBack('item', function () {
		allowCommentsInsert = false;
	});
	$$(document).on('click', '.message a', function (e) {
		window.open($$(this).attr('href'));
	});

	// Get and parse stories on app load
	getStories();

	// Export app to global
	window.app = app;

})(Framework7, Dom7, Template7, moment, hnapi);<commit_msg>fixes console error on story without comment<commit_after>(function (Framework7, $$, T7, moment, hnapi) {
	'use strict';

	// Helpers
	T7.registerHelper('time_ago', function (time) {
		return moment.unix(time).fromNow();
	});
	T7.registerHelper('array_length', function (arr) {
		return arr ? arr.length : 0;
	});

	// Init App
	var app = new Framework7({
		modalTitle: 'HackerNews7',

		animateNavBackIcon: true,

		precompileTemplates: true,
		template7Pages: true
	});

	// Add View
	var mainView = app.addView('.view-main', {
		dynamicNavbar: true
	});

	// Update data
	function updateStories(stories) {
		app.template7Data.stories = stories;
		$$('.page[data-page="index"] .page-content .list-block').html(T7.templates.storiesTemplate(stories));
	}
	// Fetch Stories
	function getStories(refresh) {
		var results = refresh ? [] : JSON.parse(window.localStorage.getItem('stories')) || [];
		if (results.length === 0) {
			if (!refresh) app.showIndicator();
			hnapi.topStories(function (data) {
				data = JSON.parse(data);
				data.forEach(function(id) {
					hnapi.item(id, function(data) {
						data = JSON.parse(data);
						data.domain = data.url.split('/')[2];
						results.push(data);
						if (results.length === 100) {
							if (!refresh) app.hideIndicator();
							// Update local storage data
							window.localStorage.setItem('stories', JSON.stringify(results));
							// PTR Done
							app.pullToRefreshDone();
							// Clear searchbar
							$$('.searchbar-input input')[0].value = '';
							// Update T7 data and render home page stories
							updateStories(results);
						}
					});
				});
			});
		}
		else {
			// Update T7 data and render home page stories
			updateStories(results);
		}
		return results;
	}

	// Update stories on PTR
	$$('.pull-to-refresh-content').on('refresh', function () {
		getStories(true);
	});

	// Comments
	var allowCommentsInsert;
	app.onPageAfterAnimation('item', function (page) {
		allowCommentsInsert = true;
		var id = $$(page.container).attr('data-story-id');
		var comments = [];
		var story;
		for (var i = 0; i < app.template7Data.stories.length; i++) {
			if (app.template7Data.stories[i].id === parseInt(id, 10)) {
				story = app.template7Data.stories[i];
			}
		}
		var commentsCount = 0;
		if(story.kids) {
			story.kids.forEach(function (child) {
				hnapi.item(child, function(data) {
					var comment = JSON.parse(data);
					if (comment.text && comment.text.length && !comment.deleted) comments.push(comment);
					commentsCount ++;

					$$(page.container).find('.preloader-progress').text(Math.floor(commentsCount/story.kids.length*100));
					if (commentsCount === story.kids.length && allowCommentsInsert) {
						$$(page.container).find('.story-comments .messages').html(T7.templates.commentsTemplate(comments));
					}
				});
			});
		} else {
			$$(page.container).find('.story-comments .messages').html('
No comment
');
		}
	});
	app.onPageBack('item', function () {
		allowCommentsInsert = false;
	});
	$$(document).on('click', '.message a', function (e) {
		window.open($$(this).attr('href'));
	});

	// Get and parse stories on app load
	getStories();

	// Export app to global
	window.app = app;

})(Framework7, Dom7, Template7, moment, hnapi);<|endoftext|>


<commit_before><script>
function aa(a){
	return a+3;
}

console.log("11");

</script>
<commit_msg>js update 4 add<commit_after><script>
function aa(a){
	return a+3;
}

console.log("11");

var a;
var b;
</script>
<|endoftext|>


<commit_before>import {useRef} from 'react';
import {  DragPreviewImage, useDrag } from 'react-dnd';
import Color from 'color';
import Typography from '@material-ui/core/Typography';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import IconButton from '@material-ui/core/IconButton';
import Checkbox from '@material-ui/core/Checkbox';
import PersonIcon from '@material-ui/icons/Person';
import GroupIcon from '@material-ui/icons/Group';
import ClearIcon from '@material-ui/icons/Clear';
import EditIcon from '@material-ui/icons/Edit';
import DeleteIcon from '@material-ui/icons/Delete';

function UserBlock(props) {
    const opacity = props.isDragging ? 0.4 : 1;

    let textColor = !props.user ||  !props.user.common || !props.user.common.color || Color(props.user.common.color).hsl().object().l > 50 ? '#000000' : '#FFFFFF';
    if (!props.user.common.color) {
        textColor = null;
    }
    let style = { cursor: 'grab', opacity, overflow: 'hidden', color: textColor }
    if( props.user.common.color )
    {
        style.backgroundColor = props.user.common.color;
    }
    return <>
    {/* <DragPreviewImage connect={preview}/> */}
    <Card
        style={ style }
        className={props.classes.userGroupCard2}

    >

                <Checkbox
                    checked={props.user.common.enabled}
                    style={{ color: textColor }}
                    disabled={props.user.common.dontDelete}
                    onChange={e => {
                        props.socket.extendObject(
                            props.user._id,
                            { common: {
                                enabled: !props.user.common.enabled
                            }
                        }).then(()=>
                            props.updateData()
                        );
                    }
                }/>
                <IconButton
                    size="small"
                    onClick={()=>{props.showUserEditDialog(props.user, false)}}
                >
                    <EditIcon style={{ color: textColor }} />
                </IconButton>
                <IconButton
                    size="small"
                    onClick={()=>{props.showUserDeleteDialog(props.user)}}
                    disabled={props.user.common.dontDelete}
                >
                    <DeleteIcon style={props.user.common.dontDelete ? null : { color: textColor }} />
                </IconButton>

            <CardContent>
                <Typography gutterBottom component="div" className={props.classes.userGroupTitle}>
                    {
                        props.user.common.icon
                            ?

                            :
                            <PersonIcon className={props.classes.icon} />
                    }

                                {props.getName(props.user.common.name)}

                                {props.getName(props.user._id)}

                        {
                            props.user.common.desc !== ''
                                ?

                                    {props.user.common.desc}

                                :
                                null
                        }

                </Typography>
                {props.groups.find(group => group.common.members && group.common.members.includes(props.user._id)) ?

{props.t('In groups')}:
 :
                null}

                    {props.groups.map(group =>
                        group.common.members && group.common.members.includes(props.user._id) ?
                        <Card
                            key={group._id}
                            variant="outlined"
                            className={props.classes.userGroupMember}
                            style={{ color: textColor, borderColor: textColor + '40' }}
                        >
                            {
                                group.common.icon
                                    ?

                                    :
                                    <GroupIcon className={props.classes.icon} />
                                }
                            {props.getName(group.common.name)}
                            <IconButton
                                size="small"
                                onClick={() => props.removeUserFromGroup(props.user._id, group._id)}
                            >
                                <ClearIcon  style={{ color: textColor }} />
                            </IconButton>
                        </Card> :
                        null
                    )}

            </CardContent>

    </Card>
    </>
}

const UserBlockDrag = (props) => {
    const widthRef = useRef();
    const [{ isDragging }, dragRef, preview] = useDrag(
        {
            type: 'user',
            item: () => {return {userId: props.user._id, preview:
<UserBlock {...props}/>
}},
            end: (item, monitor) => {
                const dropResult = monitor.getDropResult();
                if (item && dropResult) {
                    props.addUserToGroup(item.userId, dropResult.groupId);
                }
            },
            collect: (monitor) => ({
                isDragging: monitor.isDragging(),
                handlerId: monitor.getHandlerId(),
            }),
        }
    );
    return

            <UserBlock isDragging={isDragging} widthRef={widthRef} {...props}/>

}

export default UserBlockDrag;<commit_msg>dnd preview<commit_after>import {useRef, useEffect} from 'react';
import {  DragPreviewImage, useDrag } from 'react-dnd';
import { getEmptyImage } from 'react-dnd-html5-backend';
import Color from 'color';
import Typography from '@material-ui/core/Typography';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import IconButton from '@material-ui/core/IconButton';
import Checkbox from '@material-ui/core/Checkbox';
import PersonIcon from '@material-ui/icons/Person';
import GroupIcon from '@material-ui/icons/Group';
import ClearIcon from '@material-ui/icons/Clear';
import EditIcon from '@material-ui/icons/Edit';
import DeleteIcon from '@material-ui/icons/Delete';

function UserBlock(props) {
    const opacity = props.isDragging ? 0.4 : 1;

    let textColor = !props.user ||  !props.user.common || !props.user.common.color || Color(props.user.common.color).hsl().object().l > 50 ? '#000000' : '#FFFFFF';
    if (!props.user.common.color) {
        textColor = null;
    }
    let style = { cursor: 'grab', opacity, overflow: 'hidden', color: textColor }
    if( props.user.common.color )
    {
        style.backgroundColor = props.user.common.color;
    }
    return <>
    {/* <DragPreviewImage connect={preview}/> */}
    <Card
        style={ style }
        className={props.classes.userGroupCard2}

    >

                <Checkbox
                    checked={props.user.common.enabled}
                    style={{ color: textColor }}
                    disabled={props.user.common.dontDelete}
                    onChange={e => {
                        props.socket.extendObject(
                            props.user._id,
                            { common: {
                                enabled: !props.user.common.enabled
                            }
                        }).then(()=>
                            props.updateData()
                        );
                    }
                }/>
                <IconButton
                    size="small"
                    onClick={()=>{props.showUserEditDialog(props.user, false)}}
                >
                    <EditIcon style={{ color: textColor }} />
                </IconButton>
                <IconButton
                    size="small"
                    onClick={()=>{props.showUserDeleteDialog(props.user)}}
                    disabled={props.user.common.dontDelete}
                >
                    <DeleteIcon style={props.user.common.dontDelete ? null : { color: textColor }} />
                </IconButton>

            <CardContent>
                <Typography gutterBottom component="div" className={props.classes.userGroupTitle}>
                    {
                        props.user.common.icon
                            ?

                            :
                            <PersonIcon className={props.classes.icon} />
                    }

                                {props.getName(props.user.common.name)}

                                {props.getName(props.user._id)}

                        {
                            props.user.common.desc !== ''
                                ?

                                    {props.user.common.desc}

                                :
                                null
                        }

                </Typography>
                {props.groups.find(group => group.common.members && group.common.members.includes(props.user._id)) ?

{props.t('In groups')}:
 :
                null}

                    {props.groups.map(group =>
                        group.common.members && group.common.members.includes(props.user._id) ?
                        <Card
                            key={group._id}
                            variant="outlined"
                            className={props.classes.userGroupMember}
                            style={{ color: textColor, borderColor: textColor + '40' }}
                        >
                            {
                                group.common.icon
                                    ?

                                    :
                                    <GroupIcon className={props.classes.icon} />
                                }
                            {props.getName(group.common.name)}
                            <IconButton
                                size="small"
                                onClick={() => props.removeUserFromGroup(props.user._id, group._id)}
                            >
                                <ClearIcon  style={{ color: textColor }} />
                            </IconButton>
                        </Card> :
                        null
                    )}

            </CardContent>

    </Card>
    </>
}

const UserBlockDrag = (props) => {
    const widthRef = useRef();
    const [{ isDragging }, dragRef, preview] = useDrag(
        {
            type: 'user',
            item: () => {return {userId: props.user._id, preview:
<UserBlock {...props}/>
}},
            end: (item, monitor) => {
                const dropResult = monitor.getDropResult();
                if (item && dropResult) {
                    props.addUserToGroup(item.userId, dropResult.groupId);
                }
            },
            collect: (monitor) => ({
                isDragging: monitor.isDragging(),
                handlerId: monitor.getHandlerId(),
            }),
        }
    );
    useEffect(() => {
        preview(getEmptyImage(), { captureDraggingState: true });
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);
    return

            <UserBlock isDragging={isDragging} widthRef={widthRef} {...props}/>

}

export default UserBlockDrag;<|endoftext|>


<commit_before>// Copyright 2015 Volker Sorge
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Abstract class implementation of the walker interface.
 *
 * @author volker.sorge@gmail.com (Volker Sorge)
 */

goog.provide('sre.AbstractWalker');

goog.require('sre.EnrichMathml');
goog.require('sre.EventUtil.KeyCode');
goog.require('sre.Focus');
goog.require('sre.WalkerUtil');
goog.require('sre.WalkerInterface');

/**
 * @constructor
 * @implements {sre.WalkerInterface}
 * @param {!Node} node The node on which the walker is called.
 * @param {!sre.SpeechGeneratorInterface} generator The speech generator for
 *     this walker.
 * @override
 */
sre.AbstractWalker = function(node, generator) {
  /**
   * The math expression on which the walker is called.
   * @type {!Node}
   */
  this.node = node;

  /**
   * @type {!sre.SpeechGeneratorInterface}
   */
  this.generator = generator;

  /**
   * @type {boolean}
   * @private
   */
  this.active_ = false;

  /**
   * @type {Object.<sre.EventUtil.KeyCode, function()>}
   * @private
   */
  this.keyMapping_ = {};
  this.keyMapping_[sre.EventUtil.KeyCode.UP] = goog.bind(this.up, this);
  this.keyMapping_[sre.EventUtil.KeyCode.DOWN] = goog.bind(this.down, this);
  this.keyMapping_[sre.EventUtil.KeyCode.RIGHT] = goog.bind(this.right, this);
  this.keyMapping_[sre.EventUtil.KeyCode.LEFT] = goog.bind(this.left, this);

  this.dummy_ = function() {};
  this.keyMapping_[sre.EventUtil.KeyCode.TAB] = goog.bind(this.dummy_, this);
  this.keyMapping_[sre.EventUtil.KeyCode.ENTER] = goog.bind(this.dummy_, this);
  this.keyMapping_[sre.EventUtil.KeyCode.SPACE] = goog.bind(this.dummy_, this);

  var rootNode = this.getRoot_(node);
  /**
   * The node that currently inspected. Initially this is the entire math
   * expression.
   * @type {!sre.Focus}
   * @private
   */
  this.focus_ = new sre.Focus({nodes: [rootNode], primary: rootNode});

};

/**
 * @override
 */
sre.AbstractWalker.prototype.isActive = function() {
  return this.active_;
};

/**
 * Toggles the activity indicator of the walker.
 * @private
 */
sre.AbstractWalker.prototype.toggleActive_ = function() {
  this.active_ = !this.active_;
};

/**
 * @override
 */
sre.AbstractWalker.prototype.activate = function() {
  if (this.isActive()) {
    return;
  }
  this.generator.start();
  this.toggleActive_();
};

/**
 * @override
 */
sre.AbstractWalker.prototype.deactivate = function() {
  if (!this.isActive()) {
    return;
  }
  this.generator.end();
  this.toggleActive_();
};

/**
 * @override
 */
sre.AbstractWalker.prototype.getFocus = function() {
  return this.focus_;
};

/**
 * @override
 */
sre.AbstractWalker.prototype.speech = function() {
  return this.focus_.getNodes().map(
      goog.bind(function(x) {return this.generator.getSpeech(x);}, this))
      .join(' ');
};

/**
 * @override
 */
sre.AbstractWalker.prototype.move = function(key) {
  var direction = this.keyMapping_[key];
  if (!direction) {
    return null;
  }
  var focus = direction();
  if (!focus || focus === this.focus_) {
    return false;
  }
  this.focus_ = focus;
  return true;
};

/**
 * Moves up from the current node if possible.
 * @return {?sre.Focus}
 * @protected
 */
sre.AbstractWalker.prototype.up = goog.abstractMethod;

/**
 * Moves down from the current node if possible.
 * @return {?sre.Focus}
 * @protected
 */
sre.AbstractWalker.prototype.down = goog.abstractMethod;

/**
 * Moves left from the current node if possible.
 * @return {?sre.Focus}
 * @protected
 */
sre.AbstractWalker.prototype.left = goog.abstractMethod;

/**
 * Moves right from the current node if possible.
 * @return {?sre.Focus}
 * @protected
 */
sre.AbstractWalker.prototype.right = goog.abstractMethod;

/**
 * Retrieves the root node of the semantic tree.
 * @param {!Node} node The math node.
 * @return {!Node} The root node. If we cannot find one, the input node is
 *     returned.
 * @private
 */
sre.AbstractWalker.prototype.getRoot_ = function(node) {
  if (node.hasAttribute(sre.EnrichMathml.Attribute.SPEECH) &&
      !node.hasAttribute(sre.EnrichMathml.Attribute.PARENT)) {
    return node;
  }
  var speechNodes = node.querySelectorAll(
      '[' + sre.EnrichMathml.Attribute.SPEECH + ']');
  for (var i = 0, speechNode; speechNode = speechNodes[i]; i++) {
    if (!speechNode.hasAttribute(sre.EnrichMathml.Attribute.PARENT)) {
      return speechNode;
    }
  }
  return node;
};

/**
 * Retrieves a node containing a given semantic id.
 * @param {string} id The id of a semantic node.
 * @return {Node} The node for that id.
 */
sre.AbstractWalker.prototype.getBySemanticId = function(id) {
  var query = '[' + sre.EnrichMathml.Attribute.ID + '="' + id + '"]';
  return this.node.querySelector(query);
};

/**
 * Retrieves an attribute from the primary focused node if it exists.
 * @param {sre.EnrichMathml.Attribute} attr The attribute to retrieves.
 * @return {string} The value of the attribute for the primary node of the
 *     focus.
 */
sre.AbstractWalker.prototype.primaryAttribute = function(attr) {
  var primary = this.focus_.getPrimary();
  return primary ? sre.WalkerUtil.getAttribute(primary, attr) : '';
};

/**
 * @return {string} The id of the primary node of the current focus.
 */
sre.AbstractWalker.prototype.primaryId = function() {
  return this.primaryAttribute(sre.EnrichMathml.Attribute.ID);
};
<commit_msg>Removes dependecy on speech attribute for semantic root finding.<commit_after>// Copyright 2015 Volker Sorge
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Abstract class implementation of the walker interface.
 *
 * @author volker.sorge@gmail.com (Volker Sorge)
 */

goog.provide('sre.AbstractWalker');

goog.require('sre.EnrichMathml');
goog.require('sre.EventUtil.KeyCode');
goog.require('sre.Focus');
goog.require('sre.WalkerUtil');
goog.require('sre.WalkerInterface');

/**
 * @constructor
 * @implements {sre.WalkerInterface}
 * @param {!Node} node The node on which the walker is called.
 * @param {!sre.SpeechGeneratorInterface} generator The speech generator for
 *     this walker.
 * @override
 */
sre.AbstractWalker = function(node, generator) {
  /**
   * The math expression on which the walker is called.
   * @type {!Node}
   */
  this.node = node;

  /**
   * @type {!sre.SpeechGeneratorInterface}
   */
  this.generator = generator;

  /**
   * @type {boolean}
   * @private
   */
  this.active_ = false;

  /**
   * @type {Object.<sre.EventUtil.KeyCode, function()>}
   * @private
   */
  this.keyMapping_ = {};
  this.keyMapping_[sre.EventUtil.KeyCode.UP] = goog.bind(this.up, this);
  this.keyMapping_[sre.EventUtil.KeyCode.DOWN] = goog.bind(this.down, this);
  this.keyMapping_[sre.EventUtil.KeyCode.RIGHT] = goog.bind(this.right, this);
  this.keyMapping_[sre.EventUtil.KeyCode.LEFT] = goog.bind(this.left, this);

  this.dummy_ = function() {};
  this.keyMapping_[sre.EventUtil.KeyCode.TAB] = goog.bind(this.dummy_, this);
  this.keyMapping_[sre.EventUtil.KeyCode.ENTER] = goog.bind(this.dummy_, this);
  this.keyMapping_[sre.EventUtil.KeyCode.SPACE] = goog.bind(this.dummy_, this);

  var rootNode = this.getRoot_(node);
  /**
   * The node that currently inspected. Initially this is the entire math
   * expression.
   * @type {!sre.Focus}
   * @private
   */
  this.focus_ = new sre.Focus({nodes: [rootNode], primary: rootNode});

};

/**
 * @override
 */
sre.AbstractWalker.prototype.isActive = function() {
  return this.active_;
};

/**
 * Toggles the activity indicator of the walker.
 * @private
 */
sre.AbstractWalker.prototype.toggleActive_ = function() {
  this.active_ = !this.active_;
};

/**
 * @override
 */
sre.AbstractWalker.prototype.activate = function() {
  if (this.isActive()) {
    return;
  }
  this.generator.start();
  this.toggleActive_();
};

/**
 * @override
 */
sre.AbstractWalker.prototype.deactivate = function() {
  if (!this.isActive()) {
    return;
  }
  this.generator.end();
  this.toggleActive_();
};

/**
 * @override
 */
sre.AbstractWalker.prototype.getFocus = function() {
  return this.focus_;
};

/**
 * @override
 */
sre.AbstractWalker.prototype.speech = function() {
  return this.focus_.getNodes().map(
      goog.bind(function(x) {return this.generator.getSpeech(x);}, this))
      .join(' ');
};

/**
 * @override
 */
sre.AbstractWalker.prototype.move = function(key) {
  var direction = this.keyMapping_[key];
  if (!direction) {
    return null;
  }
  var focus = direction();
  if (!focus || focus === this.focus_) {
    return false;
  }
  this.focus_ = focus;
  return true;
};

/**
 * Moves up from the current node if possible.
 * @return {?sre.Focus}
 * @protected
 */
sre.AbstractWalker.prototype.up = goog.abstractMethod;

/**
 * Moves down from the current node if possible.
 * @return {?sre.Focus}
 * @protected
 */
sre.AbstractWalker.prototype.down = goog.abstractMethod;

/**
 * Moves left from the current node if possible.
 * @return {?sre.Focus}
 * @protected
 */
sre.AbstractWalker.prototype.left = goog.abstractMethod;

/**
 * Moves right from the current node if possible.
 * @return {?sre.Focus}
 * @protected
 */
sre.AbstractWalker.prototype.right = goog.abstractMethod;

/**
 * Retrieves the root node of the semantic tree.
 * @param {!Node} node The math node.
 * @return {!Node} The root node. If we cannot find one, the input node is
 *     returned.
 * @private
 */
sre.AbstractWalker.prototype.getRoot_ = function(node) {
  if (node.hasAttribute(sre.EnrichMathml.Attribute.TYPE) &&
      !node.hasAttribute(sre.EnrichMathml.Attribute.PARENT)) {
    return node;
  }
  var semanticNodes = node.querySelectorAll(
      '[' + sre.EnrichMathml.Attribute.TYPE + ']');
  for (var i = 0, semanticNode; semanticNode = semanticNodes[i]; i++) {
    if (!semanticNode.hasAttribute(sre.EnrichMathml.Attribute.PARENT)) {
      return semanticNode;
    }
  }
  return node;
};

/**
 * Retrieves a node containing a given semantic id.
 * @param {string} id The id of a semantic node.
 * @return {Node} The node for that id.
 */
sre.AbstractWalker.prototype.getBySemanticId = function(id) {
  var query = '[' + sre.EnrichMathml.Attribute.ID + '="' + id + '"]';
  return this.node.querySelector(query);
};

/**
 * Retrieves an attribute from the primary focused node if it exists.
 * @param {sre.EnrichMathml.Attribute} attr The attribute to retrieves.
 * @return {string} The value of the attribute for the primary node of the
 *     focus.
 */
sre.AbstractWalker.prototype.primaryAttribute = function(attr) {
  var primary = this.focus_.getPrimary();
  return primary ? sre.WalkerUtil.getAttribute(primary, attr) : '';
};

/**
 * @return {string} The id of the primary node of the current focus.
 */
sre.AbstractWalker.prototype.primaryId = function() {
  return this.primaryAttribute(sre.EnrichMathml.Attribute.ID);
};
<|endoftext|>


<commit_before>// Copyright 2015 Volker Sorge
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview A semantic walker.
 *
 * @author volker.sorge@gmail.com (Volker Sorge)
 */

goog.provide('sre.SemanticWalker');

goog.require('sre.AbstractWalker');
goog.require('sre.Levels');
goog.require('sre.WalkerUtil');

/**
 * @constructor
 * @extends {sre.AbstractWalker}
 * @override
 */
sre.SemanticWalker = function(node, generator) {
  goog.base(this, node, generator);

  /**
   * Caching of levels.
   * @type {!sre.Levels<sre.Focus>}
   */
  this.levels = new sre.Levels();

  this.levels.push([this.getFocus()]);
};
goog.inherits(sre.SemanticWalker, sre.AbstractWalker);

//TODO: Remove or refactor.
/**
 * Creates a simple focus for a solitary node.
 * @param {!string} id The node id to focus.
 * @return {!sre.Focus} A focus containing only this node and the other
 *     properties of the old focus.
 * @private
 */
sre.SemanticWalker.prototype.singletonFocus_ = function(id) {
  var node = this.getBySemanticId(id);
  return new sre.Focus({nodes: [node], primary: node});
};

/**
 * Makes a focus for a primary node and a node list, all given by their ids.
 * @param {string} id The semantic id of the primary node.
 * @param {!Array.<string>} ids The semantic id of the node list.
 * @return {?sre.Focus} The new focus.
 * @private
 */
sre.SemanticWalker.prototype.focusFromId_ = function(id, ids) {
  var node = this.getBySemanticId(id);
  var nodes = ids.map(goog.bind(this.getBySemanticId, this));
  return new sre.Focus({nodes: nodes, primary: node});
};

/**
 * @override
 */
sre.SemanticWalker.prototype.up = function() {
  var parent = this.primaryAttribute(sre.EnrichMathml.Attribute.PARENT);
  if (!parent) return null;
  this.levels.pop();
  var found = this.levels.find(
      function(x) {
        for (var i = 0, node, nodes = x.getNodes(); node = nodes[i]; i++) {
          if (sre.WalkerUtil.getAttribute(
              node, sre.EnrichMathml.Attribute.ID) === parent) {
            return true;
          }
        }
        return false;
      });
  return found;
};

/**
 * @override
 */
sre.SemanticWalker.prototype.down = function() {
  var children = this.nextLevel_();
  if (children.length === 0) {
    return null;
  }
  this.levels.push(children);
  return children[0];
};

/**
 * Computes the next lower level from children and content.
 * @return {!Array.<sre.Focus>} The next lower level.
 * @private
 */
sre.SemanticWalker.prototype.nextLevel_ = function() {
  var children = sre.WalkerUtil.splitAttribute(
      this.primaryAttribute(sre.EnrichMathml.Attribute.CHILDREN));
  var content = sre.WalkerUtil.splitAttribute(
      this.primaryAttribute(sre.EnrichMathml.Attribute.CONTENT));
  if (children.length === 0) return [];
  var primary = /** @type {!Node} */ (this.getFocus().getPrimary());
  var type = sre.WalkerUtil.getAttribute(
      primary, sre.EnrichMathml.Attribute.TYPE);
  var role = sre.WalkerUtil.getAttribute(
      primary, sre.EnrichMathml.Attribute.ROLE);
  return this.combineContentChildren(
      /** @type {!sre.SemanticAttr.Type} */ (type),
      /** @type {!sre.SemanticAttr.Role} */ (role),
      content, children);
};

/**
 * Combines content and children lists depending on semantic type and role.
 * @param {!sre.SemanticAttr.Type} type The semantic type.
 * @param {!sre.SemanticAttr.Role} role The semantic role.
 * @param {!Array.<string>} content The list of content nodes.
 * @param {!Array.<string>} children The list of child nodes.
 * @return {!Array.<sre.Focus>} The list of focus elements.
 */
sre.SemanticWalker.prototype.combineContentChildren = function(
    type, role, content, children) {
  switch (type) {
    case sre.SemanticAttr.Type.RELSEQ:
    case sre.SemanticAttr.Type.INFIXOP:
    case sre.SemanticAttr.Type.MULTIREL:
      return this.makePairList(children, content);
    case sre.SemanticAttr.Type.PREFIXOP:
      return [this.focusFromId_(children[0], content.concat(children))];
    case sre.SemanticAttr.Type.POSTFIXOP:
      return [this.focusFromId_(children[0], children.concat(content))];
    case sre.SemanticAttr.Type.FENCED:
      return [this.focusFromId_(children[0],
          [content[0], children[0], content[1]])];
    case sre.SemanticAttr.Type.PUNCTUATED:
      if (role === sre.SemanticAttr.Role.TEXT) {
        return children.map(goog.bind(this.singletonFocus_, this));
      }
      //TODO: That needs to be fixed!
      if (children.length === content.length) {
        return content.map(goog.bind(this.singletonFocus_, this));
      }
      var focusList = this.combinePunctuations(children, content, [], []);
      return focusList;
    case sre.SemanticAttr.Type.APPL:
      return [this.focusFromId_(children[0], [children[0], content[0]]),
        this.singletonFocus_(children[1])];
    case sre.SemanticAttr.Type.ROOT:
      return [this.singletonFocus_(children[1]),
              this.singletonFocus_(children[0])];
    default:
      return children.map(goog.bind(this.singletonFocus_, this));
  }
};

// This does not work yet!
/**
 * Makes a focus list from children of a punctuated element.
 * @param {!Array.<string>} children Child node ids.
 * @param {!Array.<string>} content Content node ids.
 * @param {!Array.<string>} prepunct List of prefix punctuations.
 * @param {!Array.<sre.Focus>} acc Result accumulator.
 * @return {!Array.<sre.Focus>} The list of focuses with paired nodes.
 */
sre.SemanticWalker.prototype.combinePunctuations = function(
    children, content, prepunct, acc) {
  var child = children.shift();
  var cont = content.shift();
  if (child === cont) {
    prepunct.push(cont);
    return this.combinePunctuations(children, content, prepunct, acc);
  } else {
    content.unshift(cont);
    prepunct.push(child);
    if (children.length === content.length) {
      acc.push(this.focusFromId_(child, prepunct.concat(content)));
      return acc;
    } else {
      acc.push(this.focusFromId_(child, prepunct));
      return this.combinePunctuations(children, content, [], acc);
    }
  }
};

/**
 * Makes pairwise focus structures from two lists.
 * @param {!Array.<string>} children Child nodes of length n.
 * @param {!Array.<string>} content Content nodes of length n - 1.
 * @return {!Array.<sre.Focus>} The list of focuses with paired nodes.
 */
sre.SemanticWalker.prototype.makePairList = function(children, content) {
  if (children.length === 0) return [];
  if (children.length === 1) {
    return [this.singletonFocus_(children[0])];
  }
  var result = [this.singletonFocus_(children.shift())];
  for (var i = 0, l = children.length; i < l; i++) {
    result.push(this.focusFromId_(children[i], [content[i], children[i]]));
  }
  return result;
};

/**
 * @override
 */
sre.SemanticWalker.prototype.left = function() {
  var index = this.levels.indexOf(this.getFocus()) - 1;
  var ids = this.levels.get(index);
  return ids ? ids : null;
};

/**
 * @override
 */
sre.SemanticWalker.prototype.right = function() {
  var index = this.levels.indexOf(this.getFocus()) + 1;
  var ids = this.levels.get(index);
  return ids ? ids : null;
};
<commit_msg>Adds cases for matrix, vectore, cases.<commit_after>// Copyright 2015 Volker Sorge
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview A semantic walker.
 *
 * @author volker.sorge@gmail.com (Volker Sorge)
 */

goog.provide('sre.SemanticWalker');

goog.require('sre.AbstractWalker');
goog.require('sre.Levels');
goog.require('sre.WalkerUtil');

/**
 * @constructor
 * @extends {sre.AbstractWalker}
 * @override
 */
sre.SemanticWalker = function(node, generator) {
  goog.base(this, node, generator);

  /**
   * Caching of levels.
   * @type {!sre.Levels<sre.Focus>}
   */
  this.levels = new sre.Levels();

  this.levels.push([this.getFocus()]);
};
goog.inherits(sre.SemanticWalker, sre.AbstractWalker);

//TODO: Remove or refactor.
/**
 * Creates a simple focus for a solitary node.
 * @param {!string} id The node id to focus.
 * @return {!sre.Focus} A focus containing only this node and the other
 *     properties of the old focus.
 * @private
 */
sre.SemanticWalker.prototype.singletonFocus_ = function(id) {
  var node = this.getBySemanticId(id);
  return new sre.Focus({nodes: [node], primary: node});
};

/**
 * Makes a focus for a primary node and a node list, all given by their ids.
 * @param {string} id The semantic id of the primary node.
 * @param {!Array.<string>} ids The semantic id of the node list.
 * @return {?sre.Focus} The new focus.
 * @private
 */
sre.SemanticWalker.prototype.focusFromId_ = function(id, ids) {
  var node = this.getBySemanticId(id);
  var nodes = ids.map(goog.bind(this.getBySemanticId, this));
  return new sre.Focus({nodes: nodes, primary: node});
};

/**
 * @override
 */
sre.SemanticWalker.prototype.up = function() {
  var parent = this.primaryAttribute(sre.EnrichMathml.Attribute.PARENT);
  if (!parent) return null;
  this.levels.pop();
  var found = this.levels.find(
      function(x) {
        for (var i = 0, node, nodes = x.getNodes(); node = nodes[i]; i++) {
          if (sre.WalkerUtil.getAttribute(
              node, sre.EnrichMathml.Attribute.ID) === parent) {
            return true;
          }
        }
        return false;
      });
  return found;
};

/**
 * @override
 */
sre.SemanticWalker.prototype.down = function() {
  var children = this.nextLevel_();
  if (children.length === 0) {
    return null;
  }
  this.levels.push(children);
  return children[0];
};

/**
 * Computes the next lower level from children and content.
 * @return {!Array.<sre.Focus>} The next lower level.
 * @private
 */
sre.SemanticWalker.prototype.nextLevel_ = function() {
  var children = sre.WalkerUtil.splitAttribute(
      this.primaryAttribute(sre.EnrichMathml.Attribute.CHILDREN));
  var content = sre.WalkerUtil.splitAttribute(
      this.primaryAttribute(sre.EnrichMathml.Attribute.CONTENT));
  if (children.length === 0) return [];
  var primary = /** @type {!Node} */ (this.getFocus().getPrimary());
  var type = sre.WalkerUtil.getAttribute(
      primary, sre.EnrichMathml.Attribute.TYPE);
  var role = sre.WalkerUtil.getAttribute(
      primary, sre.EnrichMathml.Attribute.ROLE);
  return this.combineContentChildren(
      /** @type {!sre.SemanticAttr.Type} */ (type),
      /** @type {!sre.SemanticAttr.Role} */ (role),
      content, children);
};

/**
 * Combines content and children lists depending on semantic type and role.
 * @param {!sre.SemanticAttr.Type} type The semantic type.
 * @param {!sre.SemanticAttr.Role} role The semantic role.
 * @param {!Array.<string>} content The list of content nodes.
 * @param {!Array.<string>} children The list of child nodes.
 * @return {!Array.<sre.Focus>} The list of focus elements.
 */
sre.SemanticWalker.prototype.combineContentChildren = function(
    type, role, content, children) {
  switch (type) {
    case sre.SemanticAttr.Type.RELSEQ:
    case sre.SemanticAttr.Type.INFIXOP:
    case sre.SemanticAttr.Type.MULTIREL:
      return this.makePairList(children, content);
    case sre.SemanticAttr.Type.PREFIXOP:
      return [this.focusFromId_(children[0], content.concat(children))];
    case sre.SemanticAttr.Type.POSTFIXOP:
      return [this.focusFromId_(children[0], children.concat(content))];
    case sre.SemanticAttr.Type.MATRIX:
    case sre.SemanticAttr.Type.VECTOR:
    case sre.SemanticAttr.Type.FENCED:
      return [this.focusFromId_(children[0],
          [content[0], children[0], content[1]])];
    case sre.SemanticAttr.Type.CASES:
      return [this.focusFromId_(children[0],
          [content[0], children[0]])];
    case sre.SemanticAttr.Type.PUNCTUATED:
      if (role === sre.SemanticAttr.Role.TEXT) {
        return children.map(goog.bind(this.singletonFocus_, this));
      }
      //TODO: That needs to be fixed!
      if (children.length === content.length) {
        return content.map(goog.bind(this.singletonFocus_, this));
      }
      var focusList = this.combinePunctuations(children, content, [], []);
      return focusList;
    case sre.SemanticAttr.Type.APPL:
      return [this.focusFromId_(children[0], [children[0], content[0]]),
        this.singletonFocus_(children[1])];
    case sre.SemanticAttr.Type.ROOT:
      return [this.singletonFocus_(children[1]),
              this.singletonFocus_(children[0])];
    default:
      return children.map(goog.bind(this.singletonFocus_, this));
  }
};

// This does not work yet!
/**
 * Makes a focus list from children of a punctuated element.
 * @param {!Array.<string>} children Child node ids.
 * @param {!Array.<string>} content Content node ids.
 * @param {!Array.<string>} prepunct List of prefix punctuations.
 * @param {!Array.<sre.Focus>} acc Result accumulator.
 * @return {!Array.<sre.Focus>} The list of focuses with paired nodes.
 */
sre.SemanticWalker.prototype.combinePunctuations = function(
    children, content, prepunct, acc) {
  var child = children.shift();
  var cont = content.shift();
  if (child === cont) {
    prepunct.push(cont);
    return this.combinePunctuations(children, content, prepunct, acc);
  } else {
    content.unshift(cont);
    prepunct.push(child);
    if (children.length === content.length) {
      acc.push(this.focusFromId_(child, prepunct.concat(content)));
      return acc;
    } else {
      acc.push(this.focusFromId_(child, prepunct));
      return this.combinePunctuations(children, content, [], acc);
    }
  }
};

/**
 * Makes pairwise focus structures from two lists.
 * @param {!Array.<string>} children Child nodes of length n.
 * @param {!Array.<string>} content Content nodes of length n - 1.
 * @return {!Array.<sre.Focus>} The list of focuses with paired nodes.
 */
sre.SemanticWalker.prototype.makePairList = function(children, content) {
  if (children.length === 0) return [];
  if (children.length === 1) {
    return [this.singletonFocus_(children[0])];
  }
  var result = [this.singletonFocus_(children.shift())];
  for (var i = 0, l = children.length; i < l; i++) {
    result.push(this.focusFromId_(children[i], [content[i], children[i]]));
  }
  return result;
};

/**
 * @override
 */
sre.SemanticWalker.prototype.left = function() {
  var index = this.levels.indexOf(this.getFocus()) - 1;
  var ids = this.levels.get(index);
  return ids ? ids : null;
};

/**
 * @override
 */
sre.SemanticWalker.prototype.right = function() {
  var index = this.levels.indexOf(this.getFocus()) + 1;
  var ids = this.levels.get(index);
  return ids ? ids : null;
};
<|endoftext|>