<commit_before>import React from 'react'
import {
  Button,
  Container,
  Heading,
  Text,
  Section,
  Link as A,
  ThemeProvider
} from '@hackclub/design-system'
import { Head, Link } from 'react-static'
import Nav from '../components/Nav'
import Footer from '../components/Footer'

// These 2 colors are from the gradient used on the original Hack Camp website
const campTheme = ['rgb(255, 75, 85)', 'rgb(212, 78, 116)']

const Header = Section.withComponent('header').extend`
  flex-direction: column;
  padding-top: 0 !important;
  background-color: ${campTheme[0]};
  background-image: linear-gradient(
    45deg,
    ${campTheme[0]} 0%,
    ${campTheme[1]} 100%
  );
`

Button.link = Button.withComponent(Link)

export default () => (
  <ThemeProvider>
    <Head>
      <title>Hack Camp</title>
    </Head>
    <Header pb={3}>
      <Nav />
      <Heading.h1 f={[5, 6]} mt={4}>
        Hack Camp
      </Heading.h1>
      <Heading f={[3, 4]} mt={2}>
        We’ve replaced camps in favor of clubs!
      </Heading>
    </Header>
    <Container maxWidth={32} py={[3, 4]} align="center">
      <Text f={3}>
        Apply to our clubs program and we’ll help you launch and lead a coding
        club at your school. It’s like summer camp, but it runs all year!
      </Text>
      <Button.link bg={campTheme[0]} color="white" to="/start" my={4}>
        Learn More + Apply »
      </Button.link>
      <Text color="slate">
        Looking for the{' '}
        <A
          color={campTheme[0]}
          href="https://hackclub.github.io/camp/"
          children="old Hack Camp website"
        />?
      </Text>
    </Container>
  </ThemeProvider>
)
<commit_msg>Update Camp page content<commit_after>import React from 'react'
import {
  Button,
  Container,
  Heading,
  Text,
  Section,
  Link as A,
  ThemeProvider
} from '@hackclub/design-system'
import { Head, Link } from 'react-static'
import Nav from '../components/Nav'
import Footer from '../components/Footer'

// These 2 colors are from the gradient used on the original Hack Camp website
const campTheme = ['rgb(255, 75, 85)', 'rgb(212, 78, 116)']

const Header = Section.withComponent('header').extend`
  flex-direction: column;
  padding-top: 0 !important;
  background-color: ${campTheme[0]};
  background-image: linear-gradient(
    45deg,
    ${campTheme[0]} 0%,
    ${campTheme[1]} 100%
  );
`

Button.link = Button.withComponent(Link)

export default () => (
  <ThemeProvider>
    <Head>
      <title>Hack Camp</title>
    </Head>
    <Header pb={3}>
      <Nav />
      <Heading.h1 f={[5, 6]} mt={4}>
        Hack Camp has been discontinued.
      </Heading.h1>
      <Heading f={[3, 4]} mt={2}>
        We’ve replaced camps in favor of clubs!
      </Heading>
    </Header>
    <Container maxWidth={32} py={[3, 4]} align="center">
      <Text f={3}>
        Apply to our clubs program and we’ll help you launch and lead a coding
        club at your school. It’s like summer camp, except that it runs all
        year long!
      </Text>
      <Button.link bg={campTheme[0]} color="white" to="/start" my={4}>
        Learn More + Apply »
      </Button.link>
      <Text color="slate">
        Looking for the{' '}
        <A
          color={campTheme[0]}
          href="https://hackclub.github.io/camp/"
          children="old Hack Camp website"
        />?
      </Text>
    </Container>
  </ThemeProvider>
)
<|endoftext|>


<commit_before>import React from 'react'
import Card, {CardContent} from 'material-ui/Card'
import Grid from 'material-ui/Grid'
import {getSiteProps} from 'react-static'
import 'font-awesome/css/font-awesome.min.css'
import SocialSiteCard from '../components/custom-cards'

export default getSiteProps(() => (

    <Grid container spacing={24}>
      <Grid item xs={6} sm={3}>
        <SocialSiteCard iconName='linkedin' href='plus.google.com' />
      </Grid>
      <Grid item xs={6} sm={3}>
        <SocialSiteCard iconName='google-plus' href='plus.google.com' />
      </Grid>
      <Grid item xs={6} sm={3}>
        <SocialSiteCard iconName='twitter' href='plus.google.com' />
      </Grid>
      <Grid item xs={6} sm={3}>
        <SocialSiteCard iconName='github' href='plus.google.com' />
      </Grid>
    </Grid>

Hi, I'm Tanay PrabhuDesai.

I'm a software engineer based in Pune, India.

      <Grid container>
        <Card className='project-card'>
          <CardContent>
        Something
          </CardContent>
        </Card>
        <Card className='project-card'>
          <CardContent>
        Something
          </CardContent>
        </Card>
      </Grid>

))
<commit_msg>Add the link to the necessary websites<commit_after>import React from 'react'
import Card, {CardContent} from 'material-ui/Card'
import Grid from 'material-ui/Grid'
import {getSiteProps} from 'react-static'
import 'font-awesome/css/font-awesome.min.css'
import SocialSiteCard from '../components/custom-cards'

export default getSiteProps(() => (

    <Grid container spacing={24}>
      <Grid item xs={6} sm={3}>
        <SocialSiteCard iconName='linkedin' href='https://www.linkedin.com/in/tanay-prabhudesai-1029b073/' />
      </Grid>
      <Grid item xs={6} sm={3}>
        <SocialSiteCard iconName='google-plus' href='https://plus.google.com/+TanayPrabhuDesai' />
      </Grid>
      <Grid item xs={6} sm={3}>
        <SocialSiteCard iconName='twitter' href='https://twitter.com/tanayseven' />
      </Grid>
      <Grid item xs={6} sm={3}>
        <SocialSiteCard iconName='github' href='https://github.com/tanayseven/' />
      </Grid>
    </Grid>

Hi, I'm Tanay PrabhuDesai.

I'm a software engineer based in Pune, India.

      <Grid container>
        <Card className='project-card'>
          <CardContent>
        Something
          </CardContent>
        </Card>
        <Card className='project-card'>
          <CardContent>
        Something
          </CardContent>
        </Card>
      </Grid>

))
<|endoftext|>


<commit_before>import React from 'react'
import {
  Provider,
  Banner,
  Heading,
  Lead,
  Container,
  Flex,
  Box,
  Text,
  Subhead,
  Absolute,
  ButtonOutline
} from 'rebass'
import theme, { colors, mx } from '../theme'
import { Head, Link } from 'react-static'
import Features from '../components/Features'
import Stat from '../components/Stat'

const css = `
  body { background-color: #000; }
  #root > div, #features *, #stats span {
    color: ${colors.green[6]} !important;
    font-family: ${theme.monospace} !important;
    text-shadow: 0 1px 3px ${colors.green[4]};
    letter-spacing: -.02em;
  }
  #features > div > div {
    background-color: #000;
    border: 1px solid ${colors.green[6]};
    border-radius: 0;
  }
  #features img { display: none !important; }
  #features * {
    font-size: ${theme.fontSizes[2]};
  }
  #stats > div {
    padding-left: .5rem;
    padding-right: .5rem;
  }
  #stats p { color: ${colors.green[8]}; }
  #stats span { font-weight: 400; }
`

const Header = Flex.extend.attrs({
  is: 'header',
  align: 'center',
  justify: 'center',
  direction: 'column',
  px: [3, 0],
  py: [5, 3]
})`
  background: #000 url('/map-repl.svg') no-repeat;
  background-size: cover;
  background-position: 33% top;
  border-bottom: 1px solid ${colors.green[9]};
  text-align: center;
  ${mx[0]} {
    background-position: center top;
    min-height: 75vh !important;
  }
`
const Section = Box.extend.attrs({ is: 'section', py: 4 })`
  border-bottom: 1px solid ${colors.green[9]};
  text-align: center;
`
const Footer = Box.extend.attrs({
  is: 'footer',
  py: 4,
  f: 2
})`text-align: center;`

const Tagline = Text.extend.attrs({
  f: 3,
  mb: 2
})`
  text-align: center;
  text-transform: uppercase;
`
const Headline = Heading.extend.attrs({
  is: 'h1',
  f: 6,
  mb: 2
})`line-height: 1.125;`
const Subheadline = Heading.extend.attrs({
  f: 5,
  mt: 4,
  px: 3
})``

const CTA = Box.extend.attrs({
  is: 'a',
  color: colors.green[6],
  px: [2, 3, 4],
  py: [2, 3],
  mx: 2,
  f: [3, 4]
})`
  border: 2px solid ${colors.green[6]};
  line-height: 1;
  text-decoration: none;
  text-transform: uppercase;
  cursor: pointer;
`
const CTA2 = CTA.extend.attrs({ f: 3 })`opacity: 0.8;`

export default () => (
  <Provider theme={theme}>

      <title>Repl.it – Hack Club</title>


<commit_before>import React from 'react'
import {
  Provider,
  Heading,
  Lead,
  Container,
  Flex,
  Box,
  Text,
  Subhead
} from 'rebass'
import theme, { colors } from '../theme'
import { Head, Link } from 'react-static'
import Nav from '../components/Nav'
import Bio from '../components/Bio'
import Footer from '../components/Footer'

const Base = Container.extend.attrs({
  py: 4,
  px: 3,
  maxWidth: 36 * 16
})``

const Headline = Heading.extend.attrs({
  color: 'primary',
  mb: 3,
  align: 'center'
})`
  text-transform: uppercase;
  letter-spacing: .1em;
`

const P = Text.extend.attrs({ f: 3, mb: 2 })`
  @supports (-webkit-initial-letter: 2) {
    &:first-of-type:first-letter {
      -webkit-initial-letter: 2;
      color: ${colors.slate};
      font-weight: bold;
      margin-right: .5rem;
    }
  }
`

export default () => (
  <Provider theme={theme}>
    <title>Team – Hack Club</title>

    <Base>
      <Headline>
        <Box f={4}>Hack Club</Box>
        <Box f={6}>Team</Box>
      </Headline>
      <Bio
        img="/team/zach.png"
        name="Zach Latta"
        role="Executive Director"
        text="Zach founded Hack Club in 2014 after he started a coding club at his high school. He previously led the engineering team at Yo and was a developer on Football Heroes. He cares about building things and learning."
      />
      <Bio
        img="/team/max.jpg"
        name="Max Wofford"
        role="Software Engineer"
        text="Tapping into the hacking community, Max has found a common purpose with the founders of Hack Club and his passion for amplifying people’s ideas. He loves helping students scale their ideas into even more awesome products."
      />
      <Bio
        img="/team/lachlan.jpg"
        name="Lachlan Campbell"
        role="Web Designer"
        text="Lachlan, a club leader from State College, PA, joined the team to work on Hack Club’s website. They care about making tools to make information more accessible."
      />
      <Bio
        img="/team/mingjie.jpg"
        name="Mingjie Jiang"
        role="Social Media"
        text="Mingjie leads a local club at Wootton High School in Rockville, Maryland. Aside from trying to engage more students into the world of hacking, he also cares about building a unique public identity for Hack Club."
      />
      <Bio
        img="/team/victor.png"
        name="Victor Truong"
        role="Finance"
        text="Victor is a club leader at Rosemead High School in Los Angeles, CA. He aims to make Hack Club’s finances as transparent as possible, and believes the way to do so is to let people know how each and every penny is being spent."
      />
      <Flex justify="center" mt={3}>
        <Text
          is={Link}
          to="/"
          color="primary"
          f={3}
          bold
          style={{ textDecoration: 'none' }}
        >
          ← Home
        </Text>
      </Flex>
    </Base>

  </Provider>
)
<commit_msg>Add Athul to Team page<commit_after>import React from 'react'
import {
  Provider,
  Heading,
  Lead,
  Container,
  Flex,
  Box,
  Text,
  Subhead
} from 'rebass'
import theme, { colors } from '../theme'
import { Head, Link } from 'react-static'
import Nav from '../components/Nav'
import Bio from '../components/Bio'
import Footer from '../components/Footer'

const Base = Container.extend.attrs({
  py: 4,
  px: 3,
  maxWidth: 36 * 16
})``

const Headline = Heading.extend.attrs({
  color: 'primary',
  mb: 3,
  align: 'center'
})`
  text-transform: uppercase;
  letter-spacing: .1em;
`

const P = Text.extend.attrs({ f: 3, mb: 2 })`
  @supports (-webkit-initial-letter: 2) {
    &:first-of-type:first-letter {
      -webkit-initial-letter: 2;
      color: ${colors.slate};
      font-weight: bold;
      margin-right: .5rem;
    }
  }
`

export default () => (
  <Provider theme={theme}>
    <title>Team – Hack Club</title>

    <Base>
      <Headline>
        <Box f={4}>Hack Club</Box>
        <Box f={6}>Team</Box>
      </Headline>
      <Bio
        img="/team/zach.png"
        name="Zach Latta"
        role="Executive Director"
        text="Zach founded Hack Club in 2014 after he started a coding club at his high school. He previously led the engineering team at Yo and was a developer on Football Heroes. He cares about building things and learning."
      />
      <Bio
        img="/team/max.jpg"
        name="Max Wofford"
        role="Software Engineer"
        text="Tapping into the hacking community, Max has found a common purpose with the founders of Hack Club and his passion for amplifying people’s ideas. He loves helping students scale their ideas into even more awesome products."
      />
      <Bio
        img="/team/lachlan.jpg"
        name="Lachlan Campbell"
        role="Web Designer"
        text="Lachlan, a club leader from State College, PA, joined the team to work on Hack Club’s website. They care about making tools to make information more accessible."
      />
      <Bio
        img="/team/mingjie.jpg"
        name="Mingjie Jiang"
        role="Social Media"
        text="Mingjie leads a local club at Wootton High School in Rockville, Maryland. Aside from trying to engage more students into the world of hacking, he also cares about building a unique public identity for Hack Club."
      />
      <Bio
        img="/team/victor.png"
        name="Victor Truong"
        role="Finance"
        text="Victor is a club leader at Rosemead High School in Los Angeles, CA. He aims to make Hack Club’s finances as transparent as possible, and believes the way to do so is to let people know how each and every penny is being spent."
      />
      <Bio
        img="/team/athul.jpg"
        name="Athul Blesson"
        role="Indian Region"
        text="Athul leads some of our largest clubs in India. After graduating from high school, he joined as our Regional Manager in India. He is passionate about bringing more students into the world of coding."
      />
      <Flex justify="center" mt={3}>
        <Text
          is={Link}
          to="/"
          color="primary"
          f={3}
          bold
          style={{ textDecoration: 'none' }}
        >
          ← Home
        </Text>
      </Flex>
    </Base>

  </Provider>
)
<|endoftext|>


<commit_before>Todos = new Meteor.Collection("todos")

if (Meteor.isClient) {
  // client code
  Template.todo_list.todos = function(){
    var filter = Session.get('filter');
    if ( !filter ) return Todos.find();

    return Todos.find({desc: {$regex: '^.*'+filter+'.*$', $options: 'i'}});
  }

  Template.todo_list.todosCount = function(){
    return Todos.find().fetch().length;
  }

  Template.todo_list.events = {
    'keyup #todo_filter': function(evt){
      Session.set('filter', evt.target.value.trim());
    }
  }

  Template.todo_info.events = {
    'change input': function(evt){
      Todos.update(this._id, {$set: {done: !!evt.target.checked}});
    },
    'click span': function(evt){
      Todos.remove(this._id);
    }
  }
}

if (Meteor.isServer) {
  Meteor.startup(function () {
    // code to run on server at startup
  });

  Todos.allow({
    insert: function(userId, item) {
      return item.hasOwnProperty('userId');
    },
    update: function(userId, item) {
      return true;
    },
    remove: function(userId, item) {
      return item.userId == userId;
    }
  });
}
<commit_msg>Removing double negative from item checked attribute<commit_after>Todos = new Meteor.Collection("todos")

if (Meteor.isClient) {
  // client code
  Template.todo_list.todos = function(){
    var filter = Session.get('filter');
    if ( !filter ) return Todos.find();

    return Todos.find({desc: {$regex: '^.*'+filter+'.*$', $options: 'i'}});
  }

  Template.todo_list.todosCount = function(){
    return Todos.find().fetch().length;
  }

  Template.todo_list.events = {
    'keyup #todo_filter': function(evt){
      Session.set('filter', evt.target.value.trim());
    }
  }

  Template.todo_info.events = {
    'change input': function(evt){
      Todos.update(this._id, {$set: {done: evt.target.checked}});
    },
    'click span': function(evt){
      Todos.remove(this._id);
    }
  }
}

if (Meteor.isServer) {
  Meteor.startup(function () {
    // code to run on server at startup
  });

  Todos.allow({
    insert: function(userId, item) {
      return item.hasOwnProperty('userId');
    },
    update: function(userId, item) {
      return true;
    },
    remove: function(userId, item) {
      return item.userId == userId;
    }
  });
}
<|endoftext|>


<commit_before>'use strict';

module.exports = function ($scope, $rootScope, $http, adLogin) {
  // login functions
  $scope.login = {};

  // copy-paste from .run code
  $scope.loginUser = function () {
    adLogin.login($scope.login.username, $scope.login.password)
    .then(function success (userData) {
      $rootScope.loginStatus = 'login';
      $rootScope.loginFailed = false;
      $rootScope.logoutKey = userData.logoutKey;
      $rootScope.uid = userData.uid;

      // user details to rootScope propagation
      $rootScope.paid = (userData.remainingDays > 0) ? true : false;
      $rootScope.remainingDays = userData.remainingDays;
      $rootScope.username = userData.username;

      // clean scope values
      delete $scope.login.username;
      delete $scope.login.password;
    }, function failure (details) {
      if (details.recaptcha) {
        $rootScope.recaptchaWarning = true;
      }

      $rootScope.loginStatus = 'anon';
      $rootScope.loginFailed = true;
    });

    $rootScope.loginStatus = 'working';
  };

  $scope.logoutUser = function () {
    adLogin.logout($rootScope.logoutKey)
    .then(function success () {
      $rootScope.loginStatus = 'anon';
    }, function failure () {
      $rootScope.loginStatus = 'login';
    });

    $rootScope.loginStatus = 'working';
  };

  $scope.showLinks = false;
  $scope.showTorrents = false;

  $scope.$on('torrentLinks', function (event, args) {
    $scope.showLinks = true;
  });

  $scope.$on('forceUpdateTorrents', function (event, args) {
    $scope.$broadcast('updateTorrents');
  });
};
<commit_msg>rename adLogin -> login<commit_after>'use strict';

module.exports = function ($scope, $rootScope, $http, login) {
  // login functions
  $scope.login = {};

  // copy-paste from .run code
  $scope.loginUser = function () {
    login.login($scope.login.username, $scope.login.password)
    .then(function success (userData) {
      $rootScope.loginStatus = 'login';
      $rootScope.loginFailed = false;
      $rootScope.logoutKey = userData.logoutKey;
      $rootScope.uid = userData.uid;

      // user details to rootScope propagation
      $rootScope.paid = (userData.remainingDays > 0) ? true : false;
      $rootScope.remainingDays = userData.remainingDays;
      $rootScope.username = userData.username;

      // clean scope values
      delete $scope.login.username;
      delete $scope.login.password;
    }, function failure (details) {
      if (details.recaptcha) {
        $rootScope.recaptchaWarning = true;
      }

      $rootScope.loginStatus = 'anon';
      $rootScope.loginFailed = true;
    });

    $rootScope.loginStatus = 'working';
  };

  $scope.logoutUser = function () {
    login.logout($rootScope.logoutKey)
    .then(function success () {
      $rootScope.loginStatus = 'anon';
    }, function failure () {
      $rootScope.loginStatus = 'login';
    });

    $rootScope.loginStatus = 'working';
  };

  $scope.showLinks = false;
  $scope.showTorrents = false;

  $scope.$on('torrentLinks', function (event, args) {
    $scope.showLinks = true;
  });

  $scope.$on('forceUpdateTorrents', function (event, args) {
    $scope.$broadcast('updateTorrents');
  });
};
<|endoftext|>


<commit_before>/* Ajax multiplexer */
Hm_Ajax = {
    requests: [],

    request: function(args, callback, extra, no_icon) {
        var ajax = new Hm_Ajax_Request();
        ajax.index = Hm_Ajax.requests.length;
        if (Hm_Ajax.requests.length == 0) {
            $("input[type='submit']").attr('disabled', true);
            if (!no_icon) {
                $('.loading_icon').css('visibility', 'visible');
            }
        }
        Hm_Ajax.requests.push(ajax);
        return ajax.make_request(args, callback, extra);
    }
};

/* Ajax request wrapper */
Hm_Ajax_Request = function() { return {

    callback: false,
    index: 0,
    start_time: 0,

    make_request: function(args, callback, extra) {
        this.callback = callback;
        if (extra) {
            for (name in extra) {
                args.push({'name': name, 'value': extra[name]});
            }
        }

        var dt = new Date();
        this.start_time = dt.getTime();
        $.ajax({
            type: "POST",
            url: '',
            data: args,
            context: this,
            success: this.done,
            complete: this.always,
            error: this.fail
        });

        return false;
    },

    done: function(res) {
        if (typeof res == 'string' && (res == 'null' || res.indexOf('<') == 0 || res == '{}')) {
            this.fail(res);
            return;
        }
        else if (!res) {
            this.fail(res);
            return;
        }
        else {
            res = jQuery.parseJSON(res);
            if (res.date) {
                $('.date').html(res.date);
            }
            if (res.router_user_msgs && !jQuery.isEmptyObject(res.router_user_msgs)) {
                Hm_Notices.show(res.router_user_msgs);
            }
            if (this.callback) {
                this.callback(res);
            }
        }
    },

    fail: function(res) {
        Hm_Notices.show({0: 'An error occured communicating with the server'});
    },

    always: function(res) {
        var dt = new Date();
        var elapsed = dt.getTime() - this.start_time;
        $('.elapsed').html('AJAX request finished in ' + elapsed + ' millis');
        Hm_Ajax.requests.splice(this.index, 1);
        if (Hm_Ajax.requests.length == 0) {
            $("input[type='submit']").attr('disabled', false);
            $('.loading_icon').css('visibility', 'hidden');
        }
    }
}; };

/* user notification manager */
Hm_Notices = {

    hide_id: false,

    show: function(msgs) {
        var msg_list = $.map(msgs, function(v) {
            if (v.match(/^ERR/)) {
                return ''+v.substring(3)+'';
            }
            return v;
        });
        $('.sys_messages').html(msg_list.join(', '));
        Hm_Notices.hide();
    },

    hide: function() {
        if (Hm_Notices.hide_id) {
            clearTimeout(Hm_Notices.hide_id);
        }
        Hm_Notices.hide_id = setTimeout(function() {
            $('.sys_messages').fadeOut(1000, function() {
                $('.sys_messages').html('');
                $('.sys_messages').show('');
            });
        }, 20000);
    }
};

/* job scheduler */
Hm_Timer = {

    jobs: [],
    interval: 1000,

    add_job: function(job, interval, defer) {
        Hm_Timer.jobs.push([job, interval, interval]);
        if (!defer) {
            try { job(); } catch(e) { console.log(e); }
        }
    },

    fire: function() {
        var job;
        for (index in Hm_Timer.jobs) {
            job = Hm_Timer.jobs[index];
            job[2]--;
            if (job[2] == 0) {
                job[2] = job[1];
                Hm_Timer.jobs[index] = job;
                try { job[0](); } catch(e) { console.log(e); }
            }
        }
        setTimeout(Hm_Timer.fire, Hm_Timer.interval);
    }
};

/* start the scheduler */
Hm_Timer.fire();

/* setup hiding of any user notifications */
Hm_Notices.hide();
<commit_msg>extra special debug<commit_after>/* Ajax multiplexer */
Hm_Ajax = {
    requests: [],

    request: function(args, callback, extra, no_icon) {
        var ajax = new Hm_Ajax_Request();
        ajax.index = Hm_Ajax.requests.length;
        if (Hm_Ajax.requests.length == 0) {
            $("input[type='submit']").attr('disabled', true);
            if (!no_icon) {
                $('.loading_icon').css('visibility', 'visible');
            }
        }
        Hm_Ajax.requests.push(ajax);
        return ajax.make_request(args, callback, extra);
    }
};

/* Ajax request wrapper */
Hm_Ajax_Request = function() { return {

    callback: false,
    index: 0,
    start_time: 0,

    make_request: function(args, callback, extra) {
        this.callback = callback;
        if (extra) {
            for (name in extra) {
                args.push({'name': name, 'value': extra[name]});
            }
        }

        var dt = new Date();
        this.start_time = dt.getTime();
        $.ajax({
            type: "POST",
            url: '',
            data: args,
            context: this,
            success: this.done,
            complete: this.always,
            error: this.fail
        });

        return false;
    },

    done: function(res) {
        if (typeof res == 'string' && (res == 'null' || res.indexOf('<') == 0 || res == '{}')) {
            this.fail(res);
            return;
        }
        else if (!res) {
            this.fail(res);
            return;
        }
        else {
            res = jQuery.parseJSON(res);
            if (res.date) {
                $('.date').html(res.date);
            }
            if (res.router_user_msgs && !jQuery.isEmptyObject(res.router_user_msgs)) {
                Hm_Notices.show(res.router_user_msgs);
            }
            if (this.callback) {
                this.callback(res);
            }
        }
    },

    fail: function(res) {
        Hm_Notices.show({0: 'An error occured communicating with the server'});
    },

    always: function(res) {
        var dt = new Date();
        var elapsed = dt.getTime() - this.start_time;
        var msg = 'AJAX request finished in ' + elapsed + ' millis';
        if (elapsed > 2000) {
            msg += '. Ouch!';
        }
        $('.elapsed').html(msg);
        Hm_Ajax.requests.splice(this.index, 1);
        if (Hm_Ajax.requests.length == 0) {
            $("input[type='submit']").attr('disabled', false);
            $('.loading_icon').css('visibility', 'hidden');
        }
    }
}; };

/* user notification manager */
Hm_Notices = {

    hide_id: false,

    show: function(msgs) {
        var msg_list = $.map(msgs, function(v) {
            if (v.match(/^ERR/)) {
                return ''+v.substring(3)+'';
            }
            return v;
        });
        $('.sys_messages').html(msg_list.join(', '));
        Hm_Notices.hide();
    },

    hide: function() {
        if (Hm_Notices.hide_id) {
            clearTimeout(Hm_Notices.hide_id);
        }
        Hm_Notices.hide_id = setTimeout(function() {
            $('.sys_messages').fadeOut(1000, function() {
                $('.sys_messages').html('');
                $('.sys_messages').show('');
            });
        }, 20000);
    }
};

/* job scheduler */
Hm_Timer = {

    jobs: [],
    interval: 1000,

    add_job: function(job, interval, defer) {
        Hm_Timer.jobs.push([job, interval, interval]);
        if (!defer) {
            try { job(); } catch(e) { console.log(e); }
        }
    },

    fire: function() {
        var job;
        for (index in Hm_Timer.jobs) {
            job = Hm_Timer.jobs[index];
            job[2]--;
            if (job[2] == 0) {
                job[2] = job[1];
                Hm_Timer.jobs[index] = job;
                try { job[0](); } catch(e) { console.log(e); }
            }
        }
        setTimeout(Hm_Timer.fire, Hm_Timer.interval);
    }
};

/* start the scheduler */
Hm_Timer.fire();

/* setup hiding of any user notifications */
Hm_Notices.hide();
<|endoftext|>


<commit_before>var grammar = require('./grammar');

// customized util.format - discards excess arguments and can void middle ones
var formatRegExp = /%[sdv%]/g;
var format = function (formatStr) {
  var i = 1;
  var args = arguments;
  var len = args.length;
  return formatStr.replace(formatRegExp, function (x) {
    if (i >= len) {
      return x; // missing argument
    }
    var arg = args[i];
    i += 1;
    switch (x) {
      case '%%':
        return '%';
      case '%s':
        return String(arg);
      case '%d':
        return Number(arg);
      case '%v':
        return '';
    }
  });
  // NB: we discard excess arguments - they are typically undefined from makeLine
};

var makeLine = function (type, obj, location) {
  var str = obj.format instanceof Function ?
    (obj.format(obj.push ? location : location[obj.name])) :
    obj.format;

  var args = [type + '=' + str];
  if (obj.names) {
    for (var i = 0; i < obj.names.length; i += 1) {
      var n = obj.names[i];
      if (obj.name) {
        args.push(location[obj.name][n]);
      }
      else { // for mLine and push attributes
        args.push(location[obj.names[i]]);
      }
    }
  }
  else {
    args.push(location[obj.name]);
  }
  return format.apply(null, args);
};

// RFC specified order
// TODO: extend this with all the rest
var defaultOuterOrder = [
  'v', 'o', 's', 'i',
  'u', 'e', 'p', 'c',
  'b', 't', 'r', 'z', 'a'
];
var defaultInnerOrder = ['i', 'c', 'b', 'a'];

module.exports = function (session, opts) {
  opts = opts || {};
  // ensure certain properties exist
  if (session.version == null) {
    session.version = 0; // "v=0" must be there (only defined version atm)
  }
  if (session.name == null) {
    session.name = " "; // "s= " must be there if no meaningful name set
  }
  session.media.forEach(function (mLine) {
    if (mLine.payloads == null) {
      mLine.payloads = "";
    }
  });

  var outerOrder = opts.outerOrder || defaultOuterOrder;
  var innerOrder = opts.innerOrder || defaultInnerOrder;
  var sdp = [];

  // loop through outerOrder for matching properties on session
  outerOrder.forEach(function (type) {
    grammar[type].forEach(function (obj) {
      if (obj.name in session && typeof session[obj.name] !== 'undefined') {
        sdp.push(makeLine(type, obj, session));
      }
      else if (obj.push in session && typeof session[obj.push] !== 'undefined') {
        session[obj.push].forEach(function (el) {
          sdp.push(makeLine(type, obj, el));
        });
      }
    });
  });

  // then for each media line, follow the innerOrder
  session.media.forEach(function (mLine) {
    sdp.push(makeLine('m', grammar.m[0], mLine));

    innerOrder.forEach(function (type) {
      grammar[type].forEach(function (obj) {
        if (obj.name in mLine && typeof mLine[obj.name] !== 'undefined') {
          sdp.push(makeLine(type, obj, mLine));
        }
        else if (obj.push in mLine && typeof mLine[obj.push] !== 'undefined') {
          mLine[obj.push].forEach(function (el) {
            sdp.push(makeLine(type, obj, el));
          });
        }
      });
    });
  });

  return sdp.join('\r\n') + '\r\n';
};
<commit_msg>ignore undefined and null properties in session object and each mline object<commit_after>var grammar = require('./grammar');

// customized util.format - discards excess arguments and can void middle ones
var formatRegExp = /%[sdv%]/g;
var format = function (formatStr) {
  var i = 1;
  var args = arguments;
  var len = args.length;
  return formatStr.replace(formatRegExp, function (x) {
    if (i >= len) {
      return x; // missing argument
    }
    var arg = args[i];
    i += 1;
    switch (x) {
      case '%%':
        return '%';
      case '%s':
        return String(arg);
      case '%d':
        return Number(arg);
      case '%v':
        return '';
    }
  });
  // NB: we discard excess arguments - they are typically undefined from makeLine
};

var makeLine = function (type, obj, location) {
  var str = obj.format instanceof Function ?
    (obj.format(obj.push ? location : location[obj.name])) :
    obj.format;

  var args = [type + '=' + str];
  if (obj.names) {
    for (var i = 0; i < obj.names.length; i += 1) {
      var n = obj.names[i];
      if (obj.name) {
        args.push(location[obj.name][n]);
      }
      else { // for mLine and push attributes
        args.push(location[obj.names[i]]);
      }
    }
  }
  else {
    args.push(location[obj.name]);
  }
  return format.apply(null, args);
};

// RFC specified order
// TODO: extend this with all the rest
var defaultOuterOrder = [
  'v', 'o', 's', 'i',
  'u', 'e', 'p', 'c',
  'b', 't', 'r', 'z', 'a'
];
var defaultInnerOrder = ['i', 'c', 'b', 'a'];

module.exports = function (session, opts) {
  opts = opts || {};
  // ensure certain properties exist
  if (session.version == null) {
    session.version = 0; // "v=0" must be there (only defined version atm)
  }
  if (session.name == null) {
    session.name = " "; // "s= " must be there if no meaningful name set
  }
  session.media.forEach(function (mLine) {
    if (mLine.payloads == null) {
      mLine.payloads = "";
    }
  });

  var outerOrder = opts.outerOrder || defaultOuterOrder;
  var innerOrder = opts.innerOrder || defaultInnerOrder;
  var sdp = [];

  // loop through outerOrder for matching properties on session
  outerOrder.forEach(function (type) {
    grammar[type].forEach(function (obj) {
      if (obj.name in session && session[obj.name] != null) {
        sdp.push(makeLine(type, obj, session));
      }
      else if (obj.push in session && session[obj.push] != null) {
        session[obj.push].forEach(function (el) {
          sdp.push(makeLine(type, obj, el));
        });
      }
    });
  });

  // then for each media line, follow the innerOrder
  session.media.forEach(function (mLine) {
    sdp.push(makeLine('m', grammar.m[0], mLine));

    innerOrder.forEach(function (type) {
      grammar[type].forEach(function (obj) {
        if (obj.name in mLine && mLine[obj.name] != null) {
          sdp.push(makeLine(type, obj, mLine));
        }
        else if (obj.push in mLine && mLine[obj.push] != null) {
          mLine[obj.push].forEach(function (el) {
            sdp.push(makeLine(type, obj, el));
          });
        }
      });
    });
  });

  return sdp.join('\r\n') + '\r\n';
};
<|endoftext|>


<commit_before>window.startExtension = function() {
    chrome.storage.sync.get({
        filterBait: true,
        filterPro: true,
        silent: true
      }, function(items) {

      var clickbaitCount = 0,
          articleCount = 0,
          plusCount = 0;
      var clickbaitFiltered = [],
          articlesN = [],
          plus = [];
      var filterPlus = items.filterPro;
      var filterBait = items.filterBait;
      var silent     = items.silent;

      var articles = $('article');
      if(silent) {
        console.log = function() {}
      }

      console.log("Found %s number of articles!", articles.length);

      if(filterPlus) {
        //console.log($('.abSlimList > li'));
        $('.abSlimList > li').each(function(i) {
          var smallArticle = $(this);
          smallArticle.find('span').each(function(j) {
            var span = $(this);
            console.log(span);
            if(span.text().indexOf('PLUS') >= 0) {
              smallArticle.remove();
            }
          });
        })
      }

      articles.each(function(index) {
        var article = $(this);
        article.children().each(function(i) {
          var a = $(this);
          var filtered = false;
          var header = $(a.find('h2')[0]).text().replace(/(\r\n|\n|\r)/gm, '');
          var paragraph = "";

          $(a.find('p')).each(function(i) {
            var p = $(this).text().replace(/(\r\n|\n|\r)/gm, '');
            paragraph += p;//p ? p : '';
          });
          if(header && paragraph) {
            console.log("Header: '%s'", header);
            console.log("paragraph: '%s'", paragraph);
            if(filterPlus) {
              if(paragraph.indexOf('PLUS') >= 0) {
                plus.push([header, paragraph]);
                plusCount++;
                article.remove();
                filtered = true;
              } else {
                $(article.find('span')).each(function(i) {
                  if($(this).text().indexOf('PLUS') >= 0) {
                    plus.push([header, paragraph]);
                    plusCount++;
                    article.remove();
                    filtered = true;
                  }
                })
              }
            }

            //console.log("filtered: %s, filterBait: %s, clickbait: %s", filtered, filterBait, window.isClickbait(header, paragraph));
            if(window.isClickbait(header, paragraph)) {
              clickbaitCount++;
              clickbaitFiltered.push([header, paragraph]);
              article.remove();
            } else {
              articlesN.push([header, paragraph]);
              articleCount++;
            }
          }
        });
      });

      console.log("%s of %s are clickbait. %s%. %s PLUS articles", clickbaitCount, articles.length, (clickbaitCount/articles.length*100), plusCount);
      console.log("Filtered articles:");
      console.log(clickbaitFiltered);
      console.log("Not filtered articles:");
      console.log(articlesN);
      console.log("PLUS articles:");
      console.log(plus);
    });
}
<commit_msg>refactor<commit_after>window.startExtension = function() {
    chrome.storage.sync.get({
        filterBait: true,
        filterPro: true,
        silent: true
      }, function(items) {

      var clickbaitCount = 0,
          articleCount = 0,
          plusCount = 0;
      var clickbaitFiltered = [],
          articlesN = [],
          plus = [];
      var filterPlus = items.filterPro;
      var filterBait = items.filterBait;
      var silent     = items.silent;

      var articles = $('article');
      if(silent) {
        console.log = function() {}
      }

      console.log("Found %s number of articles!", articles.length);

      if(filterPlus) {
        //console.log($('.abSlimList > li'));
        $('.abSlimList > li').each(function(i) {
          var smallArticle = $(this);
          smallArticle.find('span').each(function(j) {
            var span = $(this);
            console.log(span);
            if(span.text().indexOf('PLUS') >= 0) {
              smallArticle.remove();
            }
          });
        })
      }

      articles.each(function(index) {
        var article = $(this);
        article.children().each(function(i) {
          var a = $(this);
          var filtered = false;
          var header = $(a.find('h2')[0]).text().replace(/(\r\n|\n|\r)/gm, '');
          var paragraph = "";

          $(a.find('p')).each(function(i) {
            var p = $(this).text().replace(/(\r\n|\n|\r)/gm, '');
            paragraph += p;//p ? p : '';
          });
          if(header && paragraph) {
            console.log("Header: '%s': %s", header, window.headerBait(header));
            console.log("paragraph: '%s': %s", paragraph, window.paraBait(paragraph));
            if(filterPlus) {
              if(paragraph.indexOf('PLUS') >= 0) {
                plus.push([header, paragraph]);
                plusCount++;
                article.remove();
                filtered = true;
              } else {
                $(article.find('span')).each(function(i) {
                  if($(this).text().indexOf('PLUS') >= 0) {
                    plus.push([header, paragraph]);
                    plusCount++;
                    article.remove();
                    filtered = true;
                  }
                })
              }
            }

            //console.log("filtered: %s, filterBait: %s, clickbait: %s", filtered, filterBait, window.isClickbait(header, paragraph));
            if(window.isClickbait(header, paragraph)) {
              clickbaitCount++;
              clickbaitFiltered.push([header, paragraph]);
              article.remove();
            } else {
              articlesN.push([header, paragraph]);
              articleCount++;
            }
          }
        });
      });

      console.log("%s of %s are clickbait. %s%. %s PLUS articles", clickbaitCount, articles.length, (clickbaitCount/articles.length*100), plusCount);
      console.log("Filtered articles:");
      console.log(clickbaitFiltered);
      console.log("Not filtered articles:");
      console.log(articlesN);
      console.log("PLUS articles:");
      console.log(plus);
    });
}
<|endoftext|>


<commit_before>Module.register("news", {

  defaults: {
    articlesEndpoint: "https://newsapi.org/v1/articles?",
    sourcesEndpoint: "https://newsapi.org/v1/sources",
    source: "source=cnn",
    sortBy: "sortBy=top",
    apiKey: ""
  },

  getHeader: function(){
    return this.data.header //--> need to set header to News Feed
  },

  getTranslations: function(){
    return false;
  },

  start: function(){

    Log.info("Starting module: " + this.name);

    moment.locale(config.language);
    this.author = null;
    this.description = null;
    this.url = null;
    this.urlToImage = null;

    this.headlines = [];
    this.attributionLink = null;
    this.sendSocketNotification("LISTEN_NEWS", this.defaults);
    this.loaded = false;
  },

  getDom: function() {
    var div = document.createElement("div");
    div.className = "news-display";

    var articleDisplay = document.createElement("span");
    articleDisplay.className = "article-display";

    var ol = document.createElement("ol");

    for(i = 0; i < this.headlines.length; i++) {
        var li = document.createElement("li");
            li.className = "article-" + i;
            li.innerHTML = this.headlines[i];
            ol.appendChild(li);
    }
    articleDisplay.appendChild(ol);
    var sourceLi = document.createElement("li");
        sourceLi.className = "attribution-link"
        sourceLi.innerHTML = attributionLink;
        sourceLi.style.fontSize = "medium";
        sourceLi.style.listStyleType = "none";

    div.appendChild(articleDisplay);
    div.appendChild(sourceLi);

    return div;
  },

  notificationReceived: function(notification){
      if(notification === "news"){
        console.log("======== news request ========");
        this.sendSocketNotification("NEWS", this.defaults);

      }

  },

  socketNotificationReceived: function(notification, payload){
    Log.log("socket received from Node Helper");
    if(notification === "NEWS_RESULT"){
      var newsJSON = payload;
        for(i = 0; i < 5; i++){
          this.headlines.push(newsJSON["articles"][i]["title"]);
        }
        this.attributionLink = "powered by News API";
        this.updateDom();

    }
  }

});
<commit_msg>add syntax<commit_after>Module.register("news", {

  defaults: {
    articlesEndpoint: "https://newsapi.org/v1/articles?",
    sourcesEndpoint: "https://newsapi.org/v1/sources",
    source: "source=cnn",
    sortBy: "sortBy=top",
    apiKey: "apiKey="
  },

  getHeader: function(){
    return this.data.header //--> need to set header to News Feed
  },

  getTranslations: function(){
    return false;
  },

  start: function(){

    Log.info("Starting module: " + this.name);

    moment.locale(config.language);
    this.author = null;
    this.description = null;
    this.url = null;
    this.urlToImage = null;

    this.headlines = [];
    this.attributionLink = null;
    this.sendSocketNotification("LISTEN_NEWS", this.defaults);
    this.loaded = false;
  },

  getDom: function() {
    var div = document.createElement("div");
    div.className = "news-display";

    var articleDisplay = document.createElement("span");
    articleDisplay.className = "article-display";

    var ol = document.createElement("ol");

    for(i = 0; i < this.headlines.length; i++) {
        var li = document.createElement("li");
            li.className = "article-" + i;
            li.innerHTML = this.headlines[i];
            ol.appendChild(li);
    }
    articleDisplay.appendChild(ol);
    var sourceLi = document.createElement("li");
        sourceLi.className = "attribution-link"
        sourceLi.innerHTML = attributionLink;
        sourceLi.style.fontSize = "medium";
        sourceLi.style.listStyleType = "none";

    div.appendChild(articleDisplay);
    div.appendChild(sourceLi);

    return div;
  },

  notificationReceived: function(notification){
      if(notification === "news"){
        console.log("======== news request ========");
        this.sendSocketNotification("NEWS", this.defaults);

      }

  },

  socketNotificationReceived: function(notification, payload){
    Log.log("socket received from Node Helper");
    if(notification === "NEWS_RESULT"){
      var newsJSON = payload;
        for(i = 0; i < 5; i++){
          this.headlines.push(newsJSON["articles"][i]["title"]);
        }
        this.attributionLink = "powered by News API";
        this.updateDom();

    }
  }

});
<|endoftext|>


<commit_before>import Ember from 'ember';

import scheduler from 'vertical-collection/-private/scheduler';
import Token from 'vertical-collection/-private/scheduler/token';

import VirtualComponent from 'vertical-collection/-private/data-view/virtual-component';
import insertRangeBefore from 'vertical-collection/-private/data-view/utils/insert-range-before';
import objectAt from 'vertical-collection/-private/data-view/utils/object-at';

import { assert } from 'vertical-collection/-debug/helpers';

const {
  A,
  get,
  set
} = Ember;

export default class Radar {
  constructor() {
    this.token = new Token();

    this._scrollTop = 0;
    this._prependOffset = 0;
    this._scrollTopOffset = null;

    this._itemContainer = null;
    this._scrollContainer = null;
    this.didUpdate = () => {};

    this.minHeight = 0;
    this.bufferSize = 0;
    this.renderFromLast = 0;

    this._occludedContentBefore = new VirtualComponent(document.createElement('occluded-content'));
    this._occludedContentAfter = new VirtualComponent(document.createElement('occluded-content'));

    this.virtualComponents = A([this._occludedContentBefore, this._occludedContentAfter]);
    this.orderedComponents = [];
  }

  init(itemContainer, scrollContainer, minHeight, bufferSize, renderFromLast) {
    this.itemContainer = itemContainer;
    this.scrollContainer = scrollContainer;

    this.minHeight = minHeight;
    this.bufferSize = bufferSize;
    this.renderFromLast = renderFromLast;

    this._updateVirtualComponentPool();
    this.scheduleUpdate();
  }

  destroy() {
    this.token.cancel();

    for (let i = 0; i < this.orderedComponents.length; i++) {
      this.orderedComponents[i].destroy();
    }

    this.orderedComponents = null;
    set(this, 'virtualComponents', null);

  }

  schedule(queueName, job) {
    return scheduler.schedule(queueName, job, this.token);
  }

  /*
   * Schedules an update for the next RAF
   *
   * This will first run _updateVirtualComponents in the sync phase, which figures out what
   * components need to be rerendered and updates the appropriate VCs and moves their associated
   * DOM. At the end of the `sync` phase the runloop is flushed and Glimmer renders the changes.
   *
   * By the `affect` phase the Radar should have had time to measure, meaning it has all of the
   * current info and we can send actions for any changes.
   *
   * @private
   */
  scheduleUpdate() {
    if (this._nextUpdate) {
      return;
    }

    this._nextUpdate = this.schedule('sync', () => {
      this._nextUpdate = null;
      this._scrollTop = this.scrollContainer.scrollTop;

      const delta = this._updateIndexes();
      this._updateVirtualComponents(delta);

      this.schedule('measure', () => {
        if (this._prependOffset !== 0) {
          this.scrollTop += this._prependOffset;
          this._prependOffset = 0;
        }

        this.didUpdate();
      });
    });
  }

  get totalItems() {
    return this.items ? get(this.items, 'length') : 0;
  }

  set itemContainer(itemContainer) {
    this._itemContainer = itemContainer;
    this._scrollTopOffset = null;
  }

  get itemContainer() {
    return this._itemContainer;
  }

  set scrollContainer(scrollContainer) {
    this._scrollContainer = scrollContainer;
    this._scrollTopOffset = null;
    this.scrollContainerHeight = scrollContainer.getBoundingClientRect().height;
  }

  get scrollContainer() {
    return this._scrollContainer;
  }

  get scrollTop() {
    return this._scrollTop;
  }

  set scrollTop(scrollTop) {
    this.scrollContainer.scrollTop = this._scrollTop = scrollTop;
  }

  /*
   * Represents the offset between the top of the itemContainer and the top of scrollContainer
   * when `scrollTop === 0`. Basically, the item container could "begin" anywhere in the
   * scrollContainer. There could be some header or other element _before_ the itemContainer that
   * pushes it down a little bit. In this case, the true position of the scrollContainer's top
   * relative to our measurements, which begin at 0, is `scrollTop - scrollTopOffset`. In other
   * words, while we _can't_ have a negative `scrollTop`, we _can_ have a negative `visibleTop`.
   */
  get scrollTopOffset() {
    if (this._scrollTopOffset === null) {
      const marginTop = parseInt(this.itemContainer.style.marginTop || 0);
      const itemContainerTop = this.itemContainer ? this.itemContainer.getBoundingClientRect().top : 0;
      const scrollContainerTop = this.scrollContainer ? this.scrollContainer.getBoundingClientRect().top : 0;

      this._scrollTopOffset = (this.scrollTop + (itemContainerTop - marginTop)) - scrollContainerTop;
    }

    return this._scrollTopOffset;
  }

  /*
   * `prependOffset` exists because there are times when we need to do the following in this exact
   * order:
   *
   * 1. Prepend, which means we need to adjust the scroll position by `minHeight * numPrepended`
   * 2. Calculate the items that will be displayed after the prepend, and move VCs around as
   *    necessary (`scheduleUpdate`).
   * 3. Actually add the amount prepended to `scrollContainer.scrollTop`
   *
   * This is due to some strange behavior in Chrome where it will modify `scrollTop` on it's own
   * when prepending item elements. We seem to avoid this behavior by doing these things in a RAF
   * in this exact order.
   */
  get visibleTop() {
    return this.scrollTop + this._prependOffset + this.scrollTopOffset;
  }

  set visibleTop(visibleTop) {
    assert('Must set visibleTop to a number', typeof visibleTop === 'number');

    this.scrollTop = visibleTop - this._prependOffset - this.scrollTopOffset;
  }

  get visibleBottom() {
    return this.visibleTop + this.scrollContainerHeight;
  }

  /*
   * Update the VirtualComponents state based on current scroll position
   *
   * @private
   */
  _updateVirtualComponents(itemDelta) {
    const {
      items,
      orderedComponents,
      itemContainer,
      _occludedContentBefore,
      _occludedContentAfter,

      firstItemIndex,
      lastItemIndex,
      totalBefore,
      totalAfter
    } = this;

    const offsetAmount = Math.abs(itemDelta % orderedComponents.length);

    if (offsetAmount > 0) {
      if (itemDelta < 0) {
        // Scrolling up
        let movedComponents = orderedComponents.splice(-offsetAmount);
        orderedComponents.unshift(...movedComponents);

        const firstNode = movedComponents[0].realUpperBound;
        const lastNode = movedComponents[movedComponents.length - 1].realLowerBound;

        insertRangeBefore(_occludedContentBefore.realLowerBound.nextSibling, firstNode, lastNode);
      } else if (itemDelta > 0) {
        // Scrolling down
        let movedComponents = orderedComponents.splice(0, offsetAmount);
        orderedComponents.push(...movedComponents);

        const firstNode = movedComponents[0].realUpperBound;
        const lastNode = movedComponents[movedComponents.length - 1].realLowerBound;

        insertRangeBefore(_occludedContentAfter.realUpperBound, firstNode, lastNode);
      }
    }

    for (let i = 0, itemIndex = firstItemIndex; itemIndex <= lastItemIndex; i++, itemIndex++) {
      orderedComponents[i].recycle(objectAt(items, itemIndex), itemIndex);
    }

    _occludedContentBefore.element.style.height = `${totalBefore}px`;
    _occludedContentAfter.element.style.height = `${totalAfter}px`;
    itemContainer.style.minHeight = '';
  }

  /*
   * Sets up _virtualComponents, which is meant to be a static pool of components that we render to.
   * In order to decrease the time spent rendering and diffing, we pull the {{each}} out of the DOM
   * and only replace the content of _virtualComponents which are removed/added.
   *
   * For instance, if we start with the following and scroll down, items 2 and 3 do not need to be
   * rerendered, only item 1 needs to be removed and only item 4 needs to be added. So we replace
   * item 1 with item 4, and then manually move the DOM:
   *
   *   1                        4                         2
   *   2 -> replace 1 with 4 -> 2 -> manually move DOM -> 3
   *   3                        3                         4
   *
   * However, _virtualComponents is still out of order. Rather than keep track of the state of
   * things in _virtualComponents, we track the visually ordered components in the
   * _orderedComponents array. This is possible because all of our operations are relatively simple,
   * popping some number of components off one end and pushing them onto the other.
   *
   * @private
   */
  _updateVirtualComponentPool() {
    const {
      scrollContainerHeight,
      bufferSize,
      minHeight,
      virtualComponents,
      orderedComponents,
      totalItems,
      items
    } = this;

    // The total number of components is determined by the minimum number required to span the
    // container with its buffers. Combined with the above rendering strategy this is fairly
    // performant, even if mean item size is above the minimum.
    const totalHeight = scrollContainerHeight + (scrollContainerHeight * bufferSize * 2);
    const totalComponents = Math.min(totalItems, Math.ceil(totalHeight / minHeight) + 1);
    const delta = totalComponents - orderedComponents.length;

    if (delta > 0) {
      const firstItemIndex = orderedComponents.length > 0 ? orderedComponents[orderedComponents.length - 1].index + 1 : 0;

      for (let i = 0; i < delta; i++) {
        let component = new VirtualComponent();
        set(component, 'content', objectAt(items, firstItemIndex + i));

        virtualComponents.insertAt(virtualComponents.get('length') - 1, component);
        orderedComponents.push(component);
      }
    } else if (delta < 0) {
      for (let i = delta; i < 0; i++) {
        let component = orderedComponents.pop();

        virtualComponents.removeObject(component);
        component.destroy();
      }
    }
  }

  _updatePoolContents() {
    const {
      orderedComponents,
      firstItemIndex,
      items
    } = this;

    for (let i = 0; i < orderedComponents.length; i++) {
      let component = orderedComponents[i];
      let newContent = objectAt(items, firstItemIndex + i);

      set(component, 'content', newContent);
    }
  }

  prepend(items, numPrepended) {
    this.items = items;
    this.firstItemIndex += numPrepended;
    this.lastItemIndex += numPrepended;

    this._updateVirtualComponentPool();
    this.scheduleUpdate();

    this._prependOffset = numPrepended * this.minHeight;
  }

  append(items) {
    this.items = items;

    this._updateVirtualComponentPool();
    this.scheduleUpdate();
  }

  updateItems(items, isReset = false) {
    this.items = items;

    if (isReset) {
      this.firstItemIndex = null;
      this.lastItemIndex = null;
      this._updateVirtualComponentPool();
      this.scheduleUpdate();
    } else {
      this._updatePoolContents();
    }
  }
}
<commit_msg>simplify scroll update (#62)<commit_after>import Ember from 'ember';

import scheduler from 'vertical-collection/-private/scheduler';
import Token from 'vertical-collection/-private/scheduler/token';

import VirtualComponent from 'vertical-collection/-private/data-view/virtual-component';
import insertRangeBefore from 'vertical-collection/-private/data-view/utils/insert-range-before';
import objectAt from 'vertical-collection/-private/data-view/utils/object-at';

import { assert } from 'vertical-collection/-debug/helpers';

const {
  A,
  get,
  set
} = Ember;

export default class Radar {
  constructor() {
    this.token = new Token();

    this._scrollTop = 0;
    this._prependOffset = 0;
    this._scrollTopOffset = null;

    this._itemContainer = null;
    this._scrollContainer = null;
    this.didUpdate = () => {};

    this.minHeight = 0;
    this.bufferSize = 0;
    this.renderFromLast = 0;

    this._occludedContentBefore = new VirtualComponent(document.createElement('occluded-content'));
    this._occludedContentAfter = new VirtualComponent(document.createElement('occluded-content'));

    this.virtualComponents = A([this._occludedContentBefore, this._occludedContentAfter]);
    this.orderedComponents = [];
  }

  init(itemContainer, scrollContainer, minHeight, bufferSize, renderFromLast) {
    this.itemContainer = itemContainer;
    this.scrollContainer = scrollContainer;

    this.minHeight = minHeight;
    this.bufferSize = bufferSize;
    this.renderFromLast = renderFromLast;

    this._updateVirtualComponentPool();
    this.scheduleUpdate();
  }

  destroy() {
    this.token.cancel();

    for (let i = 0; i < this.orderedComponents.length; i++) {
      this.orderedComponents[i].destroy();
    }

    this.orderedComponents = null;
    set(this, 'virtualComponents', null);

  }

  schedule(queueName, job) {
    return scheduler.schedule(queueName, job, this.token);
  }

  /*
   * Schedules an update for the next RAF
   *
   * This will first run _updateVirtualComponents in the sync phase, which figures out what
   * components need to be rerendered and updates the appropriate VCs and moves their associated
   * DOM. At the end of the `sync` phase the runloop is flushed and Glimmer renders the changes.
   *
   * By the `affect` phase the Radar should have had time to measure, meaning it has all of the
   * current info and we can send actions for any changes.
   *
   * @private
   */
  scheduleUpdate() {
    if (this._nextUpdate) {
      return;
    }

    this._nextUpdate = this.schedule('sync', () => {
      this._nextUpdate = null;
      this._scrollTop = this.scrollContainer.scrollTop;

      const delta = this._updateIndexes();
      this._updateVirtualComponents(delta);

      this.schedule('measure', () => {
        if (this._prependOffset !== 0) {
          this.scrollTop += this._prependOffset;
          this._prependOffset = 0;
        }

        this.didUpdate();
      });
    });
  }

  get totalItems() {
    return this.items ? get(this.items, 'length') : 0;
  }

  set itemContainer(itemContainer) {
    this._itemContainer = itemContainer;
    this._scrollTopOffset = null;
  }

  get itemContainer() {
    return this._itemContainer;
  }

  set scrollContainer(scrollContainer) {
    this._scrollContainer = scrollContainer;
    this._scrollTopOffset = null;
    this.scrollContainerHeight = scrollContainer.getBoundingClientRect().height;
  }

  get scrollContainer() {
    return this._scrollContainer;
  }

  get scrollTop() {
    return this._scrollTop;
  }

  set scrollTop(scrollTop) {
    this.scrollContainer.scrollTop = this._scrollTop = scrollTop;
  }

  /*
   * Represents the offset between the top of the itemContainer and the top of scrollContainer
   * when `scrollTop === 0`. Basically, the item container could "begin" anywhere in the
   * scrollContainer. There could be some header or other element _before_ the itemContainer that
   * pushes it down a little bit. In this case, the true position of the scrollContainer's top
   * relative to our measurements, which begin at 0, is `scrollTop - scrollTopOffset`. In other
   * words, while we _can't_ have a negative `scrollTop`, we _can_ have a negative `visibleTop`.
   */
  get scrollTopOffset() {
    if (this._scrollTopOffset === null) {
      const marginTop = parseInt(this.itemContainer.style.marginTop || 0);
      const itemContainerTop = this.itemContainer ? this.itemContainer.getBoundingClientRect().top : 0;
      const scrollContainerTop = this.scrollContainer ? this.scrollContainer.getBoundingClientRect().top : 0;

      this._scrollTopOffset = (this.scrollTop + (itemContainerTop - marginTop)) - scrollContainerTop;
    }

    return this._scrollTopOffset;
  }

  /*
   * `prependOffset` exists because there are times when we need to do the following in this exact
   * order:
   *
   * 1. Prepend, which means we need to adjust the scroll position by `minHeight * numPrepended`
   * 2. Calculate the items that will be displayed after the prepend, and move VCs around as
   *    necessary (`scheduleUpdate`).
   * 3. Actually add the amount prepended to `scrollContainer.scrollTop`
   *
   * This is due to some strange behavior in Chrome where it will modify `scrollTop` on it's own
   * when prepending item elements. We seem to avoid this behavior by doing these things in a RAF
   * in this exact order.
   */
  get visibleTop() {
    return this.scrollTop + this._prependOffset + this.scrollTopOffset;
  }

  set visibleTop(visibleTop) {
    assert('Must set visibleTop to a number', typeof visibleTop === 'number');

    this.scrollTop = visibleTop - this._prependOffset - this.scrollTopOffset;
  }

  get visibleBottom() {
    return this.visibleTop + this.scrollContainerHeight;
  }

  /*
   * Update the VirtualComponents state based on current scroll position
   *
   * @private
   */
  _updateVirtualComponents(itemDelta) {
    const {
      items,
      orderedComponents,
      itemContainer,
      _occludedContentBefore,
      _occludedContentAfter,

      firstItemIndex,
      lastItemIndex,
      totalBefore,
      totalAfter
    } = this;

    const offsetAmount = Math.abs(itemDelta % orderedComponents.length);

    if (offsetAmount > 0) {
      if (itemDelta < 0) {
        // Scrolling up
        let movedComponents = orderedComponents.splice(-offsetAmount);
        orderedComponents.unshift(...movedComponents);

        const firstNode = movedComponents[0].realUpperBound;
        const lastNode = movedComponents[movedComponents.length - 1].realLowerBound;

        insertRangeBefore(_occludedContentBefore.realLowerBound.nextSibling, firstNode, lastNode);
      } else if (itemDelta > 0) {
        // Scrolling down
        let movedComponents = orderedComponents.splice(0, offsetAmount);
        orderedComponents.push(...movedComponents);

        const firstNode = movedComponents[0].realUpperBound;
        const lastNode = movedComponents[movedComponents.length - 1].realLowerBound;

        insertRangeBefore(_occludedContentAfter.realUpperBound, firstNode, lastNode);
      }
    }

    for (let i = 0, itemIndex = firstItemIndex; itemIndex <= lastItemIndex; i++, itemIndex++) {
      orderedComponents[i].recycle(objectAt(items, itemIndex), itemIndex);
    }

    _occludedContentBefore.element.style.height = `${totalBefore}px`;
    _occludedContentAfter.element.style.height = `${totalAfter}px`;
    itemContainer.style.minHeight = '';
  }

  /*
   * Sets up _virtualComponents, which is meant to be a static pool of components that we render to.
   * In order to decrease the time spent rendering and diffing, we pull the {{each}} out of the DOM
   * and only replace the content of _virtualComponents which are removed/added.
   *
   * For instance, if we start with the following and scroll down, items 2 and 3 do not need to be
   * rerendered, only item 1 needs to be removed and only item 4 needs to be added. So we replace
   * item 1 with item 4, and then manually move the DOM:
   *
   *   1                        4                         2
   *   2 -> replace 1 with 4 -> 2 -> manually move DOM -> 3
   *   3                        3                         4
   *
   * However, _virtualComponents is still out of order. Rather than keep track of the state of
   * things in _virtualComponents, we track the visually ordered components in the
   * _orderedComponents array. This is possible because all of our operations are relatively simple,
   * popping some number of components off one end and pushing them onto the other.
   *
   * @private
   */
  _updateVirtualComponentPool() {
    const {
      scrollContainerHeight,
      bufferSize,
      minHeight,
      virtualComponents,
      orderedComponents,
      totalItems,
      items
    } = this;

    // The total number of components is determined by the minimum number required to span the
    // container with its buffers. Combined with the above rendering strategy this is fairly
    // performant, even if mean item size is above the minimum.
    const totalHeight = scrollContainerHeight + (scrollContainerHeight * bufferSize * 2);
    const totalComponents = Math.min(totalItems, Math.ceil(totalHeight / minHeight) + 1);
    const delta = totalComponents - orderedComponents.length;

    if (delta > 0) {
      const firstItemIndex = orderedComponents.length > 0 ? orderedComponents[orderedComponents.length - 1].index + 1 : 0;

      for (let i = 0; i < delta; i++) {
        let component = new VirtualComponent();
        set(component, 'content', objectAt(items, firstItemIndex + i));

        virtualComponents.insertAt(virtualComponents.get('length') - 1, component);
        orderedComponents.push(component);
      }
    } else if (delta < 0) {
      for (let i = delta; i < 0; i++) {
        let component = orderedComponents.pop();

        virtualComponents.removeObject(component);
        component.destroy();
      }
    }
  }

  prepend(items, numPrepended) {
    this.items = items;
    this.firstItemIndex += numPrepended;
    this.lastItemIndex += numPrepended;

    this._updateVirtualComponentPool();
    this.scheduleUpdate();

    this._prependOffset = numPrepended * this.minHeight;
  }

  append(items) {
    this.items = items;

    this._updateVirtualComponentPool();
    this.scheduleUpdate();
  }

  updateItems(items, isReset = false) {
    this.items = items;

    if (isReset) {
      this.firstItemIndex = null;
      this.lastItemIndex = null;
      this._updateVirtualComponentPool();
    }

    this.scheduleUpdate();
  }
}
<|endoftext|>


<commit_before>import Component from '@ember/component'
import { get } from '@ember/object'
import { scheduleOnce } from '@ember/runloop'

import layout from '../templates/components/ember-inline-editor';

const {
  $
} = Ember

export default Component.extend({
  layout,
  classNameBindings: ['isVisible:is-visible:is-hidden'],

  textFields: ['search', 'url', 'text', 'phone', 'email', 'number'],
  textAreaFields: ['textarea'],

  didReceiveAttrs () {
    scheduleOnce('afterRender', () => {
      $(this.element).children().first().focus()
    })
  },

  keyUp (e) {
    let field = get(this, 'field')
    let textAreaFields = get(this, 'textAreaFields')

    let isEnter = e.which === 13 || e.keyCode === 13
    let isEsc   = e.which === 27 || e.keyCode === 27

    /*
     * If the user pressed enter and it's not a textarea
     * field, we send the save action
    */

    if (isEnter && textAreaFields.indexOf(field) < 0) {
      this.sendAction('on-save')

    } else if (isEsc) {
      this.sendAction('on-close')
    }
  },
});
<commit_msg>Remove jQuery<commit_after>import Component from '@ember/component'
import { get } from '@ember/object'
import { scheduleOnce } from '@ember/runloop'

import layout from '../templates/components/ember-inline-editor'

const isInputField = (el) => {
  const { tagName } = el

  if (!tagName) {
    return false
  }

  return ['input', 'textarea', 'select'].includes(tagName.toLowerCase())
}

export default Component.extend({
  layout,
  classNameBindings: ['isVisible:is-visible:is-hidden'],

  textFields: ['search', 'url', 'text', 'phone', 'email', 'number'],
  textAreaFields: ['textarea'],

  didReceiveAttrs() {
    scheduleOnce('afterRender', this.focusOnInput.bind(this))
  },

  focusOnInput() {
    const children = this.element.childNodes

    children.forEach(child => {
      if (isInputField(child)) child.focus()
    })
  },

  keyUp(ev) {
    const field = get(this, 'field')
    const textAreaFields = get(this, 'textAreaFields')

    const { keyCode } = ev

    const isEnter = keyCode === 13
    const isEsc = keyCode === 27

    if (isEnter && !textAreaFields.includes(field)) {
      this.sendAction('on-save')

    } else if (isEsc) {
      this.sendAction('on-close')
    }
  },
});
<|endoftext|>


<commit_before>import 'babel/polyfill';
import Allele from './allele';
import { NotImplementedError } from '../errors';

export default class Individual {
    constructor(alleles) {
        this._alleles = alleles;
    }

    get alleles() {
        return this.deconstruct(this._alleles);
    }

    set alleles(alleles) {
        this._alleles = this.reconstruct(alleles);
    }

    deconstruct(alleles) {
        return alleles;
    }

    reconstruct(alleles) {
        return alleles;
    }

    fitness() {
        throw new NotImplementedError(`${this.constructor.name}.fitness`);
    }
}
<commit_msg>added allele method to individual class<commit_after>import 'babel/polyfill';
import Allele from './allele';
import { NotImplementedError, ImproperlyConfiguredError } from '../errors';
import { shuffle } from '../utils';

export default class Individual {
    constructor(alleles, possibleAlleles) {
        this._alleles = alleles;
        this.possibleAlleles = possibleAlleles;
    }

    get alleles() {
        return this.deconstruct(this._alleles);
    }

    set alleles(alleles) {
        this._alleles = this.reconstruct(alleles);
    }

    deconstruct(alleles) {
        return alleles;
    }

    reconstruct(alleles) {
        return alleles;
    }

    fitness() {
        throw new NotImplementedError(`${this.constructor.name}.fitness`);
    }

    allele() {
        shuffle(this.possibleAlleles)[0];
    }
}
<|endoftext|>


<commit_before>'use strict'

const unixfsEngine = require('ipfs-unixfs-engine')
const Importer = unixfsEngine.Importer
const Exporter = unixfsEngine.Exporter
const UnixFS = require('ipfs-unixfs')
const through = require('through2')
const isStream = require('isstream')
const promisify = require('promisify-es6')
const Duplex = require('stream').Duplex
const multihashes = require('multihashes')

module.exports = function files (self) {
  return {
    createAddStream: (callback) => {
      const i = new Importer(self._dagS)
      const ds = new Duplex({ objectMode: true })

      ds._read = (n) => {}
      ds._write = (file, enc, next) => {
        i.write(file)
        next()
      }

      ds.end = () => {
        i.end()
      }

      let counter = 0

      i.on('data', (file) => {
        counter++
        self.object.get(file.multihash, (err, node) => {
          if (err) {
            return ds.emit('error', err)
          }
          ds.push({path: file.path, node: node})
          counter--
        })
      })

      i.on('end', () => {
        function canFinish () {
          if (counter === 0) {
            ds.push(null)
          } else {
            setTimeout(canFinish, 100)
          }
        }
        canFinish()
      })

      callback(null, ds)
    },
    add: promisify((data, callback) => {
      // Buffer input
      if (Buffer.isBuffer(data)) {
        data = [{
          path: '',
          content: data
        }]
      }
      // Readable stream input
      if (isStream.isReadable(data)) {
        data = [{
          path: '',
          content: data
        }]
      }
      if (!callback || typeof callback !== 'function') {
        callback = function noop () {}
      }
      if (!Array.isArray(data)) {
        return callback(new Error('"data" must be an array of { path: string, content: Buffer|Readable } or Buffer or Readable'))
      }

      const i = new Importer(self._dagS)
      const res = []

      // Transform file info tuples to DAGNodes
      i.pipe(through.obj((info, enc, next) => {
        const mh = multihashes.toB58String(info.multihash)
        self._dagS.get(mh, (err, node) => {
          if (err) return callback(err)
          var obj = {
            path: info.path || mh,
            node: node
          }
          res.push(obj)
          next()
        })
      }, (done) => {
        callback(null, res)
      }))

      data.forEach((tuple) => {
        i.write(tuple)
      })

      i.end()
    }),

    cat: promisify((hash, callback) => {
      if (typeof hash === 'function') {
        callback = hash
        return callback('You must supply a multihash', null)
      }
      self._dagS.get(hash, (err, fetchedNode) => {
        if (err) {
          return callback(err, null)
        }
        const data = UnixFS.unmarshal(fetchedNode.data)
        if (data.type === 'directory') {
          callback('This dag node is a directory', null)
        } else {
          const exportStream = Exporter(hash, self._dagS)
          exportStream.once('data', (object) => {
            callback(null, object.content)
          })
        }
      })
    }),

    get: (hash, callback) => {
      var exportFile = Exporter(hash, self._dagS)
      callback(null, exportFile)
    }
  }
}
<commit_msg>CR updates<commit_after>'use strict'

const unixfsEngine = require('ipfs-unixfs-engine')
const Importer = unixfsEngine.Importer
const Exporter = unixfsEngine.Exporter
const UnixFS = require('ipfs-unixfs')
const through = require('through2')
const isStream = require('isstream')
const promisify = require('promisify-es6')
const Duplex = require('stream').Duplex
const multihashes = require('multihashes')

module.exports = function files (self) {
  return {
    createAddStream: (callback) => {
      const i = new Importer(self._dagS)
      const ds = new Duplex({ objectMode: true })

      ds._read = (n) => {}
      ds._write = (file, enc, next) => {
        i.write(file)
        next()
      }

      ds.end = () => {
        i.end()
      }

      let counter = 0

      i.on('data', (file) => {
        counter++
        self.object.get(file.multihash, (err, node) => {
          if (err) {
            return ds.emit('error', err)
          }
          ds.push({path: file.path, node: node})
          counter--
        })
      })

      i.on('end', () => {
        function canFinish () {
          if (counter === 0) {
            ds.push(null)
          } else {
            setTimeout(canFinish, 100)
          }
        }
        canFinish()
      })

      callback(null, ds)
    },
    add: promisify((data, callback) => {
      // Buffer input
      if (Buffer.isBuffer(data)) {
        data = [{
          path: '',
          content: data
        }]
      }
      // Readable stream input
      if (isStream.isReadable(data)) {
        data = [{
          path: '',
          content: data
        }]
      }
      if (!callback || typeof callback !== 'function') {
        callback = function noop () {}
      }
      if (!Array.isArray(data)) {
        return callback(new Error('"data" must be an array of { path: string, content: Buffer|Readable } or Buffer or Readable'))
      }

      const i = new Importer(self._dagS)
      const res = []

      // Transform file info tuples to DAGNodes
      i.pipe(through.obj((info, enc, next) => {
        const mh = multihashes.toB58String(info.multihash)
        self._dagS.get(mh, (err, node) => {
          if (err) return callback(err)
          var obj = {
            path: info.path || mh,
            node: node
          }
          res.push(obj)
          next()
        })
      }, (done) => {
        callback(null, res)
      }))

      data.forEach((tuple) => {
        i.write(tuple)
      })

      i.end()
    }),

    cat: promisify((hash, callback) => {
      if (typeof hash === 'function') {
        return callback(new Error('You must supply a multihash'))
      }
      self._dagS.get(hash, (err, fetchedNode) => {
        if (err) {
          return callback(err)
        }
        const data = UnixFS.unmarshal(fetchedNode.data)
        if (data.type === 'directory') {
          callback(new Error('This dag node is a directory'))
        } else {
          const exportStream = Exporter(hash, self._dagS)
          exportStream.once('data', (object) => {
            callback(null, object.content)
          })
        }
      })
    }),

    get: (hash, callback) => {
      var exportFile = Exporter(hash, self._dagS)
      callback(null, exportFile)
    }
  }
}
<|endoftext|>


<commit_before>/**
 * This JS is only a first release while testing
 * dynamic build of components for nodejs with
 * express.
 *
 * This should in near future adopt the same
 * developing architecture as
 *
 * http://github.com/component/component.io
 *
 * and
 *
 * http://github.com/hunterloftis/component-test
 *
 * It.
 */

var config = require('config');
var page = require('page');
var timeago = require('timeago');
var translations = require('translations');
var bus = require('bus');
var ua = require('user-agent');
var t = require('t');

/**
 * Load localization dictionaries to translation application
 */

translations.help(t);

/**
 * Init `t` component with locale as `es`
 */

t.lang(config['locale']);

/**
 * Mount applications.
 */

require('body-classes');
require('header');
require('homepage');
require('proposal');
require('law');
require('markdown-page');
require('signin');
require('signup');
require('forgot');
require('settings');
require('admin');
require('logout');

/**
 * Init `timeago` component with parameter locale
 */

<<<<<<< HEAD
timeago('.ago', { lang: 'es', interval: 10 });
=======
timeago('.ago', { lang: config['locale'], interval: 10 });
>>>>>>> 7cbecec0666a08751918c5b5559d1d85ce32abdb

/**
 * Render not found page.
 */

page('*', function(ctx, next) {
  console.log('Should render Not found.');
});

/**
 * Init page.js
 */
page({click: !ua.ie().lte(9)});

if(config['google analytics tracking id']) {
	require('ga')(config['google analytics tracking id']);
}<commit_msg>Fix unresolved conflict<commit_after>/**
 * This JS is only a first release while testing
 * dynamic build of components for nodejs with
 * express.
 *
 * This should in near future adopt the same
 * developing architecture as
 *
 * http://github.com/component/component.io
 *
 * and
 *
 * http://github.com/hunterloftis/component-test
 *
 * It.
 */

var config = require('config');
var page = require('page');
var timeago = require('timeago');
var translations = require('translations');
var bus = require('bus');
var ua = require('user-agent');
var t = require('t');

/**
 * Load localization dictionaries to translation application
 */

translations.help(t);

/**
 * Init `t` component with locale as `es`
 */

t.lang(config['locale']);

/**
 * Mount applications.
 */

require('body-classes');
require('header');
require('homepage');
require('proposal');
require('law');
require('markdown-page');
require('signin');
require('signup');
require('forgot');
require('settings');
require('admin');
require('logout');

/**
 * Init `timeago` component with parameter locale
 */

timeago('.ago', { lang: config['locale'], interval: 10 });

/**
 * Render not found page.
 */

page('*', function(ctx, next) {
  console.log('Should render Not found.');
});

/**
 * Init page.js
 */
page({click: !ua.ie().lte(9)});

if(config['google analytics tracking id']) {
	require('ga')(config['google analytics tracking id']);
}<|endoftext|>