<commit_before>import PropTypes from "prop-types";
import React, { useCallback, useEffect, useState } from "react";
import { useTransition, animated } from "react-spring";
import styled from "styled-components";

import style from "@agir/front/genericComponents/_variables.scss";

import { useGlobalContext } from "@agir/front/genericComponents/GlobalContext";

import background from "./feedback-form-button.svg";
import closeButton from "./close-btn.svg";

const slideInTransition = {
  from: { opacity: 0, marginBottom: "-3rem" },
  enter: { opacity: 1, marginBottom: "0" },
  leave: { opacity: 0, marginBottom: "-3rem" },
};

const fadeInTransition = {
  from: { opacity: 0 },
  enter: { opacity: 1 },
  leave: { opacity: 0 },
  delay: 200,
};

const Tooltip = styled(animated.p)`
  position: absolute;
  top: -10px;
  right: 0;
  transform: translate(-26px, -100%);
  right: 0;
  width: 175px;
  background-color: ${style.black1000};
  color: white;
  padding: 1rem;
  display: flex;
  flex-flow: column nowrap;
  font-size: 13px;
  line-height: 1.3;

  strong {
    font-size: 14px;
  }

  button {
    position: absolute;
    top: 0;
    right: 0;
    transform: translate(50%, -50%);
    width: 24px;
    height: 24px;
    background-color: transparent;
    border: none;
    background-image: url(${closeButton});
    background-repeat: no-repeat;
    background-position: center center;
    background-size: cover;
    cursor: pointer;
  }

  :after {
    content: "";
    position: absolute;
    top: 100%;
    right: 0;
    margin-left: -4px;
    border-width: 4px;
    border-style: solid;
    border-color: black black transparent transparent;
  }
`;

const Button = styled.a`
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 100%;
  background-color: transparent;
  background-image: url(${background});
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center center;
`;

const Wrapper = styled(animated.div)`
  position: fixed;
  bottom: 1rem;
  right: 1rem;
  width: 53px;
  height: 53px;
  z-index: ${style.zindexFeedbackButton};

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

export const FeedbackButton = (props) => {
  const { isActive, href } = props;
  const [hasTooltip, setHasTooltip] = useState(false);
  const handleCloseTooltip = useCallback(() => {
    setHasTooltip(false);
  }, []);
  const handleOpenTooltip = useCallback(() => {
    setHasTooltip(true);
  }, []);

  const tooltipTransition = useTransition(hasTooltip, null, fadeInTransition);
  const wrapperTransition = useTransition(isActive, null, {
    ...slideInTransition,
    onRest: handleOpenTooltip,
  });

  return wrapperTransition.map(({ item, key, props }) =>
    item ? (
      <Wrapper key={key} style={props}>
        {tooltipTransition.map(({ item, key, props }) =>
          item ? (
            <Tooltip key={key} style={props}>
              Aidez-nous !
              Donnez votre avis sur le nouveau site →
              <button
                title={
                  hasTooltip ? "" : "Donnez votre avis sur le nouveau site"
                }
                aria-label="Cacher"
                onClick={handleCloseTooltip}
              />
            </Tooltip>
          ) : null
        )}
        <Button href={href} aria-label="Je donne mon avis" />
      </Wrapper>
    ) : null
  );
};
FeedbackButton.propTypes = {
  isActive: PropTypes.bool,
  href: PropTypes.string.isRequired,
};
const ConnectedFeedbackButton = (props) => {
  const { routes } = useGlobalContext();
  const href = routes && routes.feedbackForm;

  const [isActive, setIsActive] = useState(false);

  useEffect(() => {
    if (!window.localStorage) {
      return;
    }
    let visitCount = window.localStorage.getItem("AP_vcount");
    visitCount = !isNaN(parseInt(visitCount)) ? parseInt(visitCount) : 0;
    window.localStorage.setItem("AP_vcount", visitCount + 1);
    visitCount > 3 && setIsActive(true);
  }, []);

  return <FeedbackButton {...props} href={href} isActive={isActive} />;
};
export default ConnectedFeedbackButton;
<commit_msg>fix: feedback form link display logic<commit_after>import PropTypes from "prop-types";
import React, { useCallback, useEffect, useState } from "react";
import { useTransition, animated } from "react-spring";
import styled from "styled-components";

import style from "@agir/front/genericComponents/_variables.scss";

import { useGlobalContext } from "@agir/front/genericComponents/GlobalContext";

import background from "./feedback-form-button.svg";
import closeButton from "./close-btn.svg";

const slideInTransition = {
  from: { opacity: 0, marginBottom: "-3rem" },
  enter: { opacity: 1, marginBottom: "0" },
  leave: { opacity: 0, marginBottom: "-3rem" },
};

const fadeInTransition = {
  from: { opacity: 0 },
  enter: { opacity: 1 },
  leave: { opacity: 0 },
  delay: 200,
};

const Tooltip = styled(animated.p)`
  position: absolute;
  top: -10px;
  right: 0;
  transform: translate(-26px, -100%);
  right: 0;
  width: 175px;
  background-color: ${style.black1000};
  color: white;
  padding: 1rem;
  display: flex;
  flex-flow: column nowrap;
  font-size: 13px;
  line-height: 1.3;

  strong {
    font-size: 14px;
  }

  button {
    position: absolute;
    top: 0;
    right: 0;
    transform: translate(50%, -50%);
    width: 24px;
    height: 24px;
    background-color: transparent;
    border: none;
    background-image: url(${closeButton});
    background-repeat: no-repeat;
    background-position: center center;
    background-size: cover;
    cursor: pointer;
  }

  :after {
    content: "";
    position: absolute;
    top: 100%;
    right: 0;
    margin-left: -4px;
    border-width: 4px;
    border-style: solid;
    border-color: black black transparent transparent;
  }
`;

const Button = styled.a`
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 100%;
  background-color: transparent;
  background-image: url(${background});
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center center;
`;

const Wrapper = styled(animated.div)`
  position: fixed;
  bottom: 1rem;
  right: 1rem;
  width: 53px;
  height: 53px;
  z-index: ${style.zindexFeedbackButton};

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

export const FeedbackButton = (props) => {
  const { isActive, shouldPushTooltip, href } = props;

  const [hasTooltip, setHasTooltip] = useState(false);

  const hideTooltip = useCallback(() => {
    setHasTooltip(false);
  }, []);

  const showTooltip = useCallback(() => {
    setHasTooltip(true);
  }, []);

  const pushTooltip = useCallback(() => {
    shouldPushTooltip && showTooltip();
  }, [shouldPushTooltip, showTooltip]);

  const tooltipTransition = useTransition(hasTooltip, null, fadeInTransition);
  const wrapperTransition = useTransition(isActive, null, {
    ...slideInTransition,
    onRest: pushTooltip,
  });

  return wrapperTransition.map(({ item, key, props }) =>
    item ? (
      <Wrapper key={key} style={props}>
        {tooltipTransition.map(({ item, key, props }) =>
          item ? (
            <Tooltip key={key} style={props}>
              Aidez-nous !
              Donnez votre avis sur le nouveau site →
              {shouldPushTooltip ? (
                <button aria-label="Cacher" onClick={hideTooltip} />
              ) : null}
            </Tooltip>
          ) : null
        )}
        <Button
          href={href}
          aria-label="Je donne mon avis"
          onMouseOver={shouldPushTooltip ? undefined : showTooltip}
          onMouseLeave={shouldPushTooltip ? undefined : hideTooltip}
        />
      </Wrapper>
    ) : null
  );
};
FeedbackButton.propTypes = {
  isActive: PropTypes.bool,
  shouldPushTooltip: PropTypes.bool,
  href: PropTypes.string.isRequired,
};
const ConnectedFeedbackButton = (props) => {
  const { routes } = useGlobalContext();
  const href = routes && routes.feedbackForm;

  const [isActive, setIsActive] = useState(false);
  const [shouldPushTooltip, setShouldPushTooltip] = useState(false);

  useEffect(() => {
    if (!window.localStorage) {
      return;
    }
    let visitCount = window.localStorage.getItem("AP_vcount");
    visitCount = !isNaN(parseInt(visitCount)) ? parseInt(visitCount) : 0;
    visitCount += 1;
    visitCount % 20 === 3 && setShouldPushTooltip(true);
    setIsActive(true);
    window.localStorage.setItem("AP_vcount", visitCount);
  }, []);

  return (
    <FeedbackButton
      {...props}
      href={href}
      isActive={isActive}
      shouldPushTooltip={shouldPushTooltip}
    />
  );
};
export default ConnectedFeedbackButton;
<|endoftext|>


<commit_before>(function($) {
  var methodMap = {
    'create': 'POST',
    'update': 'PUT',
    'delete': 'DELETE',
    'read'  : 'GET'
  };

  var getUrl = function(object) {
    if (!(object && object.url)) return null;
    return _.isFunction(object.url) ? object.url() : object.url;
  };

  var urlError = function() {
    throw new Error("A 'url' property or function must be specified");
  };

  Backbone.sync = function(method, model, options) {
    var type = methodMap[method];

    // Default JSON-request options.
    var params = _.extend({
      type:         type,
      dataType:     'json',
      beforeSend: function( xhr ) {
        var token = $('meta[name="csrf-token"]').attr('content');
        if (token) xhr.setRequestHeader('X-CSRF-Token', token);

        model.trigger('sync:start');
      }
    }, options);

    if (!params.url) {
      params.url = getUrl(model) || urlError();
    }

    // Ensure that we have the appropriate request data.
    if (!params.data && model && (method == 'create' || method == 'update')) {
      params.contentType = 'application/json';

      var data = {}

      if(model.paramRoot) {
        data[model.paramRoot] = model.toJSON();
      } else {
        data = model.toJSON();
      }

      params.data = JSON.stringify(data)
    }

    // Don't process data on a non-GET request.
    if (params.type !== 'GET') {
      params.processData = false;
    }

    // Trigger the sync end event
    var complete = options.complete;
    params.complete = function(jqXHR, textStatus) {
      model.trigger('sync:end');
      if (complete) complete(jqXHR, textStatus);
    };

    // Make the request.
    return $.ajax(params);
  }

})(jQuery);
<commit_msg>Allows the X-CSRF-Token to be skipped optionally<commit_after>(function($) {
  var methodMap = {
    'create': 'POST',
    'update': 'PUT',
    'delete': 'DELETE',
    'read'  : 'GET'
  };

  var getUrl = function(object) {
    if (!(object && object.url)) return null;
    return _.isFunction(object.url) ? object.url() : object.url;
  };

  var urlError = function() {
    throw new Error("A 'url' property or function must be specified");
  };

  Backbone.sync = function(method, model, options) {
    var type = methodMap[method];

    // Default JSON-request options.
    var params = _.extend({
      type:         type,
      dataType:     'json',
      beforeSend: function( xhr ) {
        if (!options.noCSRF) {
          var token = $('meta[name="csrf-token"]').attr('content');
          if (token) xhr.setRequestHeader('X-CSRF-Token', token);
        }
        model.trigger('sync:start');
      }
    }, options);

    if (!params.url) {
      params.url = getUrl(model) || urlError();
    }

    // Ensure that we have the appropriate request data.
    if (!params.data && model && (method == 'create' || method == 'update')) {
      params.contentType = 'application/json';

      var data = {}

      if(model.paramRoot) {
        data[model.paramRoot] = model.toJSON();
      } else {
        data = model.toJSON();
      }

      params.data = JSON.stringify(data)
    }

    // Don't process data on a non-GET request.
    if (params.type !== 'GET') {
      params.processData = false;
    }

    // Trigger the sync end event
    var complete = options.complete;
    params.complete = function(jqXHR, textStatus) {
      model.trigger('sync:end');
      if (complete) complete(jqXHR, textStatus);
    };

    // Make the request.
    return $.ajax(params);
  }

})(jQuery);
<|endoftext|>


<commit_before>//by Eamon Nerbonne (from http://home.nerbonne.org/A-vs-An), Apache 2.0 license
var AvsAnSimple = (function () {
	"use strict";
	var dict = "2h.#2.a;i;&1.N;*4.a;e;i;o;/9.a;e;h1.o.i;l1./;n1.o.o;r1.e.s1./;01.8;12.1a;01.0;12.8;9;2.31.7;4.5.6.7.8.9.8a;0a.0;1;2;3;4;5;6;7;8;9;11; .22; .–.31; .42; .–.55; .,.h.k.m.62; .k.72; .–.82; .,.92; .–.8;<2.m1.d;o;=1.=1.E;@;A6;A1;A1.S;i1;r1;o.m1;a1;r1; .n1;d1;a1;l1;u1;c1.i1.a1.n;s1;t1;u1;r1;i1;a1;s.t1;h1;l1;e1;t1;e1.s;B2.h2.a1.i1;r1;a.á;o1.r1.d1. ;C3.a1.i1.s1.s.h4.a2.i1.s1;e.o1.i;l1.á;r1.o1.í;u2.i;r1.r1.a;o1.n1.g1.j;D7.a1.o1.q;i2.n1.a1.s;o1.t;u1.a1.l1.c;á1. ;ò;ù;ư;E7;U1;R.b1;o1;l1;i.m1;p1;e1;z.n1;a1;m.s1;p5.a1.c;e;h;o;r;u1.l1;o.w1;i.F11. ;,;.;/;0;1;2;3;4;5;6;71.0.8;9;Ae;B.C.D.F.I2.L.R.K.L.M.N.P.Q.R.S.T.B;C1;M.D;E2.C;I;F1;r.H;I3.A1;T.R1. ;U;J;L3.C;N;P;M;O1. ;P1;..R2.A1. ;S;S;T1;S.U2.,;.;X;Y1;V.c;f1.o.h;σ;G7.e1.r1.n1.e;h1.a3.e;i;o;i1.a1.n1.g;o2.f1. ;t1.t1. ;r1.i1.a;w1.a1.r1.r;ú;Hs. ;&;,;.2;A.I.1;2;3;5;7;B1;P.C;D;F;G;H1;I.I6;C.G.N.P.S1.D;T.K1.9;L;M1;..N;O2. ;V;P;R1;T.S1.F.T;V;e2.i1.r;r1.r1.n;o2.n6;d.e1.s;g.k.o2;l.r1;i1.f;v.u1.r;I3;I2;*.I.n1;d1;e1;p1;e1;n1;d2;e1;n1;c1;i.ê.s1;l1;a1;n1;d1;s.J1.i1.a1.o;Ly. ;,;.;1;2;3;4;8;A3. ;P;X;B;C;D;E2. ;D;F1;T.G;H1.D.I1.R;L;M;N;P;R;S1;m.T;U1. ;V1;C.W1.T;Z;^;a1.o1.i1.g;o1.c1.h1.a1;b.p;u1.s1.h1;o.ộ;M15. ;&;,;.1;A1;.1;S./;1;2;3;4;5;6;7;8;Ai;B.C.D.F.G.J.L.M.N.P.R.S.T.V.W.X.Y.Z.B1;S1;T.C;D;E3.P1;S.W;n;F;G;H;I4. ;5;6;T1;M.K;L;M;N;O1.U;P;Q;R;S;T1;R.U2. ;V;V;X;b1.u1.m;f;h;o2.D1.e.U1;..p1.3;s1.c;Ny. ;+;.1.E.4;7;8;:;A3.A1;F.I;S1.L;B;C;D;E3.A;H;S1. ;F1;U.G;H;I7.C.D1. ;K.L.N.O.S.K;L;M1;M.N2.R;T;P1.O1.V1./1.B;R2;J.T.S1;W.T1;L1.D.U1.S;V;W2.A;O1.H;X;Y3.C1.L;P;U;a1.s1.a1.n;t1.h;v;²;×;O5;N1;E.l1;v.n2;c1.e.e1.i;o1;p.u1;i.P1.h2.i1.a;o2.b2;i.o.i;Q1.i1.n1.g1.x;Rz. ;&;,;.1;J./;1;4;6;A3. ;.;F1;T.B1;R.C;D;E3. ;S1.P;U;F;G;H1.S;I2.A;C1. ;J;K;L1;P.M5;1.2.3.5.6.N;O2.H;T2;A.O.P;Q;R1;F.S4;,...?.T.T;U4;B.M.N.S.V;X;c;f1;M1...h2.A;B;ò;S11. ;&;,;.4.E;M;O;T1..3.B;D;M;1;3;4;5;6;8;9;A3. ;8;S2;E.I.B;C3.A1. ;R2.A.U.T;D;E6. ;5;C3;A.O.R.I1.F.O;U;F3;&.H.O1.S.G1;D.H3.2;3;L;I2. ;S1.O.K2.I.Y.L3;A2. ;.;I1. ;O.M3;A1. ;I.U1.R.N5.A.C3.A.B.C.E.F.O.O5. ;A1.I;E;S1;U.V;P7;A7;A.C.D.M.N.R.S.E1. ;I4;C.D.N.R.L1;O.O.U.Y.Q1. ;R;S1;W.T9.A1. ;C;D;F;I;L;M;S;V;U7.B.L.M.N.P.R.S.V;W1.R;X1.M;h1.i1.g1.a1.o;p1.i1.o1;n.t2.B;i1.c1.i;T4.a2.i2.g1.a.s1.c;v1.e1.s;e1.a1.m1.p;u1.i2.l;r;à;Um..1.N1..1.C;/1.1;11. .21.1;L1.T;M1.N;N4.C1.L;D2. .P.K;R1. .a;b2;a.i.d;g1.l;i1.g.l2;i.y.m;no. ;a1.n.b;c;d;e1;s.f;g;h;i2.d;n;j;k;l;m;n;o;p;q;r;s;t;u;v;w;p;r3;a.e.u1.k;s3. ;h;t1;r.t4.h;n;r;t;x;z;í;W2.P1.:4.A1.F;I2.B;N1.H.O1.V;R1.F1.C2.N.U.i1.k1.i1.E1.l1.i;X7;a.e.h.i.o.u.y.Y3.e1.t1.h;p;s;[5.A;E;I;a;e;_2._1.i;e;`3.a;e;i;a7; .m1;a1;r1. .n1;d2; .ě.p1;r1;t.r1;t1;í.u1;s1;s1;i1. .v1;u1;t.d3.a1.s1. ;e2.m1. ;r1. ;i2.c1.h1. ;e1.s1.e2.m;r;e8;c1;o1;n1;o1;m1;i1;a.e1;w.l1;i1;t1;e1;i.m1;p1;e1;z.n1;t1;e1;n1;d.s2;a1. .t4;a1; .e1; .i1;m1;a1;r.r1;u1.t.u1.p1. ;w.f3. ;M;y1.i;h9. ;,;.;C;a1.u1.t1;b.e2.i1.r1;a.r1.m1.a1.n;o4.m2.a1; .m;n8; .b.d.e3; .d.y.g.i.k.v.r1.s1. ;u1.r;r1. ;t1;t1;p1;:.i6;b1;n.e1;r.n2;f2;l1;u1;ê.o1;a.s1;t1;a1;l1;a.r1; .s1; .u.k1.u1. ;l3.c1.d;s1. ;v1.a;ma. ;,;R;b1.a.e1.i1.n;f;p;t1.a.u1.l1.t1.i1.c1.a1.m1.p1.i;×;n6. ;V;W;d1; .t;×;o8;c2;h1;o.u1;p.d1;d1;y.f1; .g1;g1;i.no. ;';,;/;a;b;c1.o;d;e2.i;r;f;g;i;l;m;n;o;r;s;t;u;w;y;z;–;r1;i1;g1;e.t1;r1.s;u1;i.r3. ;&;f;s9.,;?;R;f2.e.o.i1.c1.h;l1. ;p2.3;i1. ;r1.g;v3.a.e.i.t2.A;S;uc; ...b2.e;l;f.k2.a;i;m1;a1. .n3;a3; .n5.a;c;n;s;t;r1;y.e2; .i.i8.c2.o1.r1.p;u1.m;d1;i1.o;g1.n;l1.l;m1;o.n;s1.s;v1.o1;c.r5;a.e.i.l.o.s3. ;h;u1.r2;e.p3;a.e.i.t2.m;t;v.w1.a;xb. ;';,;.;8;b;k;l;m1;a.t;y1. ;y1.l;{1.a;|1.a;£1.8;À;Á;Ä;Å;Æ;É;Ò;Ó;Ö;Ü;à;á;æ;è;é1;t3.a;o;u;í;ö;ü1; .Ā;ā;ī;İ;Ō;ō;œ;Ω;α;ε;ω;ϵ;е;–2.e;i;ℓ;";
	var root = {};

	function fill(node, s) {
		var kidCount = parseInt(s, 36),
			offset = kidCount && kidCount.toString(36).length;
		node.article = s[offset] == "." ? "a" : "an";
		s = s.substr(1 + offset);
		for (var i = 0; i < n[2]; i++)
			s = fill(node[s[0]] = {}, s.substr(1));
		return s;
	}
	fill(root, dict);

	return {
		raw: root,
		//Usage example: AvsAnSimple.query("example ")
		//Note that the terminal space indicates this is a complete word - this is sometimes significant, particularly for acronyms!
		//example returns: "an"
		query: function (word) {
			var node = root, article = node.article, sI = 0;
			while (1)
				if (sI >= word.length) return article;
				else if (word[sI] === "(" || word[sI] === "'" || word[sI] === '"') sI++;
				else break;
			while (1) {
				node = node[word[sI]];
				if (!node) break;
				if (node.article) article = node.article;
				if (++sI >= word.length) {
					node = node[" "];
					if (node && node.article) article = node.data;
					break;
				}
			}
			return article;
		}
	};
})();
<commit_msg>Reduce code size.<commit_after>//by Eamon Nerbonne (from http://home.nerbonne.org/A-vs-An), Apache 2.0 license
var AvsAnSimple = (function () {
	"use strict";
	var dict = "2h.#2.a;i;&1.N;*4.a;e;i;o;/9.a;e;h1.o.i;l1./;n1.o.o;r1.e.s1./;01.8;12.1a;01.0;12.8;9;2.31.7;4.5.6.7.8.9.8a;0a.0;1;2;3;4;5;6;7;8;9;11; .22; .–.31; .42; .–.55; .,.h.k.m.62; .k.72; .–.82; .,.92; .–.8;<2.m1.d;o;=1.=1.E;@;A6;A1;A1.S;i1;r1;o.m1;a1;r1; .n1;d1;a1;l1;u1;c1.i1.a1.n;s1;t1;u1;r1;i1;a1;s.t1;h1;l1;e1;t1;e1.s;B2.h2.a1.i1;r1;a.á;o1.r1.d1. ;C3.a1.i1.s1.s.h4.a2.i1.s1;e.o1.i;l1.á;r1.o1.í;u2.i;r1.r1.a;o1.n1.g1.j;D7.a1.o1.q;i2.n1.a1.s;o1.t;u1.a1.l1.c;á1. ;ò;ù;ư;E7;U1;R.b1;o1;l1;i.m1;p1;e1;z.n1;a1;m.s1;p5.a1.c;e;h;o;r;u1.l1;o.w1;i.F11. ;,;.;/;0;1;2;3;4;5;6;71.0.8;9;Ae;B.C.D.F.I2.L.R.K.L.M.N.P.Q.R.S.T.B;C1;M.D;E2.C;I;F1;r.H;I3.A1;T.R1. ;U;J;L3.C;N;P;M;O1. ;P1;..R2.A1. ;S;S;T1;S.U2.,;.;X;Y1;V.c;f1.o.h;σ;G7.e1.r1.n1.e;h1.a3.e;i;o;i1.a1.n1.g;o2.f1. ;t1.t1. ;r1.i1.a;w1.a1.r1.r;ú;Hs. ;&;,;.2;A.I.1;2;3;5;7;B1;P.C;D;F;G;H1;I.I6;C.G.N.P.S1.D;T.K1.9;L;M1;..N;O2. ;V;P;R1;T.S1.F.T;V;e2.i1.r;r1.r1.n;o2.n6;d.e1.s;g.k.o2;l.r1;i1.f;v.u1.r;I3;I2;*.I.n1;d1;e1;p1;e1;n1;d2;e1;n1;c1;i.ê.s1;l1;a1;n1;d1;s.J1.i1.a1.o;Ly. ;,;.;1;2;3;4;8;A3. ;P;X;B;C;D;E2. ;D;F1;T.G;H1.D.I1.R;L;M;N;P;R;S1;m.T;U1. ;V1;C.W1.T;Z;^;a1.o1.i1.g;o1.c1.h1.a1;b.p;u1.s1.h1;o.ộ;M15. ;&;,;.1;A1;.1;S./;1;2;3;4;5;6;7;8;Ai;B.C.D.F.G.J.L.M.N.P.R.S.T.V.W.X.Y.Z.B1;S1;T.C;D;E3.P1;S.W;n;F;G;H;I4. ;5;6;T1;M.K;L;M;N;O1.U;P;Q;R;S;T1;R.U2. ;V;V;X;b1.u1.m;f;h;o2.D1.e.U1;..p1.3;s1.c;Ny. ;+;.1.E.4;7;8;:;A3.A1;F.I;S1.L;B;C;D;E3.A;H;S1. ;F1;U.G;H;I7.C.D1. ;K.L.N.O.S.K;L;M1;M.N2.R;T;P1.O1.V1./1.B;R2;J.T.S1;W.T1;L1.D.U1.S;V;W2.A;O1.H;X;Y3.C1.L;P;U;a1.s1.a1.n;t1.h;v;²;×;O5;N1;E.l1;v.n2;c1.e.e1.i;o1;p.u1;i.P1.h2.i1.a;o2.b2;i.o.i;Q1.i1.n1.g1.x;Rz. ;&;,;.1;J./;1;4;6;A3. ;.;F1;T.B1;R.C;D;E3. ;S1.P;U;F;G;H1.S;I2.A;C1. ;J;K;L1;P.M5;1.2.3.5.6.N;O2.H;T2;A.O.P;Q;R1;F.S4;,...?.T.T;U4;B.M.N.S.V;X;c;f1;M1...h2.A;B;ò;S11. ;&;,;.4.E;M;O;T1..3.B;D;M;1;3;4;5;6;8;9;A3. ;8;S2;E.I.B;C3.A1. ;R2.A.U.T;D;E6. ;5;C3;A.O.R.I1.F.O;U;F3;&.H.O1.S.G1;D.H3.2;3;L;I2. ;S1.O.K2.I.Y.L3;A2. ;.;I1. ;O.M3;A1. ;I.U1.R.N5.A.C3.A.B.C.E.F.O.O5. ;A1.I;E;S1;U.V;P7;A7;A.C.D.M.N.R.S.E1. ;I4;C.D.N.R.L1;O.O.U.Y.Q1. ;R;S1;W.T9.A1. ;C;D;F;I;L;M;S;V;U7.B.L.M.N.P.R.S.V;W1.R;X1.M;h1.i1.g1.a1.o;p1.i1.o1;n.t2.B;i1.c1.i;T4.a2.i2.g1.a.s1.c;v1.e1.s;e1.a1.m1.p;u1.i2.l;r;à;Um..1.N1..1.C;/1.1;11. .21.1;L1.T;M1.N;N4.C1.L;D2. .P.K;R1. .a;b2;a.i.d;g1.l;i1.g.l2;i.y.m;no. ;a1.n.b;c;d;e1;s.f;g;h;i2.d;n;j;k;l;m;n;o;p;q;r;s;t;u;v;w;p;r3;a.e.u1.k;s3. ;h;t1;r.t4.h;n;r;t;x;z;í;W2.P1.:4.A1.F;I2.B;N1.H.O1.V;R1.F1.C2.N.U.i1.k1.i1.E1.l1.i;X7;a.e.h.i.o.u.y.Y3.e1.t1.h;p;s;[5.A;E;I;a;e;_2._1.i;e;`3.a;e;i;a7; .m1;a1;r1. .n1;d2; .ě.p1;r1;t.r1;t1;í.u1;s1;s1;i1. .v1;u1;t.d3.a1.s1. ;e2.m1. ;r1. ;i2.c1.h1. ;e1.s1.e2.m;r;e8;c1;o1;n1;o1;m1;i1;a.e1;w.l1;i1;t1;e1;i.m1;p1;e1;z.n1;t1;e1;n1;d.s2;a1. .t4;a1; .e1; .i1;m1;a1;r.r1;u1.t.u1.p1. ;w.f3. ;M;y1.i;h9. ;,;.;C;a1.u1.t1;b.e2.i1.r1;a.r1.m1.a1.n;o4.m2.a1; .m;n8; .b.d.e3; .d.y.g.i.k.v.r1.s1. ;u1.r;r1. ;t1;t1;p1;:.i6;b1;n.e1;r.n2;f2;l1;u1;ê.o1;a.s1;t1;a1;l1;a.r1; .s1; .u.k1.u1. ;l3.c1.d;s1. ;v1.a;ma. ;,;R;b1.a.e1.i1.n;f;p;t1.a.u1.l1.t1.i1.c1.a1.m1.p1.i;×;n6. ;V;W;d1; .t;×;o8;c2;h1;o.u1;p.d1;d1;y.f1; .g1;g1;i.no. ;';,;/;a;b;c1.o;d;e2.i;r;f;g;i;l;m;n;o;r;s;t;u;w;y;z;–;r1;i1;g1;e.t1;r1.s;u1;i.r3. ;&;f;s9.,;?;R;f2.e.o.i1.c1.h;l1. ;p2.3;i1. ;r1.g;v3.a.e.i.t2.A;S;uc; ...b2.e;l;f.k2.a;i;m1;a1. .n3;a3; .n5.a;c;n;s;t;r1;y.e2; .i.i8.c2.o1.r1.p;u1.m;d1;i1.o;g1.n;l1.l;m1;o.n;s1.s;v1.o1;c.r5;a.e.i.l.o.s3. ;h;u1.r2;e.p3;a.e.i.t2.m;t;v.w1.a;xb. ;';,;.;8;b;k;l;m1;a.t;y1. ;y1.l;{1.a;|1.a;£1.8;À;Á;Ä;Å;Æ;É;Ò;Ó;Ö;Ü;à;á;æ;è;é1;t3.a;o;u;í;ö;ü1; .Ā;ā;ī;İ;Ō;ō;œ;Ω;α;ε;ω;ϵ;е;–2.e;i;ℓ;";
	var root = {};
	var article = 'article';
	function fill(node, s) {
		var kidCount = parseInt(s, 36),
			offset = kidCount && kidCount.toString(36).length;
		node[article] = s[offset] == "." ? "a" : "an";
		s = s.substr(1 + offset);
		for (var i = 0; i < n[2]; i++)
			s = fill(node[s[0]] = {}, s.substr(1));
		return s;
	}
	fill(root, dict);

	return {
		raw: root,
		//Usage example: AvsAnSimple.query("example ")
		//Note that the terminal space indicates this is a complete word - this is sometimes significant, particularly for acronyms!
		//example returns: "an"
		query: function (word) {
			var node = root, result = node[article], sI = 0, c;
			while (1) {
				c = word[sI++];
				if (!c)
					return result;
				if ('"‘’“”$\''.indexOf(c) < 0)
					break;
			}
			while (1) {
				node = node[c];
				if (!node) return result;
				result = node[article] || result;
				c = word[sI++] || " ";
			}
		}
	};
})();
<|endoftext|>


<commit_before>// Copyright 2002-2015, University of Colorado Boulder
/**
 * @fileoverview Rule to check that a require statement assigns to the correct variable name for the string! plugin.
 * @author Sam Reid (PhET Interactive Simulations)
 * @copyright 2015 University of Colorado Boulder
 */

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function( context ) {
  'use strict';

  // Adapted from Stack Overflow, see http://stackoverflow.com/questions/25085306/javascript-space-separated-string-to-camelcase
  function toCamelCase( string ) {
    var out = '';
    string.split( ' ' ).forEach( function( element, index ) {
      out += (index === 0 ? element : element[ 0 ].toUpperCase() + element.slice( 1 ));
    } );
    return out;
  }

  var endsWith = function( string, s ) {
    return string.length >= s.length && string.substring( string.length - s.length ) === s;
  };
  return {

    // Similar to the require-statement-match.js, please visit that file for AST example
    VariableDeclaration: function requireStatementMatch( node ) {

      if ( node.declarations &&
           node.declarations.length > 0 &&
           node.declarations[ 0 ].init &&
           node.declarations[ 0 ].init.arguments &&
           node.declarations[ 0 ].init.arguments.length > 0 ) {
        if ( node.declarations[ 0 ].init &&
             node.declarations[ 0 ].init.callee.name === 'require' ) {
          var varName = node.declarations[ 0 ].id.name;
          var rhs = node.declarations[ 0 ].init.arguments[ 0 ].value;

          if ( rhs.indexOf( 'string!' ) === 0 ) {

            var lastSlash = rhs.lastIndexOf( '/' );
            var key = rhs.substring( lastSlash + 1 );

            // Convert dots and dashes to whitespace
            var withWhitespace = key.replace( /\./g, ' ' ).replace( /\-/g, ' ' );

            // Convert whitespace delimited string to camel case and append string suffix
            var desiredVarName = toCamelCase( withWhitespace ) + 'String';

            if ( varName !== desiredVarName ) {
              context.report( {
                node: node,
                loc: node.loc.start,
                message: 'Mismatched var in require(string!), ' +
                         'key=' + key + ', ' +
                         'var=' + varName + ', ' +
                         'desiredVar=' + desiredVarName
              } );
            }
          }
        }
      }
    }
  };
};

module.exports.schema = [
  // JSON Schema for rule options goes here
];<commit_msg>Fixed a case where dynamic strings weren't being processed properly in string-require-statement-match.js<commit_after>// Copyright 2002-2015, University of Colorado Boulder
/**
 * @fileoverview Rule to check that a require statement assigns to the correct variable name for the string! plugin.
 * @author Sam Reid (PhET Interactive Simulations)
 * @copyright 2015 University of Colorado Boulder
 */

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function( context ) {
  'use strict';

  // Adapted from Stack Overflow, see http://stackoverflow.com/questions/25085306/javascript-space-separated-string-to-camelcase
  function toCamelCase( string ) {
    var out = '';
    string.split( ' ' ).forEach( function( element, index ) {
      out += (index === 0 ? element : element[ 0 ].toUpperCase() + element.slice( 1 ));
    } );
    return out;
  }

  var endsWith = function( string, s ) {
    return string.length >= s.length && string.substring( string.length - s.length ) === s;
  };
  return {

    // Similar to the require-statement-match.js, please visit that file for AST example
    VariableDeclaration: function requireStatementMatch( node ) {

      if ( node.declarations &&
           node.declarations.length > 0 &&
           node.declarations[ 0 ].init &&
           node.declarations[ 0 ].init.arguments &&
           node.declarations[ 0 ].init.arguments.length > 0 ) {
        if ( node.declarations[ 0 ].init &&
             node.declarations[ 0 ].init.callee.name === 'require' ) {
          var varName = node.declarations[ 0 ].id.name;
          var rhs = node.declarations[ 0 ].init.arguments[ 0 ].value;

          if ( rhs && rhs.indexOf( 'string!' ) === 0 ) {

            var lastSlash = rhs.lastIndexOf( '/' );
            var key = rhs.substring( lastSlash + 1 );

            // Convert dots and dashes to whitespace
            var withWhitespace = key.replace( /\./g, ' ' ).replace( /\-/g, ' ' );

            // Convert whitespace delimited string to camel case and append string suffix
            var desiredVarName = toCamelCase( withWhitespace ) + 'String';

            if ( varName !== desiredVarName ) {
              context.report( {
                node: node,
                loc: node.loc.start,
                message: 'Mismatched var in require(string!), ' +
                         'key=' + key + ', ' +
                         'var=' + varName + ', ' +
                         'desiredVar=' + desiredVarName
              } );
            }
          }
        }
      }
    }
  };
};

module.exports.schema = [
  // JSON Schema for rule options goes here
];<|endoftext|>


<commit_before>// https://github.com/michael-ciniawsky/postcss-load-config

module.exports = {
  'plugins': {
    'postcss-import': {},
    'postcss-url': {},
    'postcss-cssnext': {
      features: {
        customProperties: false,
        calc: false,
        autoprefixer: false,
      }
    },
    'postcss-reporter': {},
    // to edit target browsers: use 'browserslist' field in package.json
    'autoprefixer': {},
    'cssnano': {
      zindex: false
    }
  }
}
<commit_msg>:bug: Removed trailing comma in postcssrc file<commit_after>// https://github.com/michael-ciniawsky/postcss-load-config

module.exports = {
  'plugins': {
    'postcss-import': {},
    'postcss-url': {},
    'postcss-cssnext': {
      features: {
        customProperties: false,
        calc: false,
        autoprefixer: false
      }
    },
    'postcss-reporter': {},
    // to edit target browsers: use 'browserslist' field in package.json
    'autoprefixer': {},
    'cssnano': {
      zindex: false
    }
  }
}
<|endoftext|>


<commit_before>/* global module, __dirname */
'use strict'

const pkg = require('./package.json')
const webpack = require('webpack')
const url = require('url')
const reject = require('lodash/reject')
const endsWith = require('lodash/endsWith')

const CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin
const DefinePlugin = webpack.DefinePlugin
const HotModuleReplacementPlugin = webpack.HotModuleReplacementPlugin
const LoaderOptionsPlugin = webpack.LoaderOptionsPlugin
const NormalModuleReplacementPlugin = webpack.NormalModuleReplacementPlugin
const NamedModulesPlugin = webpack.NamedModulesPlugin
const UglifyJsPlugin = webpack.optimize.UglifyJsPlugin
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlPlugin = require('./scripts/webpack/html-plugin')
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin')

const isProduction = (process.env.NODE_ENV === 'production')
const isDevelopment = (process.env.NODE_ENV === 'development')
const isTest = (process.env.NODE_ENV === 'test')

let style = 'style-loader'
let css = 'css-loader'
let sass = 'sass-loader'
let cssModules = { loader: css, query: { modules: true, localIdentName: '[path][name]·[local]·[hash:base64:5]' } }

const outputFolder = __dirname + '/build/'
const urlLoaderLimit = 10000
let publicPath = '/'
if (isProduction) {
	// We use "homepage" field to infer "public path" at which the app is served.
	// Webpack needs to know it to put the right

						<link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/nhhpgddphdimipafjfiggjnbbmcoklld">

						${isProduction ?
							''
							: ''}

						${context.css ?
							`<link rel="stylesheet" href="${publicPath}${context.css}">`
							: ''}

						${Object.keys(entries)
							.map(k => `<script src="${publicPath}${context[k]}"></script>`)
							.join('\n')}

					`,
				}
			},
			isDev: isDevelopment,
		}),

		// Ignore the "full" schema in js-yaml's module, because it brings in esprima
		// to support the !!js/function type. We don't use and have no need for it, so
		// tell webpack to ignore it.
		new NormalModuleReplacementPlugin(/schema\/default_full$/, result => {
			result.request = result.request.replace('default_full', 'default_safe')
		}),

		// DefinePlugin makes some variables available to the code.
		new DefinePlugin({
			VERSION: JSON.stringify(pkg.version),
			DEVELOPMENT: isDevelopment,
			PRODUCTION: isProduction,
			TESTING: isTest,
			// APP_BASE is used in react-router, to set its base appropriately
			// across both local dev and gh-pages.
			APP_BASE: JSON.stringify(publicPath),
			'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
		}),

		// Extract the common libraries into a single file so that the chunks
		// don't need to individually bundle them.
		new CommonsChunkPlugin({
			names: [
				'react',
				'common',
				'yaml',
				'cm',
				'html',
				'idb',
				'hanson',
				'bfr',
				'manifest',
			],
			filename: '[name].[hash].js',
			minChunks: Infinity,
		}),

		// Watcher doesn't work well if you mistype casing in a path so we use
		// a plugin that prints an error when you attempt to do this.
		new CaseSensitivePathsPlugin(),

		new LoaderOptionsPlugin({
			options: {
				worker: {
					output: {
						filename: '[hash].worker.js',
						chunkFilename: '[id].[hash].worker.js',
					},
				},
			},
		}),

		new NamedModulesPlugin(),
	],

	module: {
		rules: [
			{
				test: /\.js$/,
				exclude: /node_modules\/(?!p-.*\/).*/,
				use: [ { loader: 'babel-loader', options: { cacheDirectory: true } } ],
			},
			{
				test: /\.worker.js$/,
				exclude: /node_modules/,
				use: [ 'worker-loader', { loader: 'babel-loader', options: { cacheDirectory: true } } ],
			},
			{
				test: /\.json$/,
				use: [ 'json-loader' ],
			},
			{
				test: /\.otf|eot|ttf|woff2?$/,
				use: [ { loader: 'url-loader', options: { limit: urlLoaderLimit } } ],
			},
			{
				test: /\.jpe?g|png|gif$/,
				use: [ { loader: 'url-loader', options: { limit: urlLoaderLimit } } ],
			},

			{ test: /\.css$/, use: [ style, css ] },
			{ test: /\.scss$/, use: [ style, css, sass ] },
			{ test: /\.module.css$/, use: [ style, cssModules ] },
			{ test: /\.module.scss$/, use: [ style, cssModules, sass ] },
		],
	},
}

if (isDevelopment) {
	// add dev server and hotloading clientside code
	config.entry.main.unshift(
		// 'react-hot-loader/patch',
		'webpack-dev-server/client?/',
		'webpack/hot/only-dev-server'
	)

	// add dev plugins
	config.plugins.push(new HotModuleReplacementPlugin())
}

else if (isProduction) {
	config.stats.children = false

	// minify in production
	config.plugins = config.plugins.concat([
		new UglifyJsPlugin({
			sourceMap: true,
			compress: {
				warnings: false,
				pure_getters: true, // eslint-disable-line camelcase
				screw_ie8: true, // eslint-disable-line camelcase
				unsafe: true,
			},
			mangle: {
				screw_ie8: true, // eslint-disable-line camelcase
			},
			output: {
				comments: false,
				screw_ie8: true, // eslint-disable-line camelcase
			},
		}),
		new ExtractTextPlugin({
			filename: cssFilename,
			allChunks: true,
		}),
		new LoaderOptionsPlugin({
			minimize: true,
		}),
		new DuplicatePackageCheckerPlugin(),
	])

	// remove css plugins
	const endsInCss = rule => endsWith(rule.test.toString(), 'css$/')
	config.module.rules = reject(config.module.rules, endsInCss)
	config.module.rules = config.module.rules.concat([
		{ test: /\.css$/, loader: ExtractTextPlugin.extract({ fallbackLoader: style, loader: [ css ] }) },
		{ test: /\.scss$/, loader: ExtractTextPlugin.extract({ fallbackLoader: style, loader: [ css, sass ] }) },
		{ test: /\.module.css$/, loader: ExtractTextPlugin.extract({ fallbackLoader: style, loader: [ cssModules ] }) },
		{ test: /\.module.scss$/, loader: ExtractTextPlugin.extract({ fallbackLoader: style, loader: [ cssModules, sass ] }) },
	])
}

module.exports = config
<commit_msg>remove p-* exclusion from the main babel-loader<commit_after>/* global module, __dirname */
'use strict'

const pkg = require('./package.json')
const webpack = require('webpack')
const url = require('url')
const reject = require('lodash/reject')
const endsWith = require('lodash/endsWith')

const CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin
const DefinePlugin = webpack.DefinePlugin
const HotModuleReplacementPlugin = webpack.HotModuleReplacementPlugin
const LoaderOptionsPlugin = webpack.LoaderOptionsPlugin
const NormalModuleReplacementPlugin = webpack.NormalModuleReplacementPlugin
const NamedModulesPlugin = webpack.NamedModulesPlugin
const UglifyJsPlugin = webpack.optimize.UglifyJsPlugin
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlPlugin = require('./scripts/webpack/html-plugin')
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin')

const isProduction = (process.env.NODE_ENV === 'production')
const isDevelopment = (process.env.NODE_ENV === 'development')
const isTest = (process.env.NODE_ENV === 'test')

let style = 'style-loader'
let css = 'css-loader'
let sass = 'sass-loader'
let cssModules = { loader: css, query: { modules: true, localIdentName: '[path][name]·[local]·[hash:base64:5]' } }

const outputFolder = __dirname + '/build/'
const urlLoaderLimit = 10000
let publicPath = '/'
if (isProduction) {
	// We use "homepage" field to infer "public path" at which the app is served.
	// Webpack needs to know it to put the right

						<link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/nhhpgddphdimipafjfiggjnbbmcoklld">

						${isProduction ?
							''
							: ''}

						${context.css ?
							`<link rel="stylesheet" href="${publicPath}${context.css}">`
							: ''}

						${Object.keys(entries)
							.map(k => `<script src="${publicPath}${context[k]}"></script>`)
							.join('\n')}

					`,
				}
			},
			isDev: isDevelopment,
		}),

		// Ignore the "full" schema in js-yaml's module, because it brings in esprima
		// to support the !!js/function type. We don't use and have no need for it, so
		// tell webpack to ignore it.
		new NormalModuleReplacementPlugin(/schema\/default_full$/, result => {
			result.request = result.request.replace('default_full', 'default_safe')
		}),

		// DefinePlugin makes some variables available to the code.
		new DefinePlugin({
			VERSION: JSON.stringify(pkg.version),
			DEVELOPMENT: isDevelopment,
			PRODUCTION: isProduction,
			TESTING: isTest,
			// APP_BASE is used in react-router, to set its base appropriately
			// across both local dev and gh-pages.
			APP_BASE: JSON.stringify(publicPath),
			'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
		}),

		// Extract the common libraries into a single file so that the chunks
		// don't need to individually bundle them.
		new CommonsChunkPlugin({
			names: [
				'react',
				'common',
				'yaml',
				'cm',
				'html',
				'idb',
				'hanson',
				'bfr',
				'manifest',
			],
			filename: '[name].[hash].js',
			minChunks: Infinity,
		}),

		// Watcher doesn't work well if you mistype casing in a path so we use
		// a plugin that prints an error when you attempt to do this.
		new CaseSensitivePathsPlugin(),

		new LoaderOptionsPlugin({
			options: {
				worker: {
					output: {
						filename: '[hash].worker.js',
						chunkFilename: '[id].[hash].worker.js',
					},
				},
			},
		}),

		new NamedModulesPlugin(),
	],

	module: {
		rules: [
			{
				test: /\.js$/,
				exclude: /node_modules/,
				use: [ { loader: 'babel-loader', options: { cacheDirectory: true } } ],
			},
			{
				test: /\.js$/,
				include: /node_modules[/]p-.*[/].*[.]js$/,
				use: [ { loader: 'babel-loader', options: { plugins: [ 'transform-es2015-modules-commonjs' ], cacheDirectory: true } } ],
			},
			{
				test: /\.worker.js$/,
				exclude: /node_modules/,
				use: [ 'worker-loader', { loader: 'babel-loader', options: { cacheDirectory: true } } ],
			},
			{
				test: /\.json$/,
				use: [ 'json-loader' ],
			},
			{
				test: /\.otf|eot|ttf|woff2?$/,
				use: [ { loader: 'url-loader', options: { limit: urlLoaderLimit } } ],
			},
			{
				test: /\.jpe?g|png|gif$/,
				use: [ { loader: 'url-loader', options: { limit: urlLoaderLimit } } ],
			},

			{ test: /\.css$/, use: [ style, css ] },
			{ test: /\.scss$/, use: [ style, css, sass ] },
			{ test: /\.module.css$/, use: [ style, cssModules ] },
			{ test: /\.module.scss$/, use: [ style, cssModules, sass ] },
		],
	},
}

if (isDevelopment) {
	// add dev server and hotloading clientside code
	config.entry.main.unshift(
		// 'react-hot-loader/patch',
		'webpack-dev-server/client?/',
		'webpack/hot/only-dev-server'
	)

	// add dev plugins
	config.plugins.push(new HotModuleReplacementPlugin())
}

else if (isProduction) {
	config.stats.children = false

	// minify in production
	config.plugins = config.plugins.concat([
		new UglifyJsPlugin({
			sourceMap: true,
			compress: {
				warnings: false,
				pure_getters: true, // eslint-disable-line camelcase
				screw_ie8: true, // eslint-disable-line camelcase
				unsafe: true,
			},
			mangle: {
				screw_ie8: true, // eslint-disable-line camelcase
			},
			output: {
				comments: false,
				screw_ie8: true, // eslint-disable-line camelcase
			},
		}),
		new ExtractTextPlugin({
			filename: cssFilename,
			allChunks: true,
		}),
		new LoaderOptionsPlugin({
			minimize: true,
		}),
		new DuplicatePackageCheckerPlugin(),
	])

	// remove css plugins
	const endsInCss = rule => endsWith(rule.test.toString(), 'css$/')
	config.module.rules = reject(config.module.rules, endsInCss)
	config.module.rules = config.module.rules.concat([
		{ test: /\.css$/, loader: ExtractTextPlugin.extract({ fallbackLoader: style, loader: [ css ] }) },
		{ test: /\.scss$/, loader: ExtractTextPlugin.extract({ fallbackLoader: style, loader: [ css, sass ] }) },
		{ test: /\.module.css$/, loader: ExtractTextPlugin.extract({ fallbackLoader: style, loader: [ cssModules ] }) },
		{ test: /\.module.scss$/, loader: ExtractTextPlugin.extract({ fallbackLoader: style, loader: [ cssModules, sass ] }) },
	])
}

module.exports = config
<|endoftext|>


<commit_before>/* global module, __dirname */
'use strict'

const pkg = require('./package.json')
const webpack = require('webpack')
const path = require('path')
const url = require('url')

const CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin
const DedupePlugin = webpack.optimize.DedupePlugin
const DefinePlugin = webpack.DefinePlugin
const HotModuleReplacementPlugin = webpack.HotModuleReplacementPlugin
const NormalModuleReplacementPlugin = webpack.NormalModuleReplacementPlugin
const OccurenceOrderPlugin = webpack.optimize.OccurenceOrderPlugin
const UglifyJsPlugin = webpack.optimize.UglifyJsPlugin
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlPlugin = require('./scripts/webpack/html-plugin')
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')

const isProduction = (process.env.NODE_ENV === 'production')
const isDevelopment = (process.env.NODE_ENV === 'development')
const isTest = (process.env.NODE_ENV === 'test')

const outputFolder = 'build/'
const urlLoaderLimit = 10000
let publicPath = '/'
if (isProduction) {
	// We use "homepage" field to infer "public path" at which the app is served.
	// Webpack needs to know it to put the right

						${context.css ? `<link rel="stylesheet" href="${publicPath}${context.css}">` : ''}

					`,
				}
			},
			isDev: isDevelopment,
		}),

		// Ignore the "full" schema in js-yaml's module, because it brings in esprima
		// to support the !!js/function type. We don't use and have no need for it, so
		// tell webpack to ignore it.
		new NormalModuleReplacementPlugin(/schema\/default_full$/, result => {
			result.request = result.request.replace('default_full', 'default_safe')
		}),

		// DefinePlugin makes some variables available to the code.
		new DefinePlugin({
			VERSION: JSON.stringify(pkg.version),
			DEVELOPMENT: isDevelopment,
			PRODUCTION: isProduction,
			TESTING: isTest,
			// APP_BASE is used in react-router, to set its base appropriately
			// across both local dev and gh-pages.
			APP_BASE: JSON.stringify(publicPath),
			'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
		}),

		// Extract the common libraries into a single file so that the chunks
		// don't need to individually bundle them.
		new CommonsChunkPlugin({
			names: ['react', 'common'],
			filename: '[name].[hash].js',
			minChunks: Infinity,
		}),

		// Watcher doesn't work well if you mistype casing in a path so we use
		// a plugin that prints an error when you attempt to do this.
		new CaseSensitivePathsPlugin(),
	],

	module: {
		loaders: [
			{
				test: /\.js$/,
				// allow babel to run on lodash-es
				exclude: /node_modules/,
				loaders: ['babel-loader?cacheDirectory'],
			},
			{
				test: /\.worker.js$/,
				// allow babel to run on lodash-es
				exclude: /node_modules/,
				loaders: ['worker-loader', 'babel-loader?cacheDirectory'],
			},
			{
				test: /\.json$/,
				loaders: ['json-loader'],
			},
			{
				test: /\.(otf|eot|ttf|woff2?)$/,
				loader: 'url-loader',
				query: {limit: urlLoaderLimit},
			},
			{
				test: /\.(jpe?g|png|gif)$/,
				loader: 'url-loader',
				query: {limit: urlLoaderLimit},
			},
		],
	},

	worker: {
		output: {
			filename: '[hash].worker.js',
			chunkFilename: '[id].[hash].worker.js',
		},
	},
}

// dev specific stuff
if (isDevelopment) {
	// debugging option
	config.devtool = 'eval'

	// add dev server and hotloading clientside code
	config.entry.main.unshift(
		// 'react-hot-loader/patch',
		'webpack-dev-server/client?/',
		'webpack/hot/only-dev-server'
	)

	config.devServer.port = config.port
	config.devServer.host = config.hostname

	// add dev plugins
	config.plugins.push(new HotModuleReplacementPlugin())

	// Add style loaders
	config.module.loaders.push({test: /\.css$/, loaders: ['style', 'css']})
	config.module.loaders.push({test: /\.scss$/, loaders: ['style', 'css', 'sass']})

	let identName = '[path][name]·[local]·[hash:base64:5]'
	config.module.loaders.push({test: /\.module.css$/, loaders: ['style', `css?modules&localIdentName=${identName}`]})
	config.module.loaders.push({test: /\.module.scss$/, loaders: ['style', `css?modules&localIdentName=${identName}', 'sass`]})
}

else if (isTest) {
	config.module.loaders.push({test: /\.css$/, loader: 'style!css'})
	config.module.loaders.push({test: /\.module.css$/, loader: 'style!css?modules'})
	config.module.loaders.push({test: /\.scss$/, loader: 'style!css!sass'})
	config.module.loaders.push({test: /\.module.scss$/, loader: 'style!css?modules!sass'})
}

// production
else if (isProduction) {
	config.devtool = 'source-map'
	config.stats.children = false

	// minify in production
	let extractor = new ExtractTextPlugin(config.output.cssFilename, {allChunks: true})
	config.plugins = config.plugins.concat([
		new DedupePlugin(),
		new OccurenceOrderPlugin(true),
		new UglifyJsPlugin({
			compress: {
				warnings: false,
				pure_getters: true, // eslint-disable-line camelcase
				screw_ie8: true, // eslint-disable-line camelcase
				unsafe: true,
			},
			mangle: {
				screw_ie8: true, // eslint-disable-line camelcase
			},
			output: {
				comments: false,
				screw_ie8: true, // eslint-disable-line camelcase
			},
		}),
		extractor,
	])

	config.module.loaders.push({
		test: /\.css$/,
		loader: extractor.extract('style', ['css']),
	})
	config.module.loaders.push({
		test: /\.scss$/,
		loader: extractor.extract('style', ['css', 'sass']),
	})

	config.module.loaders.push({
		test: /\.module.css$/,
		loader: extractor.extract('style', ['css?modules']),
	})
	config.module.loaders.push({
		test: /\.module.scss$/,
		loader: extractor.extract('style', ['css?modules', 'sass']),
	})
}

else {
	throw new Error('Unknown environment! Not development, production, nor test!')
}

module.exports = config
<commit_msg>edit webpack alias for new structure<commit_after>/* global module, __dirname */
'use strict'

const pkg = require('./package.json')
const webpack = require('webpack')
const path = require('path')
const url = require('url')

const CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin
const DedupePlugin = webpack.optimize.DedupePlugin
const DefinePlugin = webpack.DefinePlugin
const HotModuleReplacementPlugin = webpack.HotModuleReplacementPlugin
const NormalModuleReplacementPlugin = webpack.NormalModuleReplacementPlugin
const OccurenceOrderPlugin = webpack.optimize.OccurenceOrderPlugin
const UglifyJsPlugin = webpack.optimize.UglifyJsPlugin
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlPlugin = require('./scripts/webpack/html-plugin')
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')

const isProduction = (process.env.NODE_ENV === 'production')
const isDevelopment = (process.env.NODE_ENV === 'development')
const isTest = (process.env.NODE_ENV === 'test')

const outputFolder = 'build/'
const urlLoaderLimit = 10000
let publicPath = '/'
if (isProduction) {
	// We use "homepage" field to infer "public path" at which the app is served.
	// Webpack needs to know it to put the right

						${context.css ? `<link rel="stylesheet" href="${publicPath}${context.css}">` : ''}

					`,
				}
			},
			isDev: isDevelopment,
		}),

		// Ignore the "full" schema in js-yaml's module, because it brings in esprima
		// to support the !!js/function type. We don't use and have no need for it, so
		// tell webpack to ignore it.
		new NormalModuleReplacementPlugin(/schema\/default_full$/, result => {
			result.request = result.request.replace('default_full', 'default_safe')
		}),

		// DefinePlugin makes some variables available to the code.
		new DefinePlugin({
			VERSION: JSON.stringify(pkg.version),
			DEVELOPMENT: isDevelopment,
			PRODUCTION: isProduction,
			TESTING: isTest,
			// APP_BASE is used in react-router, to set its base appropriately
			// across both local dev and gh-pages.
			APP_BASE: JSON.stringify(publicPath),
			'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
		}),

		// Extract the common libraries into a single file so that the chunks
		// don't need to individually bundle them.
		new CommonsChunkPlugin({
			names: ['react', 'common'],
			filename: '[name].[hash].js',
			minChunks: Infinity,
		}),

		// Watcher doesn't work well if you mistype casing in a path so we use
		// a plugin that prints an error when you attempt to do this.
		new CaseSensitivePathsPlugin(),
	],

	module: {
		loaders: [
			{
				test: /\.js$/,
				// allow babel to run on lodash-es
				exclude: /node_modules/,
				loaders: ['babel-loader?cacheDirectory'],
			},
			{
				test: /\.worker.js$/,
				// allow babel to run on lodash-es
				exclude: /node_modules/,
				loaders: ['worker-loader', 'babel-loader?cacheDirectory'],
			},
			{
				test: /\.json$/,
				loaders: ['json-loader'],
			},
			{
				test: /\.(otf|eot|ttf|woff2?)$/,
				loader: 'url-loader',
				query: {limit: urlLoaderLimit},
			},
			{
				test: /\.(jpe?g|png|gif)$/,
				loader: 'url-loader',
				query: {limit: urlLoaderLimit},
			},
		],
	},

	worker: {
		output: {
			filename: '[hash].worker.js',
			chunkFilename: '[id].[hash].worker.js',
		},
	},
}

// dev specific stuff
if (isDevelopment) {
	// debugging option
	config.devtool = 'eval'

	// add dev server and hotloading clientside code
	config.entry.main.unshift(
		// 'react-hot-loader/patch',
		'webpack-dev-server/client?/',
		'webpack/hot/only-dev-server'
	)

	config.devServer.port = config.port
	config.devServer.host = config.hostname

	// add dev plugins
	config.plugins.push(new HotModuleReplacementPlugin())

	// Add style loaders
	config.module.loaders.push({test: /\.css$/, loaders: ['style', 'css']})
	config.module.loaders.push({test: /\.scss$/, loaders: ['style', 'css', 'sass']})

	let identName = '[path][name]·[local]·[hash:base64:5]'
	config.module.loaders.push({test: /\.module.css$/, loaders: ['style', `css?modules&localIdentName=${identName}`]})
	config.module.loaders.push({test: /\.module.scss$/, loaders: ['style', `css?modules&localIdentName=${identName}', 'sass`]})
}

else if (isTest) {
	config.module.loaders.push({test: /\.css$/, loader: 'style!css'})
	config.module.loaders.push({test: /\.module.css$/, loader: 'style!css?modules'})
	config.module.loaders.push({test: /\.scss$/, loader: 'style!css!sass'})
	config.module.loaders.push({test: /\.module.scss$/, loader: 'style!css?modules!sass'})
}

// production
else if (isProduction) {
	config.devtool = 'source-map'
	config.stats.children = false

	// minify in production
	let extractor = new ExtractTextPlugin(config.output.cssFilename, {allChunks: true})
	config.plugins = config.plugins.concat([
		new DedupePlugin(),
		new OccurenceOrderPlugin(true),
		new UglifyJsPlugin({
			compress: {
				warnings: false,
				pure_getters: true, // eslint-disable-line camelcase
				screw_ie8: true, // eslint-disable-line camelcase
				unsafe: true,
			},
			mangle: {
				screw_ie8: true, // eslint-disable-line camelcase
			},
			output: {
				comments: false,
				screw_ie8: true, // eslint-disable-line camelcase
			},
		}),
		extractor,
	])

	config.module.loaders.push({
		test: /\.css$/,
		loader: extractor.extract('style', ['css']),
	})
	config.module.loaders.push({
		test: /\.scss$/,
		loader: extractor.extract('style', ['css', 'sass']),
	})

	config.module.loaders.push({
		test: /\.module.css$/,
		loader: extractor.extract('style', ['css?modules']),
	})
	config.module.loaders.push({
		test: /\.module.scss$/,
		loader: extractor.extract('style', ['css?modules', 'sass']),
	})
}

else {
	throw new Error('Unknown environment! Not development, production, nor test!')
}

module.exports = config
<|endoftext|>


<commit_before>var path = require('path');
var HtmlWebpackPlugin = require('../..');
var webpackMajorVersion = require('webpack/package.json').version.split('.')[0];
module.exports = {
  context: __dirname,
  entry: './example.js',
  output: {
    path: path.join(__dirname, 'dist/webpack-' + webpackMajorVersion),
    publicPath: '',
    filename: 'bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      // NOTE if you pass plain object it will be passed as is. no default values there, so be aware!
      // for implementation detail, please see index.js and search for "userOptions" variable
      templateParameters: (compilation, assets, assetTags, options) => {
        return {
          compilation,
          webpackConfig: compilation.options,
          htmlWebpackPlugin: {
            tags: assetTags,
            files: assets,
            options
          },
          'foo': 'bar'
        };
      },
      template: 'index.ejs'
    })
  ]
};
<commit_msg>Update example to account for object merging<commit_after>var path = require('path');
var HtmlWebpackPlugin = require('../..');
var webpackMajorVersion = require('webpack/package.json').version.split('.')[0];
module.exports = {
  context: __dirname,
  entry: './example.js',
  output: {
    path: path.join(__dirname, 'dist/webpack-' + webpackMajorVersion),
    publicPath: '',
    filename: 'bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      // If you pass a plain object, it will be merged with the default values
      // (New in version 4)
      templateParameters: {
        'foo': 'bar'
      },
      // Or if you want full control, pass a function
      // templateParameters: (compilation, assets, assetTags, options) => {
      //   return {
      //     compilation,
      //     webpackConfig: compilation.options,
      //     htmlWebpackPlugin: {
      //       tags: assetTags,
      //       files: assets,
      //       options
      //     },
      //     'foo': 'bar'
      //   };
      // },
      template: 'index.ejs'
    })
  ]
};
<|endoftext|>


<commit_before>/* See license.txt for terms of usage */

define([
    "firebug/lib/trace",
    "firebug/lib/object",
    "firebug/lib/domplate",
    "firebug/lib/locale",
    "firebug/lib/dom",
    "firebug/lib/css",
    "firebug/lib/events",
    "firebug/css/selectorModule",
    "firebug/css/selectorEditor"
],
function(FBTrace, Obj, Domplate, Locale, Dom, Css, Events, CSSSelectorsModule, SelectorEditor) {

with (Domplate) {

// ********************************************************************************************* //
// CSS Computed panel (HTML side panel)

function CSSSelectorsPanel() {}

CSSSelectorsPanel.prototype = Obj.extend(Firebug.Panel,
{
    template: domplate(
    {
        selectorsTag:
            DIV({"class": "selectorTrials a11yCSSView", role: "list", "aria-label":
                Locale.$STR("aria.labels.Elements")},
                TAG("$selectorEditorRow"),
                DIV({"class": "elementsGroups"},
                    FOR("group", "$groups",
                        TAG("$elementsGroupTag", {group: "$group", windows: "$windows"})
                    )
                )),

        selectorEditorRow:
            DIV({"class": "selectorEditorContainer editorContainer a11yFocusNoTab",
                role: "button", "tabindex" : "0",
                "aria-label": Locale.$STR("a11y.labels.press enter to add new selector"),
                onclick: "$onClickEditor"},
                Locale.$STR("css.selector.TryASelector")
            ),

        elementsGroupTag:
            DIV({"class": "elementsGroup foldableGroup", $opened: "$group.opened",
                role: "list", _repObject: "$group"},
                H1({"class": "cssElementsHeader groupHeader focusRow", role: "listitem"},
                    DIV({"class": "twisty", role: "presentation"}),
                    SPAN({"class": "cssElementsLabel groupLabel"}, "$group.selector")
                ),
                TAG("$elementsTag", {elements: "$windows,$group.selector|getElements"})
            ),

        elementsTag:
            TABLE({"class": "cssElementsTable groupContent", role: "list"},
                TBODY({role: "presentation"},
                    FOR("element", "$elements",
                        TR({"class": "focusRow cssElementsRow cssElements",
                                role: "listitem", _repObject: "$element"},
                            TD({"class": "cssElement", role: "presentation"},
                                TAG("$element|getElementTag", {object: "$element"})
                            )
                        )
                    )
                )
            ),

        getElementTag: function(value)
        {
            var rep = Firebug.getRep(value);
            var tag = rep.shortTag ? rep.shortTag : rep.tag;
            return tag;
        },

        getElements: function(windows, selector)
        {
            return CSSSelectorsModule.matchElements(windows, selector);
        },

        onClickEditor: function(event)
        {
            var target = event.currentTarget;
            var panel = Firebug.getElementPanel(target);
            Firebug.Editor.startEditing(target, "");
        }
    }),

    getEditor: function(target, value)
    {
        if (!this.editor)
            this.editor = new CSSSelectorsPanelEditor(this.document);

        return this.editor;
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Extends Panel

    name: "selectors",
    parentPanel: "stylesheet",
    order: 0,

    initialize: function()
    {
        this.groups = [];

        Firebug.Panel.initialize.apply(this, arguments);
    },

    destroy: function(state)
    {
        Firebug.Panel.destroyNode.apply(this, arguments);
    },

    initializeNode: function(oldPanelNode)
    {
        Firebug.Panel.initializeNode.apply(this, arguments);
    },

    destroyNode: function()
    {
        Firebug.Panel.destroyNode.apply(this, arguments);
    },

    supportsObject: function(object)
    {
        return 0;
    },

    show: function(state)
    {
        this.refresh();
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Groups

    addGroup: function(selector)
    {
        var group = {
            selector: selector,
            opened: true
        }
        this.groups.push(group);

        // Append element group to display
        var elementsGroups = this.panelNode.getElementsByClassName("elementsGroups")[0];
        var action = elementsGroups.getElementsByClassName("noSelection")[0] ?
            "replace" : "append";
        var elementsGroup = this.template.elementsGroupTag[action](
            {group: group, windows: this.context.windows}, elementsGroups);
    },

    refresh: function()
    {
        var parentNode = this.template.selectorsTag.replace(
                {groups: this.groups, windows: this.context.windows}, this.panelNode);

        if (this.groups.length == 0)
        {
            var elementsGroups = parentNode.getElementsByClassName("elementsGroups")[0];
            WarningTemplate.noSelectionTag.replace({}, elementsGroups);
        }
    }
});

function CSSSelectorsPanelEditor(doc)
{
    this.box = this.tag.replace({}, doc, this);
    this.input = this.box;

    Firebug.InlineEditor.prototype.initialize.call(this);
    this.tabNavigation = false;
    this.fixedWidth = true;
}

CSSSelectorsPanelEditor.prototype = domplate(SelectorEditor.prototype,
{
    tag:
        INPUT({"class": "fixedWidthEditor a11yFocusNoTab",
            type: "text",
            title: Locale.$STR("Selector"),
            oninput: "$onInput",
            onkeypress: "$onKeyPress"}
        ),

    endEditing: function(target, value, cancel)
    {
        if (cancel || value == "")
            return;

        if (this.isValidSelector(value))
            this.panel.addGroup(value);
    },

    isValidSelector: function(value)
    {
        try {
            this.panel.panelNode.querySelector(value);
            return true;
        }
        catch (e)
        {
            return false;
        }
    }
});

//********************************************************************************************* //

var WarningTemplate = domplate(Firebug.Rep,
{
    noSelectionTag:
        DIV({"class": "selectorWarning noSelection"},
            SPAN(Locale.$STR("css.selector.noSelection"))
        )
});

//********************************************************************************************* //
//Registration

Firebug.registerPanel(CSSSelectorsPanel);

return CSSSelectorsPanel;

//********************************************************************************************* //
}});
<commit_msg>Display an info message for a group in case the selector doesn't match any elements<commit_after>/* See license.txt for terms of usage */

define([
    "firebug/lib/trace",
    "firebug/lib/object",
    "firebug/lib/domplate",
    "firebug/lib/locale",
    "firebug/lib/dom",
    "firebug/lib/css",
    "firebug/lib/events",
    "firebug/css/selectorModule",
    "firebug/css/selectorEditor"
],
function(FBTrace, Obj, Domplate, Locale, Dom, Css, Events, CSSSelectorsModule, SelectorEditor) {

with (Domplate) {

// ********************************************************************************************* //
// CSS Computed panel (HTML side panel)

function CSSSelectorsPanel() {}

CSSSelectorsPanel.prototype = Obj.extend(Firebug.Panel,
{
    template: domplate(
    {
        selectorsTag:
            DIV({"class": "selectorTrials a11yCSSView", role: "list", "aria-label":
                Locale.$STR("aria.labels.Elements")},
                TAG("$selectorEditorRow"),
                DIV({"class": "elementsGroups"},
                    FOR("group", "$groups",
                        TAG("$elementsGroupTag", {group: "$group", windows: "$windows"})
                    )
                )),

        selectorEditorRow:
            DIV({"class": "selectorEditorContainer editorContainer a11yFocusNoTab",
                role: "button", "tabindex" : "0",
                "aria-label": Locale.$STR("a11y.labels.press enter to add new selector"),
                onclick: "$onClickEditor"},
                Locale.$STR("css.selector.TryASelector")
            ),

        elementsGroupTag:
            DIV({"class": "elementsGroup foldableGroup", $opened: "$group.opened",
                role: "list", _repObject: "$group"},
                H1({"class": "cssElementsHeader groupHeader focusRow", role: "listitem"},
                    DIV({"class": "twisty", role: "presentation"}),
                    SPAN({"class": "cssElementsLabel groupLabel"}, "$group.selector")
                ),
                TAG("$elementsTag", {elements: "$windows,$group.selector|getElements"})
            ),

        elementsTag:
            TABLE({"class": "cssElementsTable groupContent", role: "list"},
                TBODY({role: "presentation"},
                    FOR("element", "$elements",
                        TR({"class": "focusRow cssElementsRow cssElements",
                                role: "listitem", _repObject: "$element"},
                            TD({"class": "cssElement", role: "presentation"},
                                TAG("$element|getElementTag", {object: "$element"})
                            )
                        )
                    )
                )
            ),

        getElementTag: function(value)
        {
            var rep = Firebug.getRep(value);
            var tag = rep.shortTag ? rep.shortTag : rep.tag;
            return tag;
        },

        getElements: function(windows, selector)
        {
            return CSSSelectorsModule.matchElements(windows, selector);
        },

        onClickEditor: function(event)
        {
            var target = event.currentTarget;
            var panel = Firebug.getElementPanel(target);
            Firebug.Editor.startEditing(target, "");
        }
    }),

    getEditor: function(target, value)
    {
        if (!this.editor)
            this.editor = new CSSSelectorsPanelEditor(this.document);

        return this.editor;
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Extends Panel

    name: "selectors",
    parentPanel: "stylesheet",
    order: 0,

    initialize: function()
    {
        this.groups = [];

        Firebug.Panel.initialize.apply(this, arguments);
    },

    destroy: function(state)
    {
        Firebug.Panel.destroyNode.apply(this, arguments);
    },

    initializeNode: function(oldPanelNode)
    {
        Firebug.Panel.initializeNode.apply(this, arguments);
    },

    destroyNode: function()
    {
        Firebug.Panel.destroyNode.apply(this, arguments);
    },

    supportsObject: function(object)
    {
        return 0;
    },

    show: function(state)
    {
        this.refresh();
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Groups

    addGroup: function(selector)
    {
        var group = {
            selector: selector,
            opened: true
        }
        this.groups.push(group);

        // Append element group to display
        var elementsGroups = this.panelNode.getElementsByClassName("elementsGroups")[0];
        var action = elementsGroups.getElementsByClassName("noSelection")[0] ?
            "replace" : "append";
        var elementsGroup = this.template.elementsGroupTag[action](
            {group: group, windows: this.context.windows}, elementsGroups);

        // If there are no elements matching the selector, display an info message
        if (elementsGroup.getElementsByClassName("cssElements").length == 0)
        {
            var elementsTable = elementsGroup.getElementsByClassName("cssElementsTable")[0];
            WarningTemplate.noSelectionResultsTag.replace({}, elementsTable);
        }
    },

    refresh: function()
    {
        var parentNode = this.template.selectorsTag.replace(
                {groups: this.groups, windows: this.context.windows}, this.panelNode);

        if (this.groups.length == 0)
        {
            var elementsGroups = parentNode.getElementsByClassName("elementsGroups")[0];
            WarningTemplate.noSelectionTag.replace({}, elementsGroups);
        }
    }
});

function CSSSelectorsPanelEditor(doc)
{
    this.box = this.tag.replace({}, doc, this);
    this.input = this.box;

    Firebug.InlineEditor.prototype.initialize.call(this);
    this.tabNavigation = false;
    this.fixedWidth = true;
}

CSSSelectorsPanelEditor.prototype = domplate(SelectorEditor.prototype,
{
    tag:
        INPUT({"class": "fixedWidthEditor a11yFocusNoTab",
            type: "text",
            title: Locale.$STR("Selector"),
            oninput: "$onInput",
            onkeypress: "$onKeyPress"}
        ),

    endEditing: function(target, value, cancel)
    {
        if (cancel || value == "")
            return;

        if (this.isValidSelector(value))
            this.panel.addGroup(value);
    },

    isValidSelector: function(value)
    {
        try {
            this.panel.panelNode.querySelector(value);
            return true;
        }
        catch (e)
        {
            return false;
        }
    }
});

//********************************************************************************************* //

var WarningTemplate = domplate(Firebug.Rep,
{
    noSelectionTag:
        DIV({"class": "selectorWarning noSelection"},
            SPAN(Locale.$STR("css.selector.noSelection"))
        ),

    noSelectionResultsTag:
        DIV({"class": "selectorWarning"},
            SPAN(Locale.$STR("css.selector.noSelectionResults"))
        )
});

//********************************************************************************************* //
//Registration

Firebug.registerPanel(CSSSelectorsPanel);

return CSSSelectorsPanel;

//********************************************************************************************* //
}});
<|endoftext|>


<commit_before>/**
 * Created by ksinger on 10.05.2016.
 */

import angular from "angular";
import postSeeksInfoModule from "./post-seeks-info.js";
import postIsInfoModule from "./post-is-info.js";
import postHeaderModule from "./post-header.js";
import postShareLinkModule from "./post-share-link.js";
import labelledHrModule from "./labelled-hr.js";
import postContextDropdownModule from "./post-context-dropdown.js";

import { attach } from "../utils.js";
import won from "../won-es6.js";
import { relativeTime } from "../won-label-utils.js";
import { connect2Redux } from "../won-utils.js";
import { selectOpenPostUri, selectLastUpdateTime } from "../selectors.js";
import { actionCreators } from "../actions/actions.js";

const serviceDependencies = ["$ngRedux", "$scope", "$element"];
function genComponentConf() {
  let template = `

                <svg style="--local-primary:var(--won-primary-color);"
                     class="post-info__header__back__icon clickable">
                    <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                </svg>

            <won-post-header
                need-uri="self.post.get('uri')"
                timestamp="self.createdTimestamp"
                hide-image="::false">
            </won-post-header>
            <won-post-context-dropdown ng-if="self.post.get('ownNeed')"></won-post-context-dropdown>

            <won-gallery ng-show="self.post.get('hasImages')">
            </won-gallery>

                Created

                {{ self.friendlyTimestamp }}

            <won-post-is-info is-part="::self.isPart" ng-if="self.isPart"></won-post-is-info>
            <won-labelled-hr label="::'Search'" class="cp__labelledhr" ng-show="self.isPart && self.seeksPart"></won-labelled-hr>
            <won-post-seeks-info seeks-part="::self.seeksPart" ng-if="self.seeksPart"></won-post-seeks-info>

                    <svg class="rdflink__small">
                        <use xlink:href="#rdf_logo_1" href="#rdf_logo_1"></use>
                    </svg>
                    Post

            <won-post-share-link
                ng-if="self.post.get('state') !== self.WON.InactiveCompacted"
                post-uri="self.post.get('uri')">
            </won-post-share-link>

    `;

  class Controller {
    constructor() {
      attach(this, serviceDependencies, arguments);

      this.is = "is";
      this.seeks = "seeks";

      const selectFromState = state => {
        const postUri = selectOpenPostUri(state);
        const post = state.getIn(["needs", postUri]);
        const is = post ? post.get("is") : undefined;

        //TODO it will be possible to have more than one seeks
        const seeks = post ? post.get("seeks") : undefined;

        return {
          WON: won.WON,
          isPart: is
            ? {
                postUri: postUri,
                is: is,
                isString: "is",
                location: is && is.get("location"),
                address:
                  is.get("location") && is.get("location").get("address"),
              }
            : undefined,
          seeksPart: seeks
            ? {
                postUri: postUri,
                seeks: seeks,
                seeksString: "seeks",
                location: seeks && seeks.get("location"),
                address:
                  seeks.get("location") && seeks.get("location").get("address"),
              }
            : undefined,
          post,
          showRequestButton:
            post && !post.get("ownNeed") && !post.get("isWhatsAround"),
          friendlyTimestamp:
            post &&
            relativeTime(selectLastUpdateTime(state), post.get("creationDate")),
          createdTimestamp: post && post.get("creationDate"),
          shouldShowRdf: state.get("showRdf"),
        };
      };
      connect2Redux(
        selectFromState,
        actionCreators,
        ["self.includeHeader"],
        this
      );
    }
  }

  Controller.$inject = serviceDependencies;
  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl
    template: template,
    scope: {
      includeHeader: "=",
    },
  };
}

export default angular
  .module("won.owner.components.postInfo", [
    postIsInfoModule,
    postSeeksInfoModule,
    postHeaderModule,
    postShareLinkModule,
    labelledHrModule,
    postContextDropdownModule,
  ])
  .directive("wonPostInfo", genComponentConf).name;
<commit_msg>do not show Send request button if the need is a whats new need<commit_after>/**
 * Created by ksinger on 10.05.2016.
 */

import angular from "angular";
import postSeeksInfoModule from "./post-seeks-info.js";
import postIsInfoModule from "./post-is-info.js";
import postHeaderModule from "./post-header.js";
import postShareLinkModule from "./post-share-link.js";
import labelledHrModule from "./labelled-hr.js";
import postContextDropdownModule from "./post-context-dropdown.js";

import { attach } from "../utils.js";
import won from "../won-es6.js";
import { relativeTime } from "../won-label-utils.js";
import { connect2Redux } from "../won-utils.js";
import { selectOpenPostUri, selectLastUpdateTime } from "../selectors.js";
import { actionCreators } from "../actions/actions.js";

const serviceDependencies = ["$ngRedux", "$scope", "$element"];
function genComponentConf() {
  let template = `

                <svg style="--local-primary:var(--won-primary-color);"
                     class="post-info__header__back__icon clickable">
                    <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                </svg>

            <won-post-header
                need-uri="self.post.get('uri')"
                timestamp="self.createdTimestamp"
                hide-image="::false">
            </won-post-header>
            <won-post-context-dropdown ng-if="self.post.get('ownNeed')"></won-post-context-dropdown>

            <won-gallery ng-show="self.post.get('hasImages')">
            </won-gallery>

                Created

                {{ self.friendlyTimestamp }}

            <won-post-is-info is-part="::self.isPart" ng-if="self.isPart"></won-post-is-info>
            <won-labelled-hr label="::'Search'" class="cp__labelledhr" ng-show="self.isPart && self.seeksPart"></won-labelled-hr>
            <won-post-seeks-info seeks-part="::self.seeksPart" ng-if="self.seeksPart"></won-post-seeks-info>

                    <svg class="rdflink__small">
                        <use xlink:href="#rdf_logo_1" href="#rdf_logo_1"></use>
                    </svg>
                    Post

            <won-post-share-link
                ng-if="self.post.get('state') !== self.WON.InactiveCompacted"
                post-uri="self.post.get('uri')">
            </won-post-share-link>

    `;

  class Controller {
    constructor() {
      attach(this, serviceDependencies, arguments);

      this.is = "is";
      this.seeks = "seeks";

      const selectFromState = state => {
        const postUri = selectOpenPostUri(state);
        const post = state.getIn(["needs", postUri]);
        const is = post ? post.get("is") : undefined;

        //TODO it will be possible to have more than one seeks
        const seeks = post ? post.get("seeks") : undefined;

        return {
          WON: won.WON,
          isPart: is
            ? {
                postUri: postUri,
                is: is,
                isString: "is",
                location: is && is.get("location"),
                address:
                  is.get("location") && is.get("location").get("address"),
              }
            : undefined,
          seeksPart: seeks
            ? {
                postUri: postUri,
                seeks: seeks,
                seeksString: "seeks",
                location: seeks && seeks.get("location"),
                address:
                  seeks.get("location") && seeks.get("location").get("address"),
              }
            : undefined,
          post,
          showRequestButton:
            post &&
            !post.get("ownNeed") &&
            !post.get("isWhatsAround") &&
            !post.get("isWhatsNew"),
          friendlyTimestamp:
            post &&
            relativeTime(selectLastUpdateTime(state), post.get("creationDate")),
          createdTimestamp: post && post.get("creationDate"),
          shouldShowRdf: state.get("showRdf"),
        };
      };
      connect2Redux(
        selectFromState,
        actionCreators,
        ["self.includeHeader"],
        this
      );
    }
  }

  Controller.$inject = serviceDependencies;
  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl
    template: template,
    scope: {
      includeHeader: "=",
    },
  };
}

export default angular
  .module("won.owner.components.postInfo", [
    postIsInfoModule,
    postSeeksInfoModule,
    postHeaderModule,
    postShareLinkModule,
    labelledHrModule,
    postContextDropdownModule,
  ])
  .directive("wonPostInfo", genComponentConf).name;
<|endoftext|>


<commit_before>/**
 * Created by ksinger on 10.05.2016.
 */

import angular from "angular";
import postHeaderModule from "./post-header.js";
import postContextDropdownModule from "./post-context-dropdown.js";
import postContentModule from "./post-content.js";
import shareDropdownModule from "./share-dropdown.js";
import { attach, getIn } from "../utils.js";
import { connect2Redux } from "../won-utils.js";
import { isWhatsNewNeed } from "../need-utils.js";
import { getPostUriFromRoute } from "../selectors/general-selectors.js";
import { actionCreators } from "../actions/actions.js";
import { classOnComponentRoot } from "../cstm-ng-utils.js";

import "style/_post-info.scss";

const serviceDependencies = ["$ngRedux", "$scope", "$element"];
function genComponentConf() {
  let template = `

                  <svg class="post-info__header__back__button__icon">
                      <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                  </svg>

                  <svg class="post-info__header__back__button__icon">
                      <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                  </svg>

                  <svg class="post-info__header__back__button__icon clickable hide-in-responsive">
                      <use xlink:href="#ico36_close" href="#ico36_close"></use>
                  </svg>
                  <svg class="post-info__header__back__button__icon clickable show-in-responsive">
                      <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                  </svg>

            <won-post-header
                need-uri="self.post.get('uri')">
            </won-post-header>
            <won-share-dropdown need-uri="self.post.get('uri')"></won-share-dropdown>
            <won-post-context-dropdown need-uri="self.post.get('uri')"></won-post-context-dropdown>

        <won-post-content post-uri="self.postUri"></won-post-content>

            <button class="won-button--filled red post-info__footer__button"
                ng-if="self.showCreateWhatsAround()"
                ng-click="self.createWhatsAround()"
                ng-disabled="self.processingPublish">
                <svg class="won-button-icon" style="--local-primary:white;">
                    <use xlink:href="#ico36_location_current" href="#ico36_location_current"></use>
                </svg>
                What's in your Area?
                Finding out what's going on…
            </button>

    `;

  class Controller {
    constructor() {
      attach(this, serviceDependencies, arguments);
      window.pi4dbg = this;

      const selectFromState = state => {
        /*
          If the post-info component has a need-uri attribute we display this need-uri instead of the postUriFromTheRoute
          This way we can include a overlay-close button instead of the current back-button handling
        */
        const postUri = this.needUri
          ? this.needUri
          : getPostUriFromRoute(state);
        const post = state.getIn(["needs", postUri]);

        return {
          processingPublish: state.getIn(["process", "processingPublish"]),
          postUri,
          post,
          postLoading:
            !post ||
            getIn(state, ["process", "needs", post.get("uri"), "loading"]),
          postFailedToLoad:
            post &&
            getIn(state, ["process", "needs", post.get("uri"), "failedToLoad"]),
          createdTimestamp: post && post.get("creationDate"),
          showOverlayNeed: !!this.needUri,
        };
      };
      connect2Redux(
        selectFromState,
        actionCreators,
        ["self.includeHeader", "self.needUri"],
        this
      );

      classOnComponentRoot("won-is-loading", () => this.postLoading, this);
    }

    showCreateWhatsAround() {
      return this.post && this.post.get("isOwned") && isWhatsNewNeed(this.post);
    }

    createWhatsAround() {
      if (!this.processingPublish) {
        this.needs__whatsAround();
      }
    }
  }

  Controller.$inject = serviceDependencies;
  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl
    template: template,
    scope: {
      includeHeader: "=",
      needUri: "=",
    },
  };
}

export default angular
  .module("won.owner.components.postInfo", [
    postHeaderModule,
    postContextDropdownModule,
    postContentModule,
    shareDropdownModule,
  ])
  .directive("wonPostInfo", genComponentConf).name;
<commit_msg>Fix back button for post-info<commit_after>/**
 * Created by ksinger on 10.05.2016.
 */

import angular from "angular";
import postHeaderModule from "./post-header.js";
import postContextDropdownModule from "./post-context-dropdown.js";
import postContentModule from "./post-content.js";
import shareDropdownModule from "./share-dropdown.js";
import { attach, getIn } from "../utils.js";
import { connect2Redux } from "../won-utils.js";
import { isWhatsNewNeed } from "../need-utils.js";
import { getPostUriFromRoute } from "../selectors/general-selectors.js";
import { actionCreators } from "../actions/actions.js";
import { classOnComponentRoot } from "../cstm-ng-utils.js";

import "style/_post-info.scss";

const serviceDependencies = ["$ngRedux", "$scope", "$element"];
function genComponentConf() {
  let template = `

                  <svg class="post-info__header__back__button__icon">
                      <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                  </svg>

                  <svg class="post-info__header__back__button__icon">
                      <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                  </svg>

                  <svg class="post-info__header__back__button__icon clickable hide-in-responsive">
                      <use xlink:href="#ico36_close" href="#ico36_close"></use>
                  </svg>
                  <svg class="post-info__header__back__button__icon clickable show-in-responsive">
                      <use xlink:href="#ico36_backarrow" href="#ico36_backarrow"></use>
                  </svg>

            <won-post-header
                need-uri="self.post.get('uri')">
            </won-post-header>
            <won-share-dropdown need-uri="self.post.get('uri')"></won-share-dropdown>
            <won-post-context-dropdown need-uri="self.post.get('uri')"></won-post-context-dropdown>

        <won-post-content post-uri="self.postUri"></won-post-content>

            <button class="won-button--filled red post-info__footer__button"
                ng-if="self.showCreateWhatsAround()"
                ng-click="self.createWhatsAround()"
                ng-disabled="self.processingPublish">
                <svg class="won-button-icon" style="--local-primary:white;">
                    <use xlink:href="#ico36_location_current" href="#ico36_location_current"></use>
                </svg>
                What's in your Area?
                Finding out what's going on…
            </button>

    `;

  class Controller {
    constructor() {
      attach(this, serviceDependencies, arguments);
      window.pi4dbg = this;

      const selectFromState = state => {
        /*
          If the post-info component has a need-uri attribute we display this need-uri instead of the postUriFromTheRoute
          This way we can include a overlay-close button instead of the current back-button handling
        */
        const postUri = this.needUri
          ? this.needUri
          : getPostUriFromRoute(state);
        const post = state.getIn(["needs", postUri]);

        return {
          processingPublish: state.getIn(["process", "processingPublish"]),
          postUri,
          post,
          postLoading:
            !post ||
            getIn(state, ["process", "needs", post.get("uri"), "loading"]),
          postFailedToLoad:
            post &&
            getIn(state, ["process", "needs", post.get("uri"), "failedToLoad"]),
          createdTimestamp: post && post.get("creationDate"),
          showOverlayNeed: !!this.needUri,
        };
      };
      connect2Redux(
        selectFromState,
        actionCreators,
        ["self.includeHeader", "self.needUri"],
        this
      );

      classOnComponentRoot("won-is-loading", () => this.postLoading, this);
    }

    showCreateWhatsAround() {
      return this.post && this.post.get("isOwned") && isWhatsNewNeed(this.post);
    }

    createWhatsAround() {
      if (!this.processingPublish) {
        this.needs__whatsAround();
      }
    }
  }

  Controller.$inject = serviceDependencies;
  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl
    template: template,
    scope: {
      includeHeader: "=",
      needUri: "=",
    },
  };
}

export default angular
  .module("won.owner.components.postInfo", [
    postHeaderModule,
    postContextDropdownModule,
    postContentModule,
    shareDropdownModule,
  ])
  .directive("wonPostInfo", genComponentConf).name;
<|endoftext|>