<commit_before>import React from 'react';
import 'whatwg-fetch';
import { Grid, Row, Col,
  FormGroup, ControlLabel, Alert,
  Nav, Navbar, NavItem } from 'react-bootstrap';

const apiURL = '/merge/';

const Main = () => (
  <div>
    <AppNavbar />
    <MainContainer />
  </div>
);

const cleanMsg = msg => msg
  .replace(/^\s+/, '')
  .replace(/\s+$/, '')
  .replace(/ /g, '')
  .split(/\n/)
  .filter(_ => _);

const cleanSeqs = seqs => seqs
  .map((s, i) => [i, s])
  .filter(tup => tup[1] && tup[1].length);

class MainContainer extends React.Component {
  constructor(props) {
    super(props);
    this.handleChangeRef = this.handleChangeRef.bind(this);
    this.handleChangeAli = this.handleChangeAli.bind(this);
    this.handleMessage = this.handleMessage.bind(this);
    this.state = { ref: [], seqs: [], value: '', err: '' };
  }
  handleChangeRef(e) {
    this.setState({
      ref: cleanMsg(e.target.value),
      seqs: this.state.seqs.map(() => []),
      value: '',
      err: '',
    });
  }
  handleChangeAli(e, i) {
    const seqs = this.state.seqs.slice(0);
    seqs[i] = cleanMsg(e.target.value);
    this.setState({ seqs, value: '', err: '' });
    this.handleMessage(cleanSeqs(seqs));
  }
  handleMessage(seqs) {
    const ref = this.state.ref;
    const msg = { ref, seqs };
    fetch(apiURL, {
      method: 'POST',
      body: JSON.stringify(msg),
    }).then((response) => {
      response.json().then((json) => {
        this.setState({ value: json.result, err: '' });
      }).catch((err) => {
        this.setState({ err });
      });
    });
  }
  render() {
    const notEmpty = ali => !!ali && ali.length > 0;
    return (
      <Grid>
        <AlignmentContainer
          alignment={notEmpty(this.state.ref)}
          label="Reference Alignment"
          placeholder="Paste your reference alignment here"
          onChange={this.handleChangeRef}
        />
        { this.state.ref.map((s, i) => (
          <AlignmentContainer
            alignment={notEmpty(this.state.seqs[i])}
            key={i}
            label="Child alignment for ..."
            placeholder={this.state.ref[i].replace(/-/, '')}
            onChange={e => this.handleChangeAli(e, i)}
          />)) }
        <AlignmentContainer<commit_msg>ensure valid & not redund before doing fetch<commit_after>import React from 'react';
import 'whatwg-fetch';
import { Grid, Row, Col,
  FormGroup, ControlLabel, Alert,
  Nav, Navbar, NavItem } from 'react-bootstrap';

const apiURL = '/merge/';

const Main = () => (
  <div>
    <AppNavbar />
    <MainContainer />
  </div>
);

const cleanMsg = msg => msg
  .replace(/^\s+/, '')
  .replace(/\s+$/, '')
  .replace(/ /g, '')
  .split(/\n/)
  .filter(_ => _);

const cleanSeqs = seqs => seqs
  .map((s, i) => [i, s])
  .filter(tup => tup[1] && tup[1].length);

const validAli = (seq, ali) => {
  const refSeqMatches = seq.replace(/-/g, '') === ali[0].replace(/-/g, '');
  const aliIsProper = ali.every(s => s.length === ali[0].length);
  return refSeqMatches && aliIsProper;
};

const validAlis = body => body.seqs.map(s => validAli(body.ref[s[0]], s[1])).every(_ => _);

const listEq = (l1, l2) => l1 && l2 && l1.length === l2.length && l1.every((elem, i) => elem === l2[i]);

class MainContainer extends React.Component {
  constructor(props) {
    super(props);
    this.handleChangeRef = this.handleChangeRef.bind(this);
    this.handleChangeAli = this.handleChangeAli.bind(this);
    this.handleMessage = this.handleMessage.bind(this);
    this.state = { ref: [], seqs: [], value: '', err: '' };
  }
  handleChangeRef(e) {
    const ref = cleanMsg(e.target.value);
    if (!listEq(ref, this.state.ref)) {
      this.setState({ ref, seqs: [], value: '', err: '' });
    }
  }
  handleChangeAli(e, i) {
    const seqs = this.state.seqs.slice(0);
    seqs[i] = cleanMsg(e.target.value);

    if (!listEq(seqs[i], this.state.seqs[i])) {
      this.setState({ seqs, value: '', err: '' });
      const body = { ref: this.state.ref, seqs: cleanSeqs(seqs) };
      if (validAlis(body)) this.handleMessage(body);
    }
  }
  handleMessage(body) {
    fetch(apiURL, {
      method: 'POST',
      body: JSON.stringify(body),
    }).then((response) => {
      response.json().then((json) => {
        this.setState({ value: json.result, err: '' });
      }).catch((err) => {
        this.setState({ err });
      });
    });
  }
  render() {
    const notEmpty = ali => !!ali && ali.length > 0;
    return (
      <Grid>
        <AlignmentContainer
          alignment={notEmpty(this.state.ref)}
          label="Reference Alignment"
          placeholder="Paste your reference alignment here"
          onChange={this.handleChangeRef}
        />
        { this.state.ref.map((s, i) => (
          <AlignmentContainer
            alignment={notEmpty(this.state.seqs[i])}
            key={i}
            label="Child alignment for ..."
            placeholder={this.state.ref[i].replace(/-/, '')}
            onChange={e => this.handleChangeAli(e, i)}
          />)) }
        <AlignmentContainer
{'fraction_non_alphanumeric': 0.19281175536139794, 'fraction_numerical': 0.003971405877680699, 'mean_word_length': 2.5698086463501064, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4348109', 'n_tokens_mistral': 1695, 'n_tokens_neox': 1692, 'n_words': 325}