<commit_before>/* @flow */

const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/
const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/

// KeyboardEvent.keyCode aliases
const keyCodes: { [key: string]: number | Array<number> } = {
  esc: 27,
  tab: 9,
  enter: 13,
  space: 32,
  up: 38,
  left: 37,
  right: 39,
  down: 40,
  'delete': [8, 46]
}

// KeyboardEvent.key aliases
const keyNames: { [key: string]: string | Array<string> } = {
  esc: 'Escape',
  tab: 'Tab',
  enter: 'Enter',
  space: ' ',
  // #7806: IE11 uses key names without `Arrow` prefix for arrow keys.
  up: ['Up', 'ArrowUp'],
  left: ['Left', 'ArrowLeft'],
  right: ['Right', 'ArrowRight'],
  down: ['Down', 'ArrowDown'],
  'delete': ['Backspace', 'Delete']
}

// #4868: modifiers that prevent the execution of the listener
// need to explicitly return null so that we can determine whether to remove
// the listener for .once
const genGuard = condition => `if(${condition})return null;`

const modifierCode: { [key: string]: string } = {
  stop: '$event.stopPropagation();',
  prevent: '$event.preventDefault();',
  self: genGuard(`$event.target !== $event.currentTarget`),
  ctrl: genGuard(`!$event.ctrlKey`),
  shift: genGuard(`!$event.shiftKey`),
  alt: genGuard(`!$event.altKey`),
  meta: genGuard(`!$event.metaKey`),
  left: genGuard(`'button' in $event && $event.button !== 0`),
  middle: genGuard(`'button' in $event && $event.button !== 1`),
  right: genGuard(`'button' in $event && $event.button !== 2`)
}

export function genHandlers (
  events: ASTElementHandlers,
  isNative: boolean,
  warn: Function
): string {
  let res = isNative ? 'nativeOn:{' : 'on:{'
  for (const name in events) {
    res += `"${name}":${genHandler(name, events[name])},`
  }
  return res.slice(0, -1) + '}'
}

// Generate handler code with binding params on Weex
/* istanbul ignore next */
function genWeexHandler (params: Array<any>, handlerCode: string) {
  let innerHandlerCode = handlerCode
  const exps = params.filter(exp => simplePathRE.test(exp) && exp !== '$event')
  const bindings = exps.map(exp => ({ '@binding': exp }))
  const args = exps.map((exp, i) => {
    const key = `$_${i + 1}`
    innerHandlerCode = innerHandlerCode.replace(exp, key)
    return key
  })
  args.push('$event')
  return '{\n' +
    `handler:function(${args.join(',')}){${innerHandlerCode}},\n` +
    `params:${JSON.stringify(bindings)}\n` +
    '}'
}

function genHandler (
  name: string,
  handler: ASTElementHandler | Array<ASTElementHandler>
): string {
  if (!handler) {
    return 'function(){}'
  }

  if (Array.isArray(handler)) {
    return `[${handler.map(handler => genHandler(name, handler)).join(',')}]`
  }

  const isMethodPath = simplePathRE.test(handler.value)
  const isFunctionExpression = fnExpRE.test(handler.value)

  if (!handler.modifiers) {
    if (isMethodPath || isFunctionExpression) {
      return handler.value
    }
    /* istanbul ignore if */
    if (__WEEX__ && handler.params) {
      return genWeexHandler(handler.params, handler.value)
    }
    return `function($event){${handler.value}}` // inline statement
  } else {
    let code = ''
    let genModifierCode = ''
    const keys = []
    for (const key in handler.modifiers) {
      if (modifierCode[key]) {
        genModifierCode += modifierCode[key]
        // left/right
        if (keyCodes[key]) {
          keys.push(key)
        }
      } else if (key === 'exact') {
        const modifiers: ASTModifiers = (handler.modifiers: any)
        genModifierCode += genGuard(
          ['ctrl', 'shift', 'alt', 'meta']
            .filter(keyModifier => !modifiers[keyModifier])
            .map(keyModifier => `$event.${keyModifier}Key`)
            .join('||')
        )
      } else {
        keys.push(key)
      }
    }
    if (keys.length) {
      code += genKeyFilter(keys)
    }
    // Make sure modifiers like prevent and stop get executed after key filtering
    if (genModifierCode) {
      code += genModifierCode
    }
    const handlerCode = isMethodPath
      ? `return ${handler.value}($event)`
      : isFunctionExpression
        ? `return (${handler.value})($event)`
        : handler.value
    /* istanbul ignore if */
    if (__WEEX__ && handler.params) {
      return genWeexHandler(handler.params, code + handlerCode)
    }
    return `function($event){${code}${handlerCode}}`
  }
}

function genKeyFilter (keys: Array<string>): string {
  return `if(!('button' in $event)&&${keys.map(genFilterCode).join('&&')})return null;`
}

function genFilterCode (key: string): string {
  const keyVal = parseInt(key, 10)
  if (keyVal) {
    return `$event.keyCode!==${keyVal}`
  }
  const keyCode = keyCodes[key]
  const keyName = keyNames[key]
  return (
    `_k($event.keyCode,` +
    `${JSON.stringify(key)},` +
    `${JSON.stringify(keyCode)},` +
    `$event.key,` +
    `${JSON.stringify(keyName)}` +
    `)`
  )
}
<commit_msg>fix(codegen): support IE11 and Edge use of "Esc" key (#7887)<commit_after>/* @flow */

const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/
const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/

// KeyboardEvent.keyCode aliases
const keyCodes: { [key: string]: number | Array<number> } = {
  esc: 27,
  tab: 9,
  enter: 13,
  space: 32,
  up: 38,
  left: 37,
  right: 39,
  down: 40,
  'delete': [8, 46]
}

// KeyboardEvent.key aliases
const keyNames: { [key: string]: string | Array<string> } = {
  // #7880: IE11 and Edge use `Esc` for Escape key name.
  esc: ['Esc', 'Escape'],
  tab: 'Tab',
  enter: 'Enter',
  space: ' ',
  // #7806: IE11 uses key names without `Arrow` prefix for arrow keys.
  up: ['Up', 'ArrowUp'],
  left: ['Left', 'ArrowLeft'],
  right: ['Right', 'ArrowRight'],
  down: ['Down', 'ArrowDown'],
  'delete': ['Backspace', 'Delete']
}

// #4868: modifiers that prevent the execution of the listener
// need to explicitly return null so that we can determine whether to remove
// the listener for .once
const genGuard = condition => `if(${condition})return null;`

const modifierCode: { [key: string]: string } = {
  stop: '$event.stopPropagation();',
  prevent: '$event.preventDefault();',
  self: genGuard(`$event.target !== $event.currentTarget`),
  ctrl: genGuard(`!$event.ctrlKey`),
  shift: genGuard(`!$event.shiftKey`),
  alt: genGuard(`!$event.altKey`),
  meta: genGuard(`!$event.metaKey`),
  left: genGuard(`'button' in $event && $event.button !== 0`),
  middle: genGuard(`'button' in $event && $event.button !== 1`),
  right: genGuard(`'button' in $event && $event.button !== 2`)
}

export function genHandlers (
  events: ASTElementHandlers,
  isNative: boolean,
  warn: Function
): string {
  let res = isNative ? 'nativeOn:{' : 'on:{'
  for (const name in events) {
    res += `"${name}":${genHandler(name, events[name])},`
  }
  return res.slice(0, -1) + '}'
}

// Generate handler code with binding params on Weex
/* istanbul ignore next */
function genWeexHandler (params: Array<any>, handlerCode: string) {
  let innerHandlerCode = handlerCode
  const exps = params.filter(exp => simplePathRE.test(exp) && exp !== '$event')
  const bindings = exps.map(exp => ({ '@binding': exp }))
  const args = exps.map((exp, i) => {
    const key = `$_${i + 1}`
    innerHandlerCode = innerHandlerCode.replace(exp, key)
    return key
  })
  args.push('$event')
  return '{\n' +
    `handler:function(${args.join(',')}){${innerHandlerCode}},\n` +
    `params:${JSON.stringify(bindings)}\n` +
    '}'
}

function genHandler (
  name: string,
  handler: ASTElementHandler | Array<ASTElementHandler>
): string {
  if (!handler) {
    return 'function(){}'
  }

  if (Array.isArray(handler)) {
    return `[${handler.map(handler => genHandler(name, handler)).join(',')}]`
  }

  const isMethodPath = simplePathRE.test(handler.value)
  const isFunctionExpression = fnExpRE.test(handler.value)

  if (!handler.modifiers) {
    if (isMethodPath || isFunctionExpression) {
      return handler.value
    }
    /* istanbul ignore if */
    if (__WEEX__ && handler.params) {
      return genWeexHandler(handler.params, handler.value)
    }
    return `function($event){${handler.value}}` // inline statement
  } else {
    let code = ''
    let genModifierCode = ''
    const keys = []
    for (const key in handler.modifiers) {
      if (modifierCode[key]) {
        genModifierCode += modifierCode[key]
        // left/right
        if (keyCodes[key]) {
          keys.push(key)
        }
      } else if (key === 'exact') {
        const modifiers: ASTModifiers = (handler.modifiers: any)
        genModifierCode += genGuard(
          ['ctrl', 'shift', 'alt', 'meta']
            .filter(keyModifier => !modifiers[keyModifier])
            .map(keyModifier => `$event.${keyModifier}Key`)
            .join('||')
        )
      } else {
        keys.push(key)
      }
    }
    if (keys.length) {
      code += genKeyFilter(keys)
    }
    // Make sure modifiers like prevent and stop get executed after key filtering
    if (genModifierCode) {
      code += genModifierCode
    }
    const handlerCode = isMethodPath
      ? `return ${handler.value}($event)`
      : isFunctionExpression
        ? `return (${handler.value})($event)`
        : handler.value
    /* istanbul ignore if */
    if (__WEEX__ && handler.params) {
      return genWeexHandler(handler.params, code + handlerCode)
    }
    return `function($event){${code}${handlerCode}}`
  }
}

function genKeyFilter (keys: Array<string>): string {
  return `if(!('button' in $event)&&${keys.map(genFilterCode).join('&&')})return null;`
}

function genFilterCode (key: string): string {
  const keyVal = parseInt(key, 10)
  if (keyVal) {
    return `$event.keyCode!==${keyVal}`
  }
  const keyCode = keyCodes[key]
  const keyName = keyNames[key]
  return (
    `_k($event.keyCode,` +
    `${JSON.stringify(key)},` +
    `${JSON.stringify(keyCode)},` +
    `$event.key,` +
    `${JSON.stringify(keyName)}` +
    `)`
  )
}
<|endoftext|>


<commit_before>// vim:ts=4:sw=4:expandtab

x11vis = (function() {
    var used_names = [];
    var details = {};

    function type_to_color(type) {
        if (type === 'event') {
            return '#ffffc0';
        } else if (type === 'reply') {
            return '#c0ffc0';
        } else if (type === 'error') {
            return '#ffc0c0';
        } else {
            return '#c0c0c0';
        }
    }

    // TODO: formatting needs to be more beautiful
    function detail_obj_to_html(obj, indent) {
        var result = '';
        $.each(obj, function(key, val) {
            var formatted_value;
            if (typeof(val) === 'object') {
                formatted_value = detail_obj_to_html(val, indent + 1);
            } else {
                formatted_value = val;
            }
            result += '
' + key + ': ' + formatted_value + '
';
        });
        return result;
    }

    function toggle_expand_packet(pkt) {
        var html = $(pkt).find('.moredetails')

        // if it's visible, hide it
        if (html.css('display') === 'block') {
            html.css('display', 'none');
        } else {
            // otherwise, format the details (if not expanded) and show it
            if ($(pkt).data('expanded') === undefined) {
                html.append(detail_obj_to_html($(pkt).data('moredetails'), 0));
                $(pkt).data('expanded', true);
            }

            html.css('display', 'block');
        }
    }

    function create_request_layout(obj) {
        // concat'ing strings instead of using the DOM saves us ~ 350 ms
        // (measured with 547 bursts of a typical i3 startup)

        var html = '
\

\
        ' + obj.seq + '\
        ' + obj.name + '\
        ' + parse_detail(obj.details) + '\
        \

\
        ';
        var rdiv = $(html);

        // store object type and moredetails for later (used type_to_color and
        // detail_obj_to_html, respectively)
        rdiv.data('type', obj.type);
        rdiv.data('moredetails', obj.moredetails);

        return rdiv;
    }

    function parse_detail(detail) {
        var result = detail;
        var matches = detail.match(/%([^%]+)%/g) || [];
        matches.forEach(function(m) {
            var id = m.replace(/%/g, '');
            result = result.replace(m, '');
        });
        return result;
    }

    function save_cleverness(obj) {
        //console.log('obj is clever: ' + obj.id + ' to ' + obj.title);
        var title = obj.title;
        var cnt = 2;
        while ($.inArray(title, used_names) !== -1) {
            title = obj.title + ' (' + cnt + ')';
            cnt = cnt + 1;
        }
        obj.title = title;
        used_names.push(title);
        details[obj.id] = obj;
    }

    function handle_marker(marker) {
        var div = $(tmpl.get('marker'));
        div.find("span.name").replaceWith(marker.title);
        $('body').append(div);
    }

    function handle_burst(burst) {
        // TODO: what about zero-length bursts?
        if (burst.packets.length === 0) {
            return;
        }
        var div = $(tmpl.get('request_buffer'));
        div.find(".request_info").append(burst.elapsed);

        // TODO: add direction also to burst
        var is_reply = false;
        $.each(burst.packets, function(idx, elm) {
            if (elm.type === 'reply') {
                is_reply = true;
            } else if (elm.type === 'event') {
                is_reply = true;
            }
        });
        if (is_reply) {
            div.css('margin-left', '2em');
            div.find(".client").replaceWith(parse_detail('%conn_' + burst.fd + '%←'));
        } else {
            div.find(".client").replaceWith(parse_detail('%conn_' + burst.fd + '%→'));
            div.css('margin-right', '2em');
        }

        burst.packets.forEach(function(obj) {
            if (obj.type === 'cleverness') {
                save_cleverness(obj);
            } else {
                div.append(create_request_layout(obj));
            }
        });

        $('body').append(div);
    }

    function update_hide_packets() {
        // add all event types (once) to the 'hide'-panel
        // TODO: group by type
        // TODO: start with collapsed 'hide' panel
        var t = _.map($('span.name'), function(elm) { return $(elm).text(); });
        t.sort();
        $.each(_.uniq(t, true), function(idx, elm) {
            var cb = $('<input type="checkbox" class="display_cb" id="display_cb_' + idx + '" checked="checked">' + elm + '
');
            cb.data('element', elm);
            $('div#display').append(cb);
        });

        $('input.display_cb').click(function() {
            var elm = $(this).data('element');
            $("span.name:contains('" + elm + "')")
                .parent()
                .css('display', ($(this).attr('checked') ? 'block' : 'none'));
        });
    }

    function update_hide_clients() {
        // add all clients (once) to 'hide' panel
        t = _.map($('div.reqbuf .header .id_name'), function (elm) { return $(elm).attr('id'); });
        t.sort();
        $.each(_.uniq(t, true), function(idx, elm) {
            console.log('client: ' + elm);
            var cb = $('<input type="checkbox" class="client_cb" id="client_cb_' + idx + '" checked="checked">' + parse_detail('%' + elm + '%') + '
');
            cb.data('element', elm);
            $('div#filter_clients').append(cb);
        });

        $('input.client_cb').click(function() {
            var elm = $(this).data('element');
            $('div.reqbuf .header .id_name#' + elm)
                .parent()
                .parent()
                .css('display', ($(this).attr('checked') ? 'block' : 'none'));
        });
    }

    function fold_boring_packets() {
        // go through all reqbufs and fold series of 'boring' requests (like InternAtom)
        var boring_packets = [ 'InternAtom', 'GrabKey', 'ImageText8', 'ImageText16' ];
        $('div.reqbuf').each(function() {
            var last_name = '';
            var to_fold = [];
            var samecnt = 0;
            // TODO: check if there are 5 singlepackets at all before iterating
            $(this).find('div.singlepacket').each(function() {
                var name = $(this).find('span.name').text();
                if ($.inArray(name, to_fold) !== -1) {
                    return;
                }
                samecnt = (last_name === name ? samecnt + 1 : 0);
                if (samecnt === 5 && $.inArray(last_name, boring_packets) !== -1) {
                    // more than 5 packets of the same type, fold them
                    to_fold.push(last_name);
                }
                last_name = name;
            });

            var that = this;
            $.each(to_fold, function(idx, elm) {
                var folded = $('

');
                var info = $('
 lots of ' + elm + '
');
                var to_expand = $('

');
                var elements = $(that).find('div.singlepacket span.name:econtains("' + elm + '")').parent();
                var type = elements.first().data('type');
                folded.data('type', type);
                folded.css('background-color', type_to_color(type));
                info.append(' (' + elements.size() + ' packets folded)');
                elements.wrapAll(to_expand);
                $(that).find('.to_expand')
                    .wrap(folded)
                    .parent()
                    .prepend(info);

            });
        });
    }

    function setup_expand_button() {
        // set up the expand button
        $('.singlepacket').live('click', function() {
            toggle_expand_packet(this);
        });

        $('.folded_info').live('click', function() {
            var to_expand = $(this).parent().find('.to_expand');
            if (to_expand.css('display') === 'block') {
                to_expand.css('display', 'none');
            } else {
                to_expand.css('display', 'block');
            }
        });

        // TODO: only show button if the request has details
        $('.request.singlepacket, .folded').each(function() {
            $(this).hover(function() {
                var expandBtn = $(this).children('.expandbtn');
                // if the expand image is not yet loaded, add it
                if (expandBtn.find('img').size() === 0) {
                    expandBtn.append($(''));
                }
                expandBtn.find('img').css('display', 'inline');
                $(this).css('background-color', '#eff8c6');
            }, function() {
                $(this).find('.expandbtn img').css('display', 'none');
                $(this).css('background-color', type_to_color($(this).data('type')));
            });
        });
    }

    function display_cleverness() {
        // resolve all the cleverness placeholders
        $('span.id_name').each(function() {
            var id = $(this).attr('id');
            if (details[id] !== undefined) {
                $(this).append(details[id].title);
                if (details[id].idtype === 'atom') {
                    $(this).css('background-color', '#82caff');
                } else if (details[id].idtype === 'font') {
                    $(this).css('background-color', '#f87217');
                } else if (details[id].idtype === 'pixmap') {
                    $(this).css('background-color', '#d462ff');
                } else if (details[id].idtype === 'gcontext') {
                    $(this).css('background-color', '#f433ff');
                } else {
                    $(this).css('background-color', '#f75d59');
                }
            } else {
                $(this).append(id);
            }
        });
    }

    var process_json = function(json) {
        json.forEach(function(obj) {
            if (obj.type === 'cleverness') {
                save_cleverness(obj);
            } else if (obj.type === 'marker') {
                handle_marker(obj);
            } else {
                handle_burst(obj);
            }
        });

        update_hide_packets();
        update_hide_clients();
        fold_boring_packets();
        setup_expand_button();
        display_cleverness();

        // initialize the markerbar
        markerbar().update();
    };

    var process_cleverness = function(json) {
        json.forEach(function(obj) {
            save_cleverness(obj);
        });
    };

    return function() {
        return {
            process_json: process_json,
            process_cleverness: process_cleverness
        };
    };
})();
<commit_msg>optimization: use for-loop instead of foreach (saves ~100ms)<commit_after>// vim:ts=4:sw=4:expandtab

x11vis = (function() {
    var used_names = [];
    var details = {};

    function type_to_color(type) {
        if (type === 'event') {
            return '#ffffc0';
        } else if (type === 'reply') {
            return '#c0ffc0';
        } else if (type === 'error') {
            return '#ffc0c0';
        } else {
            return '#c0c0c0';
        }
    }

    // TODO: formatting needs to be more beautiful
    function detail_obj_to_html(obj, indent) {
        var result = '';
        $.each(obj, function(key, val) {
            var formatted_value;
            if (typeof(val) === 'object') {
                formatted_value = detail_obj_to_html(val, indent + 1);
            } else {
                formatted_value = val;
            }
            result += '
' + key + ': ' + formatted_value + '
';
        });
        return result;
    }

    function toggle_expand_packet(pkt) {
        var html = $(pkt).find('.moredetails')

        // if it's visible, hide it
        if (html.css('display') === 'block') {
            html.css('display', 'none');
        } else {
            // otherwise, format the details (if not expanded) and show it
            if ($(pkt).data('expanded') === undefined) {
                html.append(detail_obj_to_html($(pkt).data('moredetails'), 0));
                $(pkt).data('expanded', true);
            }

            html.css('display', 'block');
        }
    }

    function create_request_layout(obj) {
        // concat'ing strings instead of using the DOM saves us ~ 350 ms
        // (measured with 547 bursts of a typical i3 startup)

        var html = '
\

\
        ' + obj.seq + '\
        ' + obj.name + '\
        ' + parse_detail(obj.details) + '\
        \

\
        ';
        var rdiv = $(html);

        // store object type and moredetails for later (used type_to_color and
        // detail_obj_to_html, respectively)
        rdiv.data('type', obj.type);
        rdiv.data('moredetails', obj.moredetails);

        return rdiv;
    }

    function parse_detail(detail) {
        var result = detail;
        var matches = detail.match(/%([^%]+)%/g) || [];
        matches.forEach(function(m) {
            var id = m.replace(/%/g, '');
            result = result.replace(m, '');
        });
        return result;
    }

    function save_cleverness(obj) {
        //console.log('obj is clever: ' + obj.id + ' to ' + obj.title);
        var title = obj.title;
        var cnt = 2;
        while ($.inArray(title, used_names) !== -1) {
            title = obj.title + ' (' + cnt + ')';
            cnt = cnt + 1;
        }
        obj.title = title;
        used_names.push(title);
        details[obj.id] = obj;
    }

    function handle_marker(marker) {
        var div = $(tmpl.get('marker'));
        div.find("span.name").replaceWith(marker.title);
        $('body').append(div);
    }

    function handle_burst(burst) {
        // TODO: what about zero-length bursts?
        if (burst.packets.length === 0) {
            return;
        }
        var div = $(tmpl.get('request_buffer'));
        div.find(".request_info").append(burst.elapsed);

        // TODO: add direction also to burst
        var is_reply = false;
        $.each(burst.packets, function(idx, elm) {
            if (elm.type === 'reply') {
                is_reply = true;
            } else if (elm.type === 'event') {
                is_reply = true;
            }
        });
        if (is_reply) {
            div.css('margin-left', '2em');
            div.find(".client").replaceWith(parse_detail('%conn_' + burst.fd + '%←'));
        } else {
            div.find(".client").replaceWith(parse_detail('%conn_' + burst.fd + '%→'));
            div.css('margin-right', '2em');
        }

        burst.packets.forEach(function(obj) {
            if (obj.type === 'cleverness') {
                save_cleverness(obj);
            } else {
                div.append(create_request_layout(obj));
            }
        });

        $('body').append(div);
    }

    function update_hide_packets() {
        // add all event types (once) to the 'hide'-panel
        // TODO: group by type
        // TODO: start with collapsed 'hide' panel
        var t = _.map($('span.name'), function(elm) { return $(elm).text(); });
        t.sort();
        $.each(_.uniq(t, true), function(idx, elm) {
            var cb = $('<input type="checkbox" class="display_cb" id="display_cb_' + idx + '" checked="checked">' + elm + '
');
            cb.data('element', elm);
            $('div#display').append(cb);
        });

        $('input.display_cb').click(function() {
            var elm = $(this).data('element');
            $("span.name:contains('" + elm + "')")
                .parent()
                .css('display', ($(this).attr('checked') ? 'block' : 'none'));
        });
    }

    function update_hide_clients() {
        // add all clients (once) to 'hide' panel
        t = _.map($('div.reqbuf .header .id_name'), function (elm) { return $(elm).attr('id'); });
        t.sort();
        $.each(_.uniq(t, true), function(idx, elm) {
            console.log('client: ' + elm);
            var cb = $('<input type="checkbox" class="client_cb" id="client_cb_' + idx + '" checked="checked">' + parse_detail('%' + elm + '%') + '
');
            cb.data('element', elm);
            $('div#filter_clients').append(cb);
        });

        $('input.client_cb').click(function() {
            var elm = $(this).data('element');
            $('div.reqbuf .header .id_name#' + elm)
                .parent()
                .parent()
                .css('display', ($(this).attr('checked') ? 'block' : 'none'));
        });
    }

    function fold_boring_packets() {
        // go through all reqbufs and fold series of 'boring' requests (like InternAtom)
        var boring_packets = [ 'InternAtom', 'GrabKey', 'ImageText8', 'ImageText16' ];
        $('div.reqbuf').each(function() {
            var last_name = '';
            var to_fold = [];
            var samecnt = 0;
            // TODO: check if there are 5 singlepackets at all before iterating
            $(this).find('div.singlepacket').each(function() {
                var name = $(this).find('span.name').text();
                if ($.inArray(name, to_fold) !== -1) {
                    return;
                }
                samecnt = (last_name === name ? samecnt + 1 : 0);
                if (samecnt === 5 && $.inArray(last_name, boring_packets) !== -1) {
                    // more than 5 packets of the same type, fold them
                    to_fold.push(last_name);
                }
                last_name = name;
            });

            var that = this;
            $.each(to_fold, function(idx, elm) {
                var folded = $('

');
                var info = $('
 lots of ' + elm + '
');
                var to_expand = $('

');
                var elements = $(that).find('div.singlepacket span.name:econtains("' + elm + '")').parent();
                var type = elements.first().data('type');
                folded.data('type', type);
                folded.css('background-color', type_to_color(type));
                info.append(' (' + elements.size() + ' packets folded)');
                elements.wrapAll(to_expand);
                $(that).find('.to_expand')
                    .wrap(folded)
                    .parent()
                    .prepend(info);

            });
        });
    }

    function setup_expand_button() {
        // set up the expand button
        $('.singlepacket').live('click', function() {
            toggle_expand_packet(this);
        });

        $('.folded_info').live('click', function() {
            var to_expand = $(this).parent().find('.to_expand');
            if (to_expand.css('display') === 'block') {
                to_expand.css('display', 'none');
            } else {
                to_expand.css('display', 'block');
            }
        });

        // TODO: only show button if the request has details
        $('.request.singlepacket, .folded').each(function() {
            $(this).hover(function() {
                var expandBtn = $(this).children('.expandbtn');
                // if the expand image is not yet loaded, add it
                if (expandBtn.find('img').size() === 0) {
                    expandBtn.append($(''));
                }
                expandBtn.find('img').css('display', 'inline');
                $(this).css('background-color', '#eff8c6');
            }, function() {
                $(this).find('.expandbtn img').css('display', 'none');
                $(this).css('background-color', type_to_color($(this).data('type')));
            });
        });
    }

    function display_cleverness() {
        // resolve all the cleverness placeholders
        $('span.id_name').each(function() {
            var id = $(this).attr('id');
            if (details[id] !== undefined) {
                $(this).append(details[id].title);
                if (details[id].idtype === 'atom') {
                    $(this).css('background-color', '#82caff');
                } else if (details[id].idtype === 'font') {
                    $(this).css('background-color', '#f87217');
                } else if (details[id].idtype === 'pixmap') {
                    $(this).css('background-color', '#d462ff');
                } else if (details[id].idtype === 'gcontext') {
                    $(this).css('background-color', '#f433ff');
                } else {
                    $(this).css('background-color', '#f75d59');
                }
            } else {
                $(this).append(id);
            }
        });
    }

    var process_json = function(json) {
        var len = json.length;
        for (var c = 0; c < len; c++) {
            var obj = json[c];
            if (obj.type === 'cleverness') {
                save_cleverness(obj);
            } else if (obj.type === 'marker') {
                handle_marker(obj);
            } else {
                handle_burst(obj);
            }
        }

        update_hide_packets();
        update_hide_clients();
        fold_boring_packets();
        setup_expand_button();
        display_cleverness();

        // initialize the markerbar
        markerbar().update();
    };

    var process_cleverness = function(json) {
        json.forEach(function(obj) {
            save_cleverness(obj);
        });
    };

    return function() {
        return {
            process_json: process_json,
            process_cleverness: process_cleverness
        };
    };
})();
<|endoftext|>


<commit_before>'use strict'

var utils = require('../utils')
var Vue = require('vue')
Vue.config.silent = true

/* start-debug-block */
Vue.config.silent = false
Vue.config.debug = true
/* end-debug-block */

// default config
var config = {
  appActive: true,

  mode: 'icon',
  // icon: show pop icon first
  // direct: show panel directly
  // ctrl: TODO show panel when double click ctrl + selection not empty

  // show panel when triple press ctrl
  tripleCtrl: true,

  chineseMode: true,
  englishMode: true
}

// get user config
utils
  .sendMessage({
    msg:'grab',
    items: Object.keys(config)
  })
  .then(function(response) {
    if (response.msg === 'success') {
      setConfig(response.data)
    }
  })

// when user save config on popup panel,
// appStateChanged is triggered
chrome.runtime.onMessage.addListener(
  function (request, sender, sendResponse) {
    if (request.msg === 'appStateChanged') {
      setConfig(request.data)
    }
  })

// inject component
var content = new Vue(require('./main'))
content.$mount().$before(document.body.firstChild)

// listen to click
document.body.addEventListener('mouseup', mouseupEventHandler)

// listen to triple ctrl keypress
var tripleCtrlCount = 0
document.body.addEventListener('keyup', tripleCtrlHandler)

function mouseupEventHandler(evt) {
  var el = evt.target
  var newSelection = window.getSelection().toString()

  // app shutdown
  if (!config.appActive) {
    content.isShow = false
    return
  }

  // if clicking inside the panel then do nothing
  do {
    if ((' ' + el.className + ' ').indexOf(' saladict-panel ') > -1) {
      return
    }
    el = el.parentNode
  } while (el)

  if (content.isPinned) {
    if (newSelection) {
      content.pageStatus.selection = newSelection
      content.$broadcast('search', newSelection)
    }
    return
  }

  // empty selection
  if (!newSelection) {
    content.isShow = false
    return
  }

  // Chinese or English Only options
  if ((config.chineseMode && !isContainChinese(newSelection)) &&
      (config.englishMode && !isContainEnglish(newSelection))) {
    content.isShow = false
    return
  }

  // update status, shared
  content.pageStatus.selection = newSelection
  // calculate popup icon position
  var x = evt.clientX
  var y = evt.clientY
  var ww = window.innerWidth
  var wh = window.innerHeight
  //             +-----+
  //             |     |
  //             |     |30px
  //        60px +-----+
  //             | 30px
  //             |
  //       40px  |
  //     +-------+
  // cursor
  content.pageStatus.iconLeft = ww - x > 40 + 30 ? x + 40 : x - 50
  content.pageStatus.iconTop = y > 60 ? y - 60 : y + 40

  // show main panel
  content.isShow = true

  // show icon & panel accordingly
  var isIconHidden = true
  var isPanelHidden = true
  if (config.mode === 'icon') {
    isIconHidden = false
  } else if (config.mode === 'direct') {
    isPanelHidden = false
  } else if (config.mode === 'ctrl') {
    // TODO
  }
  content.$nextTick(function() {
    content.$broadcast('icon-hide', isIconHidden)
    content.$broadcast('panel-hide', isPanelHidden)
  })
}

var tripleCtrlTimeout
function tripleCtrlHandler(e) {
  if (e.keyCode === 17) {
    if (++tripleCtrlCount >= 3) {
      // triple!
      content.pageStatus.selection = window.getSelection().toString()
      content.pageStatus.iconLeft = (window.innerWidth - 400) / 2 - 40
      content.pageStatus.iconTop = window.innerHeight / 3
      content.isShow = true
      content.$nextTick(function() {
        content.$broadcast('icon-hide', true)
        content.$broadcast('panel-hide', false, 'focus')
      })
    } else {
      clearTimeout(tripleCtrlTimeout)
      tripleCtrlTimeout = setTimeout(function() {
        tripleCtrlCount = 0
      }, 500)
    }
  }
}

function setConfig(response) {
  Object.keys(response).forEach(function(k) {
    if (response[k] !== void(0)) {
      config[k] = response[k]
    }
  })
}

function isContainChinese(text) {
  return /[\u4e00-\u9fa5]/.test(text)
}

function isContainEnglish(text) {
  return /[a-z,A-Z]/.test(text)
}

/* start-test-block */
module.exports = {
  mouseupEventHandler: mouseupEventHandler,
  setConfig: setConfig,
  config: config,
  pageStatus: pageStatus
}
/* end-test-block */
<commit_msg>Fix selection valid check<commit_after>'use strict'

var utils = require('../utils')
var Vue = require('vue')
Vue.config.silent = true

/* start-debug-block */
Vue.config.silent = false
Vue.config.debug = true
/* end-debug-block */

// default config
var config = {
  appActive: true,

  mode: 'icon',
  // icon: show pop icon first
  // direct: show panel directly
  // ctrl: TODO show panel when double click ctrl + selection not empty

  // show panel when triple press ctrl
  tripleCtrl: true,

  chineseMode: true,
  englishMode: true
}

// get user config
utils
  .sendMessage({
    msg:'grab',
    items: Object.keys(config)
  })
  .then(function(response) {
    if (response.msg === 'success') {
      setConfig(response.data)
    }
  })

// when user save config on popup panel,
// appStateChanged is triggered
chrome.runtime.onMessage.addListener(
  function (request, sender, sendResponse) {
    if (request.msg === 'appStateChanged') {
      setConfig(request.data)
    }
  })

// inject component
var content = new Vue(require('./main'))
content.$mount().$before(document.body.firstChild)

// listen to click
document.body.addEventListener('mouseup', mouseupEventHandler)

// listen to triple ctrl keypress
var tripleCtrlCount = 0
document.body.addEventListener('keyup', tripleCtrlHandler)

function mouseupEventHandler(evt) {
  var el = evt.target
  var newSelection = window.getSelection().toString()

  // app shutdown
  if (!config.appActive) {
    content.isShow = false
    return
  }

  // if clicking inside the panel then do nothing
  do {
    if ((' ' + el.className + ' ').indexOf(' saladict-panel ') > -1) {
      return
    }
    el = el.parentNode
  } while (el)

  if (content.isPinned) {
    if (isValid(newSelection)) {
      content.pageStatus.selection = newSelection
      content.$broadcast('search', newSelection)
    }
    return
  }

  if (!isValid(newSelection)) {
    content.isShow = false
    return
  }

  // update status, shared
  content.pageStatus.selection = newSelection
  // calculate popup icon position
  var x = evt.clientX
  var y = evt.clientY
  var ww = window.innerWidth
  var wh = window.innerHeight
  //             +-----+
  //             |     |
  //             |     |30px
  //        60px +-----+
  //             | 30px
  //             |
  //       40px  |
  //     +-------+
  // cursor
  content.pageStatus.iconLeft = ww - x > 40 + 30 ? x + 40 : x - 50
  content.pageStatus.iconTop = y > 60 ? y - 60 : y + 40

  // show main panel
  content.isShow = true

  // show icon & panel accordingly
  var isIconHidden = true
  var isPanelHidden = true
  if (config.mode === 'icon') {
    isIconHidden = false
  } else if (config.mode === 'direct') {
    isPanelHidden = false
  } else if (config.mode === 'ctrl') {
    // TODO
  }
  content.$nextTick(function() {
    content.$broadcast('icon-hide', isIconHidden)
    content.$broadcast('panel-hide', isPanelHidden)
  })
}

var tripleCtrlTimeout
function tripleCtrlHandler(e) {
  if (e.keyCode === 17) {
    if (++tripleCtrlCount >= 3) {
      // triple!
      var newSelection = window.getSelection().toString()
      if (isValid(newSelection)) {
        content.pageStatus.selection = newSelection
      } else {
        content.pageStatus.selection = ''
      }
      content.pageStatus.iconLeft = (window.innerWidth - 400) / 2 - 40
      content.pageStatus.iconTop = window.innerHeight / 3
      content.isShow = true
      content.$nextTick(function() {
        content.$broadcast('icon-hide', true)
        content.$broadcast('panel-hide', false, 'focus')
      })
    } else {
      clearTimeout(tripleCtrlTimeout)
      tripleCtrlTimeout = setTimeout(function() {
        tripleCtrlCount = 0
      }, 500)
    }
  }
}

function setConfig(response) {
  Object.keys(response).forEach(function(k) {
    if (response[k] !== void(0)) {
      config[k] = response[k]
    }
  })
}

function isContainChinese(text) {
  return /[\u4e00-\u9fa5]/.test(text)
}

function isContainEnglish(text) {
  return /[a-zA-Z]/.test(text)
}

function isValid(text) {
  // empty selection
  if (!text) return false

  // Chinese or English Only options
  if (config.chineseMode && isContainChinese(text)) return true
  if (config.englishMode && isContainEnglish(text)) return true

  return false
}

/* start-test-block */
module.exports = {
  mouseupEventHandler: mouseupEventHandler,
  setConfig: setConfig,
  config: config,
  pageStatus: pageStatus
}
/* end-test-block */
<|endoftext|>


<commit_before>var securityModule = require(__base + '/modules/module-security');

var webhookPath = "/webhook/facebook/";

module.exports = function(app)
{
    app.get(webhookPath, securityModule.ensureAuthorizedFacebook, function(req, res)
    {
        var facebookReturnValue = req.query['hub.challenge'];
         return res.status(200).send(facebookReturnValue);
    });

    app.post(webhookPath, function(req,res)
    {
        var data = req.body;
        if(!(data && data.object == "page"))
        {
            return res.status(400).send("object 'page' not found");
        }

        data.entry.forEach(function(entry)
        {
            var pageID = entry.id;
            var eventTime = entry.time;

            data.messaging.forEach(function(event)
            {
                if(event.message)
                {
                    console.log(event.message);
                }
            });
        });

    });
}

<commit_msg>ajuetes no fluxo de menagens<commit_after>var securityModule = require(__base + '/modules/module-security');

var webhookPath = "/webhook/facebook/";

module.exports = function(app)
{
    app.get(webhookPath, securityModule.ensureAuthorizedFacebook, function(req, res)
    {
        var facebookReturnValue = req.query['hub.challenge'];
         return res.status(200).send(facebookReturnValue);
    });

    app.post(webhookPath, function(req,res)
    {
        var data = req.body;
        if(!(data && data.object == "page"))
        {
            return res.status(400).send("object 'page' not found");
        }

        data.entry.array.forEach(function(entry)
        {
            var pageID = entry.id;
            var eventTime = entry.time;

            /*data.messaging.forEach(function(event)
            {
                if(event.message)
                {
                    console.log(event.message);
                }
            });*/
        });

        return res.status(200);

    });
}

<|endoftext|>


<commit_before>class Palette {
  constructor() {
    this._availableActions = {
      video: false,
      upload: false,
      input: false,
    };

    this._currentAction = false;

    this._ui = {
      vars: {
        size: 150,
        maxSamples: 5,
      },
      elements: {},
      events: {},
    };
  }

  init() {
    const promises = [];

    this.initUI();

    promises.push(this.initActions());

    return Promise.all(promises);
  }

  getAvailableActions() {
    return this._availableActions;
  }

  initActions() {
    const promises = [];

    promises.push(this.initVideoAction()
      .then(result => {
        this._availableActions.video = result;
      })
      .catch(err => {
        this._availableActions.video = false;
      }));

    promises.push(this.initUploadAction().then(result => {
      this._availableActions.upload = result;
    }));

    promises.push(this.initInputAction().then(result => {
      this._availableActions.input = result;
    }));

    return Promise.all(promises).then(() => {
      let numDisabled = 0;

      if (!this._availableActions.video) {
        this._ui.elements.actionContainer.removeChild(this._ui.elements.videoContainer);
        numDisabled++;
      } else {
        this._ui.elements.video.src = window.URL.createObjectURL(this._availableActions.video);
        this._ui.elements.video.onloadedmetadata = () => {
          this._ui.elements.video.play();

          const previewSize = this._ui.elements.video.offsetWidth;

          let biggestSide;
          let smallestSide;
          let aspectRatio;

          if (this._ui.elements.video.videoHeight > this._ui.elements.video.videoWidth) {
            biggestSide = 'height';
            smallestSide = 'width';
            aspectRatio = this._ui.elements.video.videoHeight / this._ui.elements.video.videoWidth;
          } else {
            biggestSide = 'width';
            smallestSide = 'height';
            aspectRatio = this._ui.elements.video.videoWidth / this._ui.elements.video.videoHeight;
          }

          const offset =
            Math.abs(this._ui.elements.video.videoHeight - this._ui.elements.video.videoWidth) / 2;

          this._ui.elements.video.style[biggestSide] =
            this._ui.elements.canvas.style[biggestSide] = `${previewSize * aspectRatio}px`;

          this._ui.elements.canvas[biggestSide] = previewSize * aspectRatio;
          this._ui.elements.canvas[smallestSide] = previewSize;

          this._ui.elements.videoButton.addEventListener('click', () => {
            this._ui.elements.videoButton.classList.add('hide');
            this._ui.elements.canvasContext.drawImage(this._ui.elements.video,
              biggestSide === 'height' ? 0 : offset,
              biggestSide === 'width' ? 0 : offset,
              biggestSide === 'height' ?
                this._ui.elements.video.videoWidth :
                this._ui.elements.video.videoHeight,
              biggestSide === 'height' ?
                this._ui.elements.video.videoWidth :
                this._ui.elements.video.videoHeight,
              0,
              0,
              previewSize,
              previewSize
            );
            const pixel = this._ui.elements.canvasContext
              .getImageData(previewSize / 2, previewSize / 2, 1, 1)
              .data;

            // pixel[0] = getRandom(0, 255);
            // pixel[1] = getRandom(0, 255);
            // pixel[2] = getRandom(0, 255);

            this.pushSample(pixel);
          });
        };
      }

      if (!this._availableActions.upload) {
        this._ui.elements.actionContainer.removeChild(this._ui.elements.uploadContainer);
        numDisabled++;
      }
      if (!this._availableActions.input) {
        this._ui.elements.actionContainer.removeChild(this._ui.elements.inputContainer);
        numDisabled++;
      }

      if (numDisabled > 1) {
        this._ui.elements.btnSource.parentNode.removeChild(this._ui.elements.btnSource);
      }
    });
  }

  initVideoAction() {
    return Promise.resolve().then(() => {
      if (!navigator || !navigator.mediaDevices) {
        return false;
      }

      return navigator.mediaDevices.getUserMedia({
        audio: false,
        video: {
          facingMode: 'environment',
        },
      });
    });
  }

  initUploadAction() {
    return Promise.resolve().then(() => !!FileReader);
  }

  initInputAction() {
    return Promise.resolve().then(() => true);
  }

  initUI() {
    this._ui.elements.video = document.querySelector('video');
    this._ui.elements.videoContainer = document.querySelector('.video-container');
    this._ui.elements.uploadContainer = document.querySelector('.upload-container');
    this._ui.elements.inputContainer = document.querySelector('.input-container');
    this._ui.elements.videoButton = this._ui.elements.videoContainer.querySelector('button');
    this._ui.elements.canvas = document.querySelector('canvas');
    this._ui.elements.canvasContext = this._ui.elements.canvas.getContext('2d');
    this._ui.elements.sampleContainer = document.querySelector('.sample-container');
    this._ui.elements.samplesContainer = document.querySelector('.samples-container');
    this._ui.elements.sampleRGB = document.querySelector('.sample-rgb');
    this._ui.elements.sampleHex = document.querySelector('.sample-hex');
    this._ui.elements.fileUpload = document.querySelector('.file-upload');
    this._ui.elements.actionContainer = document.querySelector('.action-container');
    this._ui.elements.btnSource = document.querySelector('.btn--source');
    this._ui.elements.inputForm = document.querySelector('.input-container form');

    this._ui.elements.inputForm.addEventListener('submit', event => {
      event.preventDefault();
      const pixel = event.target.colour.value.split(',').map(col => parseInt(col.trim(), 10));
      this.pushSample(pixel);
    });

    this._ui.elements.fileUpload.addEventListener('change', event => {
      const data = event.target.files[0];
      const reader = new FileReader();
      reader.addEventListener('load', () => {
        const image = new Image();
        image.src = reader.result;

        this._ui.elements.canvasContext.drawImage(image, 0, 0);

        const pixel = this._ui.elements.canvasContext
          .getImageData(
            this._ui.elements.canvas.width / 2,
            this._ui.elements.canvas.height / 2,
            1,
            1
          )
          .data;

        this.pushSample(pixel);
      });
      reader.readAsDataURL(data);
    });

    this._ui.elements.btnSource.addEventListener('click', event => {
      event.preventDefault();

      this._ui.elements.actionContainer.appendChild(this._ui.elements.actionContainer.children[0]);
      this._ui.elements.video.play();
    });
  }

  pushSample(pixel) {
    const sample = this.createSample(pixel);

    sample.addEventListener('click', event => {
      event.preventDefault();

      if (sample.parentNode === this._ui.elements.samplesContainer) {
        const mainSample = this._ui.elements.sampleContainer.firstChild;
        const mainSampleClassName = mainSample.className;

        this._ui.elements.samplesContainer.insertBefore(mainSample, sample);
        this._ui.elements.sampleContainer.appendChild(sample);

        mainSample.className = sample.className;
        sample.className = mainSampleClassName;

        this.updateSampleData([
          sample.dataset.r,
          sample.dataset.g,
          sample.dataset.b,
        ]);
      } else if (sample.parentNode === this._ui.elements.sampleContainer) {
        if (sample.classList.contains('sample--fullscreen')) {
          sample.classList.remove('sample--fullscreen');
        } else {
          sample.classList.add('sample--fullscreen');
        }
      }
    });

    const currentSamples = [];
    for (let i = 0; i < this._ui.elements.samplesContainer.length; i++) {
      currentSamples.push(this._ui.elements.samplesContainer[i]);
    }

    const currentSample = this._ui.elements.sampleContainer.firstChild;
    if (currentSample) {
      this._ui.elements.samplesContainer
        .insertBefore(currentSample, currentSamples[0]);
    }
    this._ui.elements.sampleContainer.appendChild(sample);

    if (this._ui.elements.samplesContainer.children.length > this._ui.vars.maxSamples) {
      this._ui.elements.samplesContainer
        .removeChild(this._ui.elements.samplesContainer.children[this._ui.vars.maxSamples]);
    }

    this.updateSampleData(pixel);

    requestAnimationFrame(() => {
      const sourceContainerRect = this._ui.elements.videoContainer.getBoundingClientRect();
      const targetContainerRect = this._ui.elements.sampleContainer.getBoundingClientRect();

      let scale = sourceContainerRect.width / targetContainerRect.width;

      let x = sourceContainerRect.left
        - targetContainerRect.left
        + (sourceContainerRect.width - targetContainerRect.width) / 2;

      let y = sourceContainerRect.top
        - targetContainerRect.top
        + (sourceContainerRect.height - targetContainerRect.height) / 2;

      sample.style.transform =
        `scale(${scale}) translateX(${x / scale}px) translateY(${y / scale}px)`;

      if (currentSample) {
        const currentTargetContainerRect =
          this._ui.elements.samplesContainer.children[0].getBoundingClientRect();

        scale = targetContainerRect.width / currentTargetContainerRect.width;

        x = targetContainerRect.left
          - currentTargetContainerRect.left
          + (targetContainerRect.width - currentTargetContainerRect.width) / 2;

        y = targetContainerRect.top
          - currentTargetContainerRect.top
          + (targetContainerRect.height - currentTargetContainerRect.height) / 2;

        currentSample.style.transform =
          `scale(${scale}) translateX(${x / scale}px) translateY(${y / scale}px)`;

        currentSample.style.color =
          `rgb(
            ${currentSamples[0].dataset.r},
            ${currentSamples[0].dataset.g},
            ${currentSamples[0].dataset.b}
          )`;
        currentSamples[this._ui.vars.maxSamples - 2].classList.add('sample--last');
      }

      const currentSamplesWidth = currentSamples[0].offsetWidth;
      currentSamples.forEach(samp => {
        samp.style.transform = `translateX(-${currentSamplesWidth}px)`;
      });

      requestAnimationFrame(() => {
        sample.style.transition = 'transform 0.3s ease-in-out 0s';
        sample.style.transform = '';

        if (currentSample) {
          currentSample.style.transition = 'transform 0.3s ease-in-out 0s';
          currentSample.style.transform = '';
        }

        currentSamples.forEach(samp => {
          samp.style.transition = 'transform 0.3s ease-in-out 0s';
          samp.style.transform = '';
        });
      });
    });

    sample.addEventListener('transitionend', event => {
      sample.style.transition = '';
    });
  }

  createSample(pixel) {
    const sample = document.createElement('div');
    sample.className = 'sample';
    sample.style.backgroundColor = `rgb(${pixel[0]}, ${pixel[1]}, ${pixel[2]})`;
    sample.dataset.r = pixel[0];
    sample.dataset.g = pixel[1];
    sample.dataset.b = pixel[2];

    return sample;
  }

  updateSampleData(pixel) {
    this._ui.elements.sampleRGB.textContent = `rgb(${pixel[0]}, ${pixel[1]}, ${pixel[2]})`;
    this._ui.elements.sampleHex.textContent = `rgb(${pixel[0]}, ${pixel[1]}, ${pixel[2]})`;
  }
}

const paletteApp = new Palette();

paletteApp.init().then(() => {
  console.log('done', paletteApp.getAvailableActions());
});
<commit_msg>animate paletter<commit_after>class Palette {
  constructor() {
    this._availableActions = {
      video: false,
      upload: false,
      input: false,
    };

    this._currentAction = false;

    this._ui = {
      vars: {
        size: 150,
        maxSamples: 5,
      },
      elements: {},
      events: {},
    };
  }

  init() {
    const promises = [];

    this.initUI();

    promises.push(this.initActions());

    return Promise.all(promises);
  }

  getAvailableActions() {
    return this._availableActions;
  }

  initActions() {
    const promises = [];

    promises.push(this.initVideoAction()
      .then(result => {
        this._availableActions.video = result;
      })
      .catch(err => {
        this._availableActions.video = false;
      }));

    promises.push(this.initUploadAction().then(result => {
      this._availableActions.upload = result;
    }));

    promises.push(this.initInputAction().then(result => {
      this._availableActions.input = result;
    }));

    return Promise.all(promises).then(() => {
      let numDisabled = 0;

      if (!this._availableActions.video) {
        this._ui.elements.actionContainer.removeChild(this._ui.elements.videoContainer);
        numDisabled++;
      } else {
        this._ui.elements.video.src = window.URL.createObjectURL(this._availableActions.video);
        this._ui.elements.video.onloadedmetadata = () => {
          this._ui.elements.video.play();

          const previewSize = this._ui.elements.video.offsetWidth;

          let biggestSide;
          let smallestSide;
          let aspectRatio;

          if (this._ui.elements.video.videoHeight > this._ui.elements.video.videoWidth) {
            biggestSide = 'height';
            smallestSide = 'width';
            aspectRatio = this._ui.elements.video.videoHeight / this._ui.elements.video.videoWidth;
          } else {
            biggestSide = 'width';
            smallestSide = 'height';
            aspectRatio = this._ui.elements.video.videoWidth / this._ui.elements.video.videoHeight;
          }

          const offset =
            Math.abs(this._ui.elements.video.videoHeight - this._ui.elements.video.videoWidth) / 2;

          this._ui.elements.video.style[biggestSide] =
            this._ui.elements.canvas.style[biggestSide] = `${previewSize * aspectRatio}px`;

          this._ui.elements.canvas[biggestSide] = previewSize * aspectRatio;
          this._ui.elements.canvas[smallestSide] = previewSize;

          this._ui.elements.videoButton.addEventListener('click', () => {
            this._ui.elements.videoButton.classList.add('hide');
            this._ui.elements.canvasContext.drawImage(this._ui.elements.video,
              biggestSide === 'height' ? 0 : offset,
              biggestSide === 'width' ? 0 : offset,
              biggestSide === 'height' ?
                this._ui.elements.video.videoWidth :
                this._ui.elements.video.videoHeight,
              biggestSide === 'height' ?
                this._ui.elements.video.videoWidth :
                this._ui.elements.video.videoHeight,
              0,
              0,
              previewSize,
              previewSize
            );
            const pixel = this._ui.elements.canvasContext
              .getImageData(previewSize / 2, previewSize / 2, 1, 1)
              .data;

            // pixel[0] = getRandom(0, 255);
            // pixel[1] = getRandom(0, 255);
            // pixel[2] = getRandom(0, 255);

            this.pushSample(pixel);
          });
        };
      }

      if (!this._availableActions.upload) {
        this._ui.elements.actionContainer.removeChild(this._ui.elements.uploadContainer);
        numDisabled++;
      }
      if (!this._availableActions.input) {
        this._ui.elements.actionContainer.removeChild(this._ui.elements.inputContainer);
        numDisabled++;
      }

      if (numDisabled > 1) {
        this._ui.elements.btnSource.parentNode.removeChild(this._ui.elements.btnSource);
      }
    });
  }

  initVideoAction() {
    return Promise.resolve().then(() => {
      if (!navigator || !navigator.mediaDevices) {
        return false;
      }

      return navigator.mediaDevices.getUserMedia({
        audio: false,
        video: {
          facingMode: 'environment',
        },
      });
    });
  }

  initUploadAction() {
    return Promise.resolve().then(() => !!FileReader);
  }

  initInputAction() {
    return Promise.resolve().then(() => true);
  }

  initUI() {
    this._ui.elements.video = document.querySelector('video');
    this._ui.elements.videoContainer = document.querySelector('.video-container');
    this._ui.elements.uploadContainer = document.querySelector('.upload-container');
    this._ui.elements.inputContainer = document.querySelector('.input-container');
    this._ui.elements.videoButton = this._ui.elements.videoContainer.querySelector('button');
    this._ui.elements.canvas = document.querySelector('canvas');
    this._ui.elements.canvasContext = this._ui.elements.canvas.getContext('2d');
    this._ui.elements.sampleContainer = document.querySelector('.sample-container');
    this._ui.elements.samplesContainer = document.querySelector('.samples-container');
    this._ui.elements.sampleRGB = document.querySelector('.sample-rgb');
    this._ui.elements.sampleHex = document.querySelector('.sample-hex');
    this._ui.elements.fileUpload = document.querySelector('.file-upload');
    this._ui.elements.actionContainer = document.querySelector('.action-container');
    this._ui.elements.btnSource = document.querySelector('.btn--source');
    this._ui.elements.inputForm = document.querySelector('.input-container form');

    this._ui.elements.inputForm.addEventListener('submit', event => {
      event.preventDefault();
      const pixel = event.target.colour.value.split(',').map(col => parseInt(col.trim(), 10));
      this.pushSample(pixel);
    });

    this._ui.elements.fileUpload.addEventListener('change', event => {
      const data = event.target.files[0];
      const reader = new FileReader();
      reader.addEventListener('load', () => {
        const image = new Image();
        image.src = reader.result;

        this._ui.elements.canvasContext.drawImage(image, 0, 0);

        const pixel = this._ui.elements.canvasContext
          .getImageData(
            this._ui.elements.canvas.width / 2,
            this._ui.elements.canvas.height / 2,
            1,
            1
          )
          .data;

        this.pushSample(pixel);
      });
      reader.readAsDataURL(data);
    });

    this._ui.elements.btnSource.addEventListener('click', event => {
      event.preventDefault();

      this._ui.elements.actionContainer.appendChild(this._ui.elements.actionContainer.children[0]);
      this._ui.elements.video.play();
    });
  }

  pushSample(pixel) {
    const sample = this.createSample(pixel);

    sample.addEventListener('click', event => {
      event.preventDefault();

      if (sample.parentNode === this._ui.elements.samplesContainer) {
        const mainSample = this._ui.elements.sampleContainer.firstChild;
        const mainSampleClassName = mainSample.className;

        this._ui.elements.samplesContainer.insertBefore(mainSample, sample);
        this._ui.elements.sampleContainer.appendChild(sample);

        mainSample.className = sample.className;
        sample.className = mainSampleClassName;

        this.updateSampleData([
          sample.dataset.r,
          sample.dataset.g,
          sample.dataset.b,
        ]);
      } else if (sample.parentNode === this._ui.elements.sampleContainer) {
        if (sample.classList.contains('sample--fullscreen')) {
          sample.classList.remove('sample--fullscreen');
        } else {
          sample.classList.add('sample--fullscreen');
        }
      }
    });

    const currentSamples = [];
    for (let i = 0; i < this._ui.elements.samplesContainer.children.length; i++) {
      currentSamples.push(this._ui.elements.samplesContainer.children[i]);
    }

    const currentSample = this._ui.elements.sampleContainer.firstChild;
    if (currentSample) {
      this._ui.elements.samplesContainer
        .insertBefore(currentSample, currentSamples[0]);
    }
    this._ui.elements.sampleContainer.appendChild(sample);

    if (this._ui.elements.samplesContainer.children.length > this._ui.vars.maxSamples) {
      this._ui.elements.samplesContainer
        .removeChild(this._ui.elements.samplesContainer.children[this._ui.vars.maxSamples]);
    }

    this.updateSampleData(pixel);

    requestAnimationFrame(() => {
      const sourceContainerRect = this._ui.elements.videoContainer.getBoundingClientRect();
      const targetContainerRect = this._ui.elements.sampleContainer.getBoundingClientRect();

      let scale = sourceContainerRect.width / targetContainerRect.width;

      let x = sourceContainerRect.left
        - targetContainerRect.left
        + (sourceContainerRect.width - targetContainerRect.width) / 2;

      let y = sourceContainerRect.top
        - targetContainerRect.top
        + (sourceContainerRect.height - targetContainerRect.height) / 2;

      sample.style.transform =
        `scale(${scale}) translateX(${x / scale}px) translateY(${y / scale}px)`;

      if (currentSample) {
        const currentTargetContainerRect =
          this._ui.elements.samplesContainer.children[0].getBoundingClientRect();

        scale = targetContainerRect.width / currentTargetContainerRect.width;

        x = targetContainerRect.left
          - currentTargetContainerRect.left
          + (targetContainerRect.width - currentTargetContainerRect.width) / 2;

        y = targetContainerRect.top
          - currentTargetContainerRect.top
          + (targetContainerRect.height - currentTargetContainerRect.height) / 2;

        currentSample.style.transform =
          `scale(${scale}) translateX(${x / scale}px) translateY(${y / scale}px)`;

        currentSample.style.color =
          `rgb(
            ${currentSamples[0].dataset.r},
            ${currentSamples[0].dataset.g},
            ${currentSamples[0].dataset.b}
          )`;
        currentSamples[this._ui.vars.maxSamples - 2].classList.add('sample--last');
      }

      const currentSamplesWidth = currentSamples[0].offsetWidth;
      currentSamples.forEach(samp => {
        samp.style.transform = `translateX(-${currentSamplesWidth}px)`;
      });

      requestAnimationFrame(() => {
        sample.style.transition = 'transform 0.3s ease-in-out 0s';
        sample.style.transform = '';

        if (currentSample) {
          currentSample.style.transition = 'transform 0.3s ease-in-out 0s';
          currentSample.style.transform = '';
        }

        currentSamples.forEach(samp => {
          samp.style.transition = 'transform 0.3s ease-in-out 0s';
          samp.style.transform = '';
        });
      });
    });

    sample.addEventListener('transitionend', event => {
      sample.style.transition = '';
    });
  }

  createSample(pixel) {
    const sample = document.createElement('div');
    sample.className = 'sample';
    sample.style.backgroundColor = `rgb(${pixel[0]}, ${pixel[1]}, ${pixel[2]})`;
    sample.dataset.r = pixel[0];
    sample.dataset.g = pixel[1];
    sample.dataset.b = pixel[2];

    return sample;
  }

  updateSampleData(pixel) {
    this._ui.elements.sampleRGB.textContent = `rgb(${pixel[0]}, ${pixel[1]}, ${pixel[2]})`;
    this._ui.elements.sampleHex.textContent = `rgb(${pixel[0]}, ${pixel[1]}, ${pixel[2]})`;
  }
}

const paletteApp = new Palette();

paletteApp.init().then(() => {
  console.log('done', paletteApp.getAvailableActions());
});
<|endoftext|>


<commit_before>import React, { useState } from "react"
import { Link } from "gatsby"
import '../../styles/header.scss'
import "../../styles/background.scss"

const cycleVisualization = (current) =>{
    if(current === 'square'){
        localStorage.setItem('visualization', 'Krzywinski');
        return 'Krzywinski'
    }
    else if(current === 'Krzywinski'){
        localStorage.setItem('visualization', 'square');
        return 'square'
    }
    return 'square'
}

const Header = (props) => {
    const loadedVisualization = localStorage.getItem('visualization') || 'square'
    const [expand,setExpand] = useState(false)
    const [visualization, setVisualization] =  useState(loadedVisualization)
    const mainDigits = ['3.',1,4,1,5,9]

    return (
        <>

                {mainDigits.map((d,i)=>(
setVisualization(cycleVisualization(visualization))}><p className={`digit${parseInt(d)}`}>{d}

))}

setExpand(!expand)}>=

<Link to="/">Home</Link>

<Link to="/projects">Projects</Link>

<Link to="/tech">Technologies</Link>

setExpand(!expand)}>=

<Link to="/">Home</Link>

<Link to="/projects">Projects</Link>

<Link to="/tech">Technologies</Link>

        </>
    )
}

export default Header<commit_msg>remove window dependency for the build<commit_after>import React, { useState } from "react"
import { Link } from "gatsby"
import '../../styles/header.scss'
import "../../styles/background.scss"

const cycleVisualization = (current) =>{
    if(current === 'square'){
        window.localStorage.setItem('visualization', 'Krzywinski');
        return 'Krzywinski'
    }
    else if(current === 'Krzywinski'){
        window.localStorage.setItem('visualization', 'square');
        return 'square'
    }
    return 'square'
}

const Header = (props) => {
    const loadedVisualization = window? window.localStorage.getItem('visualization') || 'square' : 'square'
    const [expand,setExpand] = useState(false)
    const [visualization, setVisualization] =  useState(loadedVisualization)
    const mainDigits = ['3.',1,4,1,5,9]

    return (
        <>

                {mainDigits.map((d,i)=>(
setVisualization(cycleVisualization(visualization))}><p className={`digit${parseInt(d)}`}>{d}

))}

setExpand(!expand)}>=

<Link to="/">Home</Link>

<Link to="/projects">Projects</Link>

<Link to="/tech">Technologies</Link>

setExpand(!expand)}>=

<Link to="/">Home</Link>

<Link to="/projects">Projects</Link>

<Link to="/tech">Technologies</Link>

        </>
    )
}

export default Header<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Relay from 'react-relay';
import { Grid, Row, Col, Button, ButtonToolbar, Modal } from 'react-bootstrap';
import _ from 'lodash';
import EntryForm from './EntryForm';
import AddEntryMutation from './mutations/AddEntryMutation';

export class AddEntryForm extends Component {

    constructor(props) {
        super(props);
        this.state = {
            show: props.show,
            entry: props.entry
        }

        this.handleDone = this.handleDone.bind(this);
        this.showForm = this.showForm.bind(this);
    }

    handleDone(entry, cb) {
        var viewer = this.props.viewer;
        var onSuccess = () => {
            this.setState({show: false});
            cb();
        }
        this.props.relay.commitUpdate(
            new AddEntryMutation({viewer, entry}),
            {onSuccess}
        );
    }

    showForm(type) {
        this.setState({
            show: true,
            entry: {
                type
            }
        })
    }

    render() {
        return (
            <Grid>
                <Row>
                    <Col xs={12}>
                        <ButtonToolbar className='add-entry-form'>
                            <Button onClick={_.partial(this.showForm, 'text')}><Glyphicon glyph="pencil" /> Words</Button>
                            <Button onClick={_.partial(this.showForm, 'video')}><Glyphicon glyph="film" /> Video</Button>
                            <Button onClick={_.partial(this.showForm, 'image')}><Glyphicon glyph="picture" /> Photo</Button>
                            <Modal
                                show={this.state.show}
                                onHide={() => this.setState({ show: false })}
                                backdrop={true}
                                bsSize="large"
                            >
                                <Modal.Header closeButton>
                                    <Modal.Title>New Entry</Modal.Title>
                                </Modal.Header>
                                <Modal.Body>
                                    <EntryForm topics={this.props.viewer.topics} done={this.handleDone} entry={this.state.entry} />
                                </Modal.Body>
                            </Modal>
                        </ButtonToolbar>
                    </Col>
                </Row>
            </Grid>
        );
    }
};
AddEntryForm.propTypes = {
    show: React.PropTypes.bool,
    entry: React.PropTypes.object
}
AddEntryForm.defaultProps = {
    show: false,
    entry: {}
}

export const AddEntryFormContainer = Relay.createContainer(AddEntryForm, {
    fragments: {
        viewer: () => Relay.QL`
            fragment on Viewer {
                id
                topics {
                    type,
                    name
                }
                ${AddEntryMutation.getFragment('viewer')}
            }
        `,
    }
});
<commit_msg>Add Glyphicon import<commit_after>import React, { Component } from 'react';
import Relay from 'react-relay';
import { Grid, Row, Col, Button, ButtonToolbar, Modal, Glyphicon } from 'react-bootstrap';
import _ from 'lodash';
import EntryForm from './EntryForm';
import AddEntryMutation from './mutations/AddEntryMutation';

export class AddEntryForm extends Component {

    constructor(props) {
        super(props);
        this.state = {
            show: props.show,
            entry: props.entry
        }

        this.handleDone = this.handleDone.bind(this);
        this.showForm = this.showForm.bind(this);
    }

    handleDone(entry, cb) {
        var viewer = this.props.viewer;
        var onSuccess = () => {
            this.setState({show: false});
            cb();
        }
        this.props.relay.commitUpdate(
            new AddEntryMutation({viewer, entry}),
            {onSuccess}
        );
    }

    showForm(type) {
        this.setState({
            show: true,
            entry: {
                type
            }
        })
    }

    render() {
        return (
            <Grid>
                <Row>
                    <Col xs={12}>
                        <ButtonToolbar className='add-entry-form'>
                            <Button onClick={_.partial(this.showForm, 'text')}><Glyphicon glyph="pencil" /> Words</Button>
                            <Button onClick={_.partial(this.showForm, 'video')}><Glyphicon glyph="film" /> Video</Button>
                            <Button onClick={_.partial(this.showForm, 'image')}><Glyphicon glyph="picture" /> Photo</Button>
                            <Modal
                                show={this.state.show}
                                onHide={() => this.setState({ show: false })}
                                backdrop={true}
                                bsSize="large"
                            >
                                <Modal.Header closeButton>
                                    <Modal.Title>New Entry</Modal.Title>
                                </Modal.Header>
                                <Modal.Body>
                                    <EntryForm topics={this.props.viewer.topics} done={this.handleDone} entry={this.state.entry} />
                                </Modal.Body>
                            </Modal>
                        </ButtonToolbar>
                    </Col>
                </Row>
            </Grid>
        );
    }
};
AddEntryForm.propTypes = {
    show: React.PropTypes.bool,
    entry: React.PropTypes.object
}
AddEntryForm.defaultProps = {
    show: false,
    entry: {}
}

export const AddEntryFormContainer = Relay.createContainer(AddEntryForm, {
    fragments: {
        viewer: () => Relay.QL`
            fragment on Viewer {
                id
                topics {
                    type,
                    name
                }
                ${AddEntryMutation.getFragment('viewer')}
            }
        `,
    }
});
<|endoftext|>


<commit_before>$(function(){
    return $.getJSON('/api/v1/user_management/users', function (data) {
      window.users=Object.keys(data)
        .map(n=>{
            return {val:n.split('@')[0]};
        });
    });
});

function generate_category_label(category){
     cat_classes = {
        'Workset': ['primary', 'calendar-plus'],
        'Flowcell': ['success', 'grip-vertical'],
        'Decision': ['info', 'thumbs-up'],
        'Lab': ['succe', 'flask'],
        'Bioinformatics': ['warning', 'laptop-code'],
        'User Communication': ['usr', 'people-arrows'],
        'Administration': ['danger', 'folder-open'],
        'Important': ['imp', 'exclamation-circle'],
        'Deviation': ['devi', 'frown'],
        'Invoicing': ['inv', 'file-invoice-dollar']
    }
    var cat_label = '';
    var categories = category.split(',')
    Object.values(categories).forEach(function(val){
      var cat = val.trim()
      if (Object.keys(cat_classes).indexOf(cat) != -1){
          cat_label += ''+cat+' '+''+" ";
      }
    });
    return cat_label;
}

function get_note_url() {
    // URL for the notes
    if ((typeof notetype !== 'undefined' && notetype == 'lims_step') || ('lims_step' in window && lims_step !== null)){
        note_url='/api/v1/workset_notes/' + lims_step;
    } else if ((typeof notetype !== 'undefined' && notetype == 'flowcell') || ('flowcell_id_reference' in window && flowcell_id_reference!== null)){
        note_url='/api/v1/flowcell_notes/' + flowcell_id_reference;
    } else {
        note_url='/api/v1/running_notes/' + project;
    }
    return note_url;
}

function make_running_note(date, note){
  try {
    var category = '';
    var date = date.replace(/-/g, '/');
    date = date.replace(/\.\d{6}/, '');
    date = new Date(date);
    if (note['note'] != undefined){
        if(date > new Date('2015-01-01')){
          noteText = make_markdown(note['note']);
        } else {
          noteText = '
'+make_project_links(note['note'])+'
';
        }
        datestring = date.toDateString() + ', ' + date.toLocaleTimeString(date);
        var page_to_link = '';
        if(typeof project !== 'undefined'){
          page_to_link = project;
        }
        else if (typeof flowcell!== 'undefined') {
          page_to_link = flowcell;
        }
        else if(typeof workset_name !== 'undefined'){
          page_to_link = workset_name
        }
        note_id = 'running_note_'+page_to_link+'_'+(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(),
                   date.getUTCDate(), date.getHours(), date.getMinutes(), date.getSeconds())/1000);
        if ('category' in note){
            category=generate_category_label(note['category']);
        }
    }
  } catch(e){
    noteText = '
'+make_project_links(note['note'])+'
';
    var datestring = '?';
  }
  var printHyphen =category? ' - ': ' ';
  var panelClass='';
  if (note['category'].includes('Important')) {
    panelClass = 'card-important';
  }
  return '
' +
      '
'+
        ''+note['user']+' - '+
       '' + datestring + '' + printHyphen +category +'

'+noteText+'

';
}

function load_running_notes(wait) {
  // Clear previously loaded notes, if so
  note_url = get_note_url();
  $("#running_notes_panels").empty();
  return $.getJSON(note_url, function(data) {
    if(Object.keys(data).length == 0 || typeof data === 'undefined'){
      $('#running_notes_panels').html('
No running notes found.
');
    } else {
      $.each(data, function(date, note) {
        $('#running_notes_panels').append(make_running_note(date, note));
      });
      check_img_sources($('#running_notes_panels img'));
      count_cards();
    }
  }).fail(function( jqxhr, textStatus, error ) {
      try {
        var response = JSON.parse(jqxhr.responseText);
        var err = response['page_title'];
        var exception = $('
').text(response['error_exception']).html(); // HTML encode string
        var debugging = "
For debugging purposes, we've tried to grab the error that triggered this page for you:
"+
                        '

'+exception+'';
      } catch(e) {
        var err = error+', '+textStatus;
        var debugging = '';
      }
      $('#running_notes_panels').append('
' +
          '
Error Loading Running Notes: '+err+'
' +
          '
Apologies, running notes could not be loaded.' +
          'These problems are usually ' +
          'due to connection problems. Please try again later and report if the problem persists.

'+debugging);
  });
}
function preview_running_notes(){
    var now = new Date();
    $('.todays_date').text(now.toDateString() + ', ' + now.toLocaleTimeString());
    var categories = []
    $('.rn-categ button.active').each(function() {
      categories.push($(this).text().trim());
    });
    var category = generate_category_label(categories.join());
    category = category ? ' - '+ category : category;
    $('#preview_category').html(category);
    var text = $('#new_note_text').val().trim();
    if (text.length > 0) {
        $('#running_note_preview_body').html(make_markdown(text));
        check_img_sources($('#running_note_preview_body img'));
    } else {
        $('#running_note_preview_body').html('
Nothing to preview..
');
    }
    // update textarea height
    $('#new_note_text').css('height', $('#running_note_preview_panel').css('height'));
}
function filter_running_notes(search){
    search=search.toLowerCase();
    $('#running_notes_panels').children().each(function(){
        var header=$(this).children('.card-header').text();
        var note=$(this).children('.card-body').children().text();
        if (header.toLowerCase().indexOf(search) != -1 || note.toLowerCase().indexOf(search) != -1){
            $(this).show();
        }else{
            $(this).hide();
        }
    });
}
//Count rn's of each category and add badge with number to filter dropdown
function count_cards(){
    var cat_cards = {};
    var all = 0;
    $('#running_notes_panels').find('.badge').each(function(){
        var label = $.trim($(this).text());
        all++;
        if (label){
            if (label in cat_cards){
                cat_cards[label]++;
            }else{
                cat_cards[label] = 1;
            }
        }
    });
    $('.btn_count').append('All '+all+'');
    $('#rn_category').next().find('.dropdown-item').each(function(){
        var label = $.trim($(this).text())
        cat_cards['All'] = all;
        if (!cat_cards[label]){
            $(this).parent('li').addClass('d-none');
        }else if (Object.keys(cat_classes).indexOf(label) != -1){
            $(this).prepend(''+cat_cards[label]+'');
        }else{
            $(this).prepend(''+cat_cards[label]+'');
        }
    });
}

//Filter notes
$('#rn_search').keyup(function() {
    var search=$('#rn_search').val();
    filter_running_notes(search);
    $('#rn_category').html(''+
    $('#running_notes_panels').find('.badge').length+'All');
});

//Filter dropdown
$('#rn_category ~ ul > li > button').on('click', function(){
    $('#rn_category').html($(this).html());
    var search = this.lastChild.textContent;
    if (search.includes('All')){
        search = '';
    }
    filter_running_notes(search);
});

// Update the category buttons
$('.rn-categ button').click(function(e){
    e.preventDefault();
    var was_selected = $(this).hasClass('active');
    if(was_selected){
        $(this).removeClass('active');
    }
    else{
        $(this).addClass('active');
    }
    preview_running_notes();
});

//Remove hover text from clicked button
$(document).ready(function(){
      $('[data-toggle="tooltip"]').click(function (){
         $('[data-toggle="tooltip"]').tooltip("hide");
      });
});

// Preview running notes
$('#new_note_text').keyup(preview_running_notes);

// Insert new running note and reload the running notes table
$("#running_notes_form").submit( function(e) {
    e.preventDefault();
    var text = $('#new_note_text').val().trim();
    text = $('
').text(text).html();
    var categories = [];
    $('.rn-categ button.active').each(function() {
      categories.push($(this).text().trim());
    });
    category = categories.join()
    if (text.length == 0) {
        alert("Error: No running note entered.");
        return false;
    }
    if (!$('.rn-categ button.active').text()) {
       if (!confirm("Are you sure that you want to submit without choosing a category?")) {
          return false;
       }
    }

    note_url = get_note_url()
    $('#save_note_button').addClass('disabled').text('Submitting...');
    $.ajax({
      type: 'POST',
      url: note_url,
      dataType: 'json',
      data: {"note": text, "category": category},
      error: function(xhr, textStatus, errorThrown) {
        alert('Error: '+xhr['responseText']+' ('+errorThrown+')');
        $('#save_note_button').removeClass('disabled').text('Submit Running Note');
        console.log(xhr);
        console.log(textStatus);
        console.log(errorThrown);
      },
      success: function(data, textStatus, xhr) {
        // Manually check whether the running note has saved
        note_url=get_note_url()
        $.getJSON(note_url, function(newdata) {
          var newNote = false;
          $.each(newdata, function(date, note) {
            if(data['note'] == note['note']){
              newNote = make_running_note(date, note);
            }
          });
          if(newNote){
            // Enable the submit button again
            $('#save_note_button').removeClass('disabled').text('Submit Running Note');
            // Clear the text box
            $('#new_note_text').val('');
            $('#running_note_preview_body').html('
Nothing to preview..
');
            $('#new_note_text').css('height', $('#running_note_preview_panel').css('height'));
            // Cler the 'no running notes found' box if it's there
            if($('#running_notes_panels').html() == '
No running notes found.
'){
              $('#running_notes_panels .well').slideUp(function(){ $(this).remove(); });
            }
            // Create a new running note and slide it in..
            var now = new Date();
            category=generate_category_label(category);
            var printHyphen =category? ' - ': ' ';
            $('

'+
                  ''+data['user']+' - '+
                  now.toDateString() + ', ' + now.toLocaleTimeString(now)+ printHyphen + category +
                '

'+make_markdown(data['note'])+
                '

').hide().prependTo('#running_notes_panels').slideDown();
            check_img_sources($('#running_notes_panels img'));
          } else {
            alert('Error - Your running note was not saved.');
            $('#save_note_button').removeClass('disabled').text('Submit Running Note');
          }
        });
      }
    });
});
$('#new_note_text').on('focus',function(){$(this).sew({values:window.users})});
<commit_msg>Fix for quotes not displayed on saved running notes<commit_after>$(function(){
    return $.getJSON('/api/v1/user_management/users', function (data) {
      window.users=Object.keys(data)
        .map(n=>{
            return {val:n.split('@')[0]};
        });
    });
});

function generate_category_label(category){
     cat_classes = {
        'Workset': ['primary', 'calendar-plus'],
        'Flowcell': ['success', 'grip-vertical'],
        'Decision': ['info', 'thumbs-up'],
        'Lab': ['succe', 'flask'],
        'Bioinformatics': ['warning', 'laptop-code'],
        'User Communication': ['usr', 'people-arrows'],
        'Administration': ['danger', 'folder-open'],
        'Important': ['imp', 'exclamation-circle'],
        'Deviation': ['devi', 'frown'],
        'Invoicing': ['inv', 'file-invoice-dollar']
    }
    var cat_label = '';
    var categories = category.split(',')
    Object.values(categories).forEach(function(val){
      var cat = val.trim()
      if (Object.keys(cat_classes).indexOf(cat) != -1){
          cat_label += ''+cat+' '+''+" ";
      }
    });
    return cat_label;
}

function get_note_url() {
    // URL for the notes
    if ((typeof notetype !== 'undefined' && notetype == 'lims_step') || ('lims_step' in window && lims_step !== null)){
        note_url='/api/v1/workset_notes/' + lims_step;
    } else if ((typeof notetype !== 'undefined' && notetype == 'flowcell') || ('flowcell_id_reference' in window && flowcell_id_reference!== null)){
        note_url='/api/v1/flowcell_notes/' + flowcell_id_reference;
    } else {
        note_url='/api/v1/running_notes/' + project;
    }
    return note_url;
}

function make_running_note(date, note){
  try {
    var category = '';
    var date = date.replace(/-/g, '/');
    date = date.replace(/\.\d{6}/, '');
    date = new Date(date);
    if (note['note'] != undefined){
        if(date > new Date('2015-01-01')){
          //Replace > and < in old versions of running notes saved on lims.
          noteText = make_markdown(note['note'].replace(/</g, '<').replace(/>/g, '>'));
        } else {
          noteText = '
'+make_project_links(note['note'])+'
';
        }
        datestring = date.toDateString() + ', ' + date.toLocaleTimeString(date);
        var page_to_link = '';
        if(typeof project !== 'undefined'){
          page_to_link = project;
        }
        else if (typeof flowcell!== 'undefined') {
          page_to_link = flowcell;
        }
        else if(typeof workset_name !== 'undefined'){
          page_to_link = workset_name
        }
        note_id = 'running_note_'+page_to_link+'_'+(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(),
                   date.getUTCDate(), date.getHours(), date.getMinutes(), date.getSeconds())/1000);
        if ('category' in note){
            category=generate_category_label(note['category']);
        }
    }
  } catch(e){
    noteText = '
'+make_project_links(note['note'])+'
';
    var datestring = '?';
  }
  var printHyphen =category? ' - ': ' ';
  var panelClass='';
  if (note['category'].includes('Important')) {
    panelClass = 'card-important';
  }
  return '
' +
      '
'+
        ''+note['user']+' - '+
       '' + datestring + '' + printHyphen +category +'

'+noteText+'

';
}

function load_running_notes(wait) {
  // Clear previously loaded notes, if so
  note_url = get_note_url();
  $("#running_notes_panels").empty();
  return $.getJSON(note_url, function(data) {
    if(Object.keys(data).length == 0 || typeof data === 'undefined'){
      $('#running_notes_panels').html('
No running notes found.
');
    } else {
      $.each(data, function(date, note) {
        $('#running_notes_panels').append(make_running_note(date, note));
      });
      check_img_sources($('#running_notes_panels img'));
      count_cards();
    }
  }).fail(function( jqxhr, textStatus, error ) {
      try {
        var response = JSON.parse(jqxhr.responseText);
        var err = response['page_title'];
        var exception = $('
').text(response['error_exception']).html(); // HTML encode string
        var debugging = "
For debugging purposes, we've tried to grab the error that triggered this page for you:
"+
                        '

'+exception+'';
      } catch(e) {
        var err = error+', '+textStatus;
        var debugging = '';
      }
      $('#running_notes_panels').append('
' +
          '
Error Loading Running Notes: '+err+'
' +
          '
Apologies, running notes could not be loaded.' +
          'These problems are usually ' +
          'due to connection problems. Please try again later and report if the problem persists.

'+debugging);
  });
}
function preview_running_notes(){
    var now = new Date();
    $('.todays_date').text(now.toDateString() + ', ' + now.toLocaleTimeString());
    var categories = []
    $('.rn-categ button.active').each(function() {
      categories.push($(this).text().trim());
    });
    var category = generate_category_label(categories.join());
    category = category ? ' - '+ category : category;
    $('#preview_category').html(category);
    var text = $('#new_note_text').val().trim();
    if (text.length > 0) {
        $('#running_note_preview_body').html(make_markdown(text));
        check_img_sources($('#running_note_preview_body img'));
    } else {
        $('#running_note_preview_body').html('
Nothing to preview..
');
    }
    // update textarea height
    $('#new_note_text').css('height', $('#running_note_preview_panel').css('height'));
}
function filter_running_notes(search){
    search=search.toLowerCase();
    $('#running_notes_panels').children().each(function(){
        var header=$(this).children('.card-header').text();
        var note=$(this).children('.card-body').children().text();
        if (header.toLowerCase().indexOf(search) != -1 || note.toLowerCase().indexOf(search) != -1){
            $(this).show();
        }else{
            $(this).hide();
        }
    });
}
//Count rn's of each category and add badge with number to filter dropdown
function count_cards(){
    var cat_cards = {};
    var all = 0;
    $('#running_notes_panels').find('.badge').each(function(){
        var label = $.trim($(this).text());
        all++;
        if (label){
            if (label in cat_cards){
                cat_cards[label]++;
            }else{
                cat_cards[label] = 1;
            }
        }
    });
    $('.btn_count').append('All '+all+'');
    $('#rn_category').next().find('.dropdown-item').each(function(){
        var label = $.trim($(this).text())
        cat_cards['All'] = all;
        if (!cat_cards[label]){
            $(this).parent('li').addClass('d-none');
        }else if (Object.keys(cat_classes).indexOf(label) != -1){
            $(this).prepend(''+cat_cards[label]+'');
        }else{
            $(this).prepend(''+cat_cards[label]+'');
        }
    });
}

//Filter notes
$('#rn_search').keyup(function() {
    var search=$('#rn_search').val();
    filter_running_notes(search);
    $('#rn_category').html(''+
    $('#running_notes_panels').find('.badge').length+'All');
});

//Filter dropdown
$('#rn_category ~ ul > li > button').on('click', function(){
    $('#rn_category').html($(this).html());
    var search = this.lastChild.textContent;
    if (search.includes('All')){
        search = '';
    }
    filter_running_notes(search);
});

// Update the category buttons
$('.rn-categ button').click(function(e){
    e.preventDefault();
    var was_selected = $(this).hasClass('active');
    if(was_selected){
        $(this).removeClass('active');
    }
    else{
        $(this).addClass('active');
    }
    preview_running_notes();
});

//Remove hover text from clicked button
$(document).ready(function(){
      $('[data-toggle="tooltip"]').click(function (){
         $('[data-toggle="tooltip"]').tooltip("hide");
      });
});

// Preview running notes
$('#new_note_text').keyup(preview_running_notes);

// Insert new running note and reload the running notes table
$("#running_notes_form").submit( function(e) {
    e.preventDefault();
    var text = $('#new_note_text').val().trim();
    var categories = [];
    $('.rn-categ button.active').each(function() {
      categories.push($(this).text().trim());
    });
    category = categories.join()
    if (text.length == 0) {
        alert("Error: No running note entered.");
        return false;
    }
    if (!$('.rn-categ button.active').text()) {
       if (!confirm("Are you sure that you want to submit without choosing a category?")) {
          return false;
       }
    }

    note_url = get_note_url()
    $('#save_note_button').addClass('disabled').text('Submitting...');
    $.ajax({
      type: 'POST',
      url: note_url,
      dataType: 'json',
      data: {"note": text, "category": category},
      error: function(xhr, textStatus, errorThrown) {
        alert('Error: '+xhr['responseText']+' ('+errorThrown+')');
        $('#save_note_button').removeClass('disabled').text('Submit Running Note');
        console.log(xhr);
        console.log(textStatus);
        console.log(errorThrown);
      },
      success: function(data, textStatus, xhr) {
        // Manually check whether the running note has saved
        note_url=get_note_url()
        $.getJSON(note_url, function(newdata) {
          var newNote = false;
          $.each(newdata, function(date, note) {
            if(data['note'] == note['note']){
              newNote = make_running_note(date, note);
            }
          });
          if(newNote){
            // Enable the submit button again
            $('#save_note_button').removeClass('disabled').text('Submit Running Note');
            // Clear the text box
            $('#new_note_text').val('');
            $('#running_note_preview_body').html('
Nothing to preview..
');
            $('#new_note_text').css('height', $('#running_note_preview_panel').css('height'));
            // Cler the 'no running notes found' box if it's there
            if($('#running_notes_panels').html() == '
No running notes found.
'){
              $('#running_notes_panels .well').slideUp(function(){ $(this).remove(); });
            }
            // Create a new running note and slide it in..
            var now = new Date();
            category=generate_category_label(category);
            var printHyphen =category? ' - ': ' ';
            $('

'+
                  ''+data['user']+' - '+
                  now.toDateString() + ', ' + now.toLocaleTimeString(now)+ printHyphen + category +
                '

'+make_markdown(data['note'])+
                '

').hide().prependTo('#running_notes_panels').slideDown();
            check_img_sources($('#running_notes_panels img'));
          } else {
            alert('Error - Your running note was not saved.');
            $('#save_note_button').removeClass('disabled').text('Submit Running Note');
          }
        });
      }
    });
});
$('#new_note_text').on('focus',function(){$(this).sew({values:window.users})});
<|endoftext|>