<commit_before>(function ($, $document, gAuthor) {

    var consoleToAreaWidthRatio = 0.9,
        consoleToAreaHeightRatio = 0.5;

    var sizeEditor = function () {

        var defaultHeight = $('#consolearea').height() * consoleToAreaHeightRatio;
        $('#resizable').height(Lockr.get('editorHeight', defaultHeight))

        editor.resize();

        /*$("#resizable").resizable({
            resize: function (event, ui) {
                //Lockr.set('editorWidth', $('#editor').width());
                Lockr.set('editorHeight', $('#editor').height());

                editor.resize();
            }
        });*/
    };

    var styleEditor = function () {
        window.editor = ace.edit("editor");
        editor.setTheme("ace/theme/twilight");
        (function () {
            editor.session.setMode("ace/mode/groovy");
        }());
    };

    var showEditor = function () {
        var lastScript = Lockr.get('lastScript');
        if (lastScript) {
            editor.setValue(lastScript, -1);
        }

        $('#consolearea').show();
        $('#formarea').hide();
    };

    var hideAllPanels = function () {
        $(".info-error, .info-result, .info-output, .info-meta").hide();
    };

    $(document).ready(function () {
        console.log("Loading editor... ");
        hideAllPanels();
        styleEditor();
        sizeEditor();
        showEditor();
        console.log("Loading editor finished.");
    });
})
(Granite.$, $(document), Granite.author);
/*
 AemScriptConsole.localStorage = function () {

 }

 $(function () {

 AemScriptConsole.initEditor();
 AemScriptConsole.initTheme();
 AemScriptConsole.initApplicationToolbar();
 AemScriptConsole.initEditorToolbarActions();
 AemScriptConsole.initFormToolbarActions();

 });*/<commit_msg>Created execute-script event handler Added printToMeta functionality Created clear event handler<commit_after>(function ($, $document, gAuthor) {

    var consoleToAreaWidthRatio = 0.9,
        consoleToAreaHeightRatio = 0.5;

    var sizeEditor = function () {

        var defaultHeight = $('#consolearea').height() * consoleToAreaHeightRatio;
        $('#resizable').height(Lockr.get('editorHeight', defaultHeight))

        editor.resize();

        /*$("#resizable").resizable({
            resize: function (event, ui) {
                //Lockr.set('editorWidth', $('#editor').width());
                Lockr.set('editorHeight', $('#editor').height());

                editor.resize();
            }
        });*/
    };

    var styleEditor = function () {
        window.editor = ace.edit("editor");
        editor.setTheme("ace/theme/twilight");
        (function () {
            editor.session.setMode("ace/mode/groovy");
        }());
    };

    var showEditor = function () {
        var lastScript = Lockr.get('lastScript');
        if (lastScript) {
            editor.setValue(lastScript, -1);
        }

        $('#consolearea').show();
        $('#formarea').hide();
    };

    var hideAllPanels = function () {
        $(".info-error, .info-result, .info-output, .info-meta").hide();
    };

    var resetAllMessages = function () {
        clearInfoPanel();
        hideAllPanels();
    };

    var clearInfoPanel = function () {
        $(".info-message").empty();
    };

    var clearEditor = function () {
        Lockr.rm('lastScript');
        editor.setValue("");
    };

    var initializeEditorToolbar = function(){
        $('.execute-script').click(function () {
            console.log("Triggered script execution... ");
            if ($(this).hasClass('disabled')) {
                return;
            }

            clearInfoPanel();

            var script = editor.getSession().getValue();
            if (script.length) {

                editor.setReadOnly(true);
                var posting = $.post(CQ.shared.HTTP.getContextPath() + '/bin/asconsole/groovy/post.json', {
                    script: script
                });

                posting.done(function (xhrMessage) {
                    console.log(xhrMessage);

                    clearInfoPanel();

                    if (xhrMessage.failed) {
                        setPanelVisibility(true, true, true);
                        $(".info-message-error").append(xhrMessage.error);
                    } else {
                        setPanelVisibility(true, true, false);
                    }

                    if (xhrMessage.result && xhrMessage.result !== "null" && xhrMessage.result !== "") {
                        $(".info-message-result").append(xhrMessage.result);
                    } else {
                        $(".info-message-result").append("No result");
                    }

                    if (xhrMessage.output && xhrMessage.output !== "null" && xhrMessage.output !== "") {
                        $(".info-message-output").append(xhrMessage.output);
                    } else {
                        $(".info-message-output").append("No output");
                    }
                    printToMeta(xhrMessage.executionTime + " ms");
                });

                posting.fail(function (xhrMessage) {
                    console.log("Fail");
                    console.log(xhrMessage);

                    setPanelVisibility(true, true, true);
                    if (xhrMessage.status == 403) {
                        //missing permissions
                        console.log("Missing permissions")
                    } else {
                        console.log("Unable to execute script");
                    }
                });

                posting.always(function () {
                    editor.setReadOnly(false);
                });
            }

            focusEndOfEditorDocument();
        });

        $('.clear-editor').click(function () {
            clearInfoPanel();
            clearEditor();
            hideAllPanels();

            printToMeta("Editor and localStorage [lastScript] cleared");

            focusEndOfEditorDocument();
        });
    };

    var focusEndOfEditorDocument = function(){

        editor.focus();
        var session = editor.getSession();
        var count = session.getLength();

        editor.gotoLine(count, session.getLine(count-1).length);
    }

    setPanelVisibility = function (result, output, error) {
        for (var i = 0, j = arguments.length; i < j; i++){
            console.log(arguments[i])
        };

        if (result) {
            $(".info-result").show();
        } else {
            $(".info-result").hide();
        }

        if (output) {
            $(".info-output").show();
        } else {
            $(".info-output").hide();
        }

        if (error) {
            $(".info-error").show();
        } else {
            $(".info-error").hide();
        }
    };

    var printToMeta = function(message) {
        window.console.log(message);
        $(".info-message-meta").show();
        $(".info-message-meta").fadeIn('slow');
        $(".info-message-meta").text(message);
        setTimeout(function () {
            $(".info-message-meta").fadeOut('slow');
            $(".info-message-meta").hide();
        }, 3500);
    };

    $(document).ready(function () {
        console.log("Loading editor... ");
        hideAllPanels();
        styleEditor();
        sizeEditor();
        showEditor();
        initializeEditorToolbar();
        printToMeta("Editor has been successfully loaded... ");
    });
})
(Granite.$, $(document), Granite.author);
/*
 AemScriptConsole.localStorage = function () {

 }

 $(function () {

 AemScriptConsole.initEditor();
 AemScriptConsole.initTheme();
 AemScriptConsole.initApplicationToolbar();
 AemScriptConsole.initEditorToolbarActions();
 AemScriptConsole.initFormToolbarActions();

 });*/<|endoftext|>


<commit_before>import {
  React, action, PropTypes, observable, observer, computed, styled,
} from 'vendor';
import Courses, { Course } from '../../models/courses-map';
import Loading from 'shared/components/loading-animation';
import { GradingTemplates } from '../../models/grading/templates';
import TemplateCard from './card';
import { ScrollToTop } from 'shared';
import CoursePage from '../../components/course-page';
import * as EDIT_TYPES from './editors';
import { Col, Row, Container, Button } from 'react-bootstrap';
import CourseBreadcrumb from '../../components/course-breadcrumb';

const Instructions = styled.p`
  font-size: 1.8rem;
`;

export default
@observer
class GradingTemplatesScreen extends React.Component {

  static propTypes = {
    course: PropTypes.instanceOf(Course),
    gradingTemplates: PropTypes.instanceOf(GradingTemplates),
    params: PropTypes.shape({
      courseId: PropTypes.string.isRequired,
    }).isRequired,
  }

  @observable editing = null;

  constructor(props) {
    super(props);
    this.store.fetch();
  }

  componentDidMount() {
    document.body.classList.add('light');
  }

  componentWillUnmount() {
    document.body.classList.remove('light');
  }

  @computed get course() {
    return this.props.course || Courses.get(this.props.params.courseId);
  }

  @computed get store() {
    return this.props.gradingTemplates || this.course.gradingTemplates;
  }

  @action.bound onEditComplete() {
    this.editing = null;
  }

  @action.bound onEditTemplate(template) {
    this.editing = template;
  }

  @action.bound onAdd() {
    this.editing = { task_plan_type: 'create' };
  }

  @action.bound onCreateTypeSelection(task_plan_type) {
    this.editing = this.store.newTemplate({ task_plan_type });
  }

  body() {
    if (this.store.api.isPending) {
      return <Loading message="Fetching templates…" />;
    }
    let modal;

    if (this.editing) {
      const Edit = EDIT_TYPES[this.editing.task_plan_type];
      if (Edit) {
        modal = (
          <Edit
            template={this.editing}
            onComplete={this.onEditComplete}
            onCreateTypeSelection={this.onCreateTypeSelection}
          />
        );
      }
    }

    return (
      <Container fluid={true}>
        {modal}
        <Row>
          <Col>
            <Instructions>Manage pre-set submission and grading policy templates here. These templates can be applied to multiple assignments.</Instructions>
          </Col>
        </Row>
        <Row>
          {this.store.array.map(tmpl =>
            <Col key={tmpl.id} lg={4} md={6} sm={12} xs={12}>
              <TemplateCard
                onEdit={this.onEditTemplate}
                template={tmpl}
                store={this.store} />
            </Col>
          )}
        </Row>
      </Container>
    );
  }

  titleControls() {
    return <Button onClick={this.onAdd} size="lg">Add new template</Button>;
  }

  titleBreadcrumbs() {
    return <CourseBreadcrumb course={this.course} currentTitle="Grading Templates" />;
  }

  render() {
    return (
      <ScrollToTop>
        <CoursePage
          course={this.course}
          title="Grading Templates"
          titleControls={this.titleControls()}
          titleBreadcrumbs={this.titleBreadcrumbs()}
          titleAppearance="light"
        >
          {this.body()}
        </CoursePage>
      </ScrollToTop>
    );
  }

}
<commit_msg>set height and background color on course page<commit_after>import {
  React, action, PropTypes, observable, observer, computed, styled,
} from 'vendor';
import Courses, { Course } from '../../models/courses-map';
import Theme from '../../theme';
import Loading from 'shared/components/loading-animation';
import { GradingTemplates } from '../../models/grading/templates';
import TemplateCard from './card';
import { ScrollToTop } from 'shared';
import CoursePage from '../../components/course-page';
import * as EDIT_TYPES from './editors';
import { Col, Row, Container, Button } from 'react-bootstrap';
import CourseBreadcrumb from '../../components/course-breadcrumb';

const Instructions = styled.p`
  font-size: 1.8rem;
`;

const Templates = styled(CoursePage)`
  min-height: calc(100vh - ${Theme.navbars.top.height});
  background-color: wheat;
`;

export default
@observer
class GradingTemplatesScreen extends React.Component {

  static propTypes = {
    course: PropTypes.instanceOf(Course),
    gradingTemplates: PropTypes.instanceOf(GradingTemplates),
    params: PropTypes.shape({
      courseId: PropTypes.string.isRequired,
    }).isRequired,
  }

  @observable editing = null;

  constructor(props) {
    super(props);
    this.store.fetch();
  }

  componentDidMount() {
    document.body.classList.add('light');
  }

  componentWillUnmount() {
    document.body.classList.remove('light');
  }

  @computed get course() {
    return this.props.course || Courses.get(this.props.params.courseId);
  }

  @computed get store() {
    return this.props.gradingTemplates || this.course.gradingTemplates;
  }

  @action.bound onEditComplete() {
    this.editing = null;
  }

  @action.bound onEditTemplate(template) {
    this.editing = template;
  }

  @action.bound onAdd() {
    this.editing = { task_plan_type: 'create' };
  }

  @action.bound onCreateTypeSelection(task_plan_type) {
    this.editing = this.store.newTemplate({ task_plan_type });
  }

  body() {
    if (this.store.api.isPending) {
      return <Loading message="Fetching templates…" />;
    }
    let modal;

    if (this.editing) {
      const Edit = EDIT_TYPES[this.editing.task_plan_type];
      if (Edit) {
        modal = (
          <Edit
            template={this.editing}
            onComplete={this.onEditComplete}
            onCreateTypeSelection={this.onCreateTypeSelection}
          />
        );
      }
    }

    return (
      <Container fluid={true}>
        {modal}
        <Row>
          <Col>
            <Instructions>Manage pre-set submission and grading policy templates here. These templates can be applied to multiple assignments.</Instructions>
          </Col>
        </Row>
        <Row>
          {this.store.array.map(tmpl =>
            <Col key={tmpl.id} lg={4} md={6} sm={12} xs={12}>
              <TemplateCard
                onEdit={this.onEditTemplate}
                template={tmpl}
                store={this.store} />
            </Col>
          )}
        </Row>
      </Container>
    );
  }

  titleControls() {
    return <Button onClick={this.onAdd} size="lg">Add new template</Button>;
  }

  titleBreadcrumbs() {
    return <CourseBreadcrumb course={this.course} currentTitle="Grading Templates" />;
  }

  render() {
    return (
      <ScrollToTop>
        <Templates
          course={this.course}
          title="Grading Templates"
          titleControls={this.titleControls()}
          titleBreadcrumbs={this.titleBreadcrumbs()}
          titleAppearance="light"
        >
          {this.body()}
        </Templates>
      </ScrollToTop>
    );
  }

}
<|endoftext|>


<commit_before>// ==UserScript==
// @name           Takarazuka ticket autoselect
// @namespace      curipha
// @description    Choose sheet category and number automatically
// @include        https://ent-kageki.e-tix.jp/ticket/seatnumberselect.html*
// @version        0.0.1
// @grant          none
// @noframes
// ==/UserScript==

(function(){
  document.getElementById('tc11').children[1].selected = true;  // Sheet S
  document.getElementById('tc21').children[1].selected = true;  // Sheet A
  document.getElementById('tc31').children[1].selected = true;  // Sheet B

  var type = document.body.querySelectorAll('input[name="rt"][value="2"]');
  for (var input of type) {
    input.checked = true;
  }
})();

<commit_msg>Add null check<commit_after>// ==UserScript==
// @name           Takarazuka ticket autoselect
// @namespace      curipha
// @description    Choose sheet category and number automatically
// @include        https://ent-kageki.e-tix.jp/ticket/seatnumberselect.html*
// @version        0.0.1
// @grant          none
// @noframes
// ==/UserScript==

(function(){
  document.getElementById('tc11').children[1].selected = true;  // Sheet S
  document.getElementById('tc21').children[1].selected = true;  // Sheet A
  document.getElementById('tc31').children[1].selected = true;  // Sheet B

  var type = document.body.querySelectorAll('input[name="rt"][value="2"]');
  for (var input of type) {
    if (input) input.checked = true;
  }
})();

<|endoftext|>


<commit_before>/*
 * jQuery UI Selectmenu @VERSION
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Selectmenu
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.widget.js
 *	jquery.ui.position.js
 *	jquery.ui.menu.js
 *	jquery.ui.button.js
 */
(function( $, undefined ) {

$.widget( "ui.selectmenu", {
	version: "@VERSION",
	defaultElement: "<select>",
	options: {
		dropdown: true,
		appendTo: "body",
		position: {
			my: "left top",
			at: "left bottom",
			collision: "none"
		},
		value: null,
		// callbacks
		open: null,
		focus: null,
		select: null,
		close: null,
		change: null
	},

	_create: function() {
		// set a default id value, generate a new random one if not set by developer
		var selectmenuId = this.element.attr( 'id' ) || 'ui-selectmenu-' + Math.random().toString( 16 ).slice( 2, 10 );

		// array of button and menu id's
		this.ids = { id: selectmenuId, button: selectmenuId + '-button', menu: selectmenuId + '-menu' };

		// set current value
		if ( this.options.value ) {
			this.element[0].value = this.options.value;
		} else {
			this.options.value = this.element[0].value;
		}

		// catch click event of the label
		this._bind({
			'click':  function( event ) {
				this.button.focus();
				event.preventDefault();
			}
		});

		this._drawButton();
		this._bind( this.button, this._buttonEvents );

		this._drawMenu();
		this.refresh();
	},

	_drawButton: function() {
		var tabindex = this.element.attr( 'tabindex' );

		// hide original select tag
		this.element.hide();

		// create button
		this.button = $( '', {
				href: '#' + this.ids.id,
				tabindex: ( tabindex ? tabindex : this.element.attr( 'disabled' ) ? -1 : 0 ),
				id: this.ids.button,
				css: {
					width: this.element.outerWidth()
				},
				'aria-disabled': this.options.disabled,
				'aria-owns': this.ids.menu,
				'aria-haspopup': true
			})
			.button({
				label: this.element.find( "option:selected" ).text(),
				icons: {
					primary: ( this.options.dropdown ? 'ui-icon-triangle-1-s' : 'ui-icon-triangle-2-n-s' )
				}
			});

		// wrap and insert new button
		this.buttonWrap = $( '' )
			.addClass( 'ui-selectmenu-button' )
			.append( this.button )
			.insertAfter( this.element );
	},

	_drawMenu: function() {
		var that = this;

		// create menu portion, append to body
		this.menu = $( '
', {
			'class': 'ui-widget ui-widget-content',
			'aria-hidden': true,
			'aria-labelledby': this.ids.button,
			role: 'menubox',
			id: this.ids.menu
		});

		// set width
		if ( this.options.dropdown ) {
			var setWidth = this.button.outerWidth();
		} else {
			var text = this.button.find( "span.ui-button-text");
			var setWidth = text.width() + parseFloat( text.css( "padding-left" ) ) || 0 + parseFloat( text.css( "margin-left" ) || 0 );
		}

		// wrap menu
		this.menuWrap = $( '
' )
			.addClass( 'ui-selectmenu-menu' )
			.width( setWidth )
			.append( this.menu )
			.appendTo( this.options.appendTo );

		// init menu widget
		this.menu.menu({
			select: function( event, ui ) {
				var flag = false,
					item = ui.item.data( "item.selectmenu" ),
					oldIndex = that.element[0].selectedIndex;

				that._setOption( "value", item.value );
				that._trigger( "select", event, { item: item } );

				if ( item.index != oldIndex ) {
					that._trigger( "change", event, { item: item } );
				}

				if ( that.isOpen ) {
					event.preventDefault();
					that.close( event, true);
				}
			},
			focus: function( event, ui ) {
				var item = ui.item.data( "item.selectmenu" );

				if ( that.focus !== undefined && item.index != that.focus ) {
					that._trigger( "focus", event, { item: item } );
				}

				that.focus = item.index;
			}
		});

		// document click closes menu
		this._bind( document, {
			'click': function( event ) {
				if ( this.isOpen && !$( event.target ).closest( "#" + this.ids.button).length ) {
					this.close( event );
				}
			}
		});
	},

	refresh: function() {
		this.menu.empty();

		this._readOptions();
		this._renderMenu( this.menu, this.items );

		this.menu.menu( "refresh" );

		// adjust ARIA
		this.menu.find( "li" ).not( '.ui-selectmenu-optgroup' ).find( 'a' ).attr( 'role', 'option' );

		if ( this.options.dropdown ) {
			this.menu
				.addClass( 'ui-corner-bottom' )
				.removeClass( 'ui-corner-all' );
		}

		// transfer disabled state
		if ( this.element.attr( 'disabled' ) ) {
			this.disable();
		} else {
			this.enable()
		}
	},

	open: function( event ) {
		var currentItem = this._getSelectedItem();

		if ( !this.options.disabled ) {
			if ( this.options.dropdown ) {
				this.button
					.addClass( 'ui-corner-top' )
					.removeClass( 'ui-corner-all' );
			}

			this.menuWrap.addClass( 'ui-selectmenu-open' );
			// needs to be fired after the document click event has closed all other Selectmenus
			// otherwise the current item is not indicated
			// TODO check if this should be handled by Menu
			this._delay( function(){
				this.menu.menu( "focus", event, currentItem );
			}, 1);

			if ( !this.options.dropdown ) {
				// center current item
				if ( this.menu.css("overflow") == "auto" ) {
					this.menu.scrollTop( this.menu.scrollTop() + currentItem.position().top - this.menu.outerHeight()/2 + currentItem.outerHeight()/2 );
				}
				// calculate offset
				var _offset = ( this.menu.offset().top  - currentItem.offset().top + ( this.button.outerHeight() - currentItem.outerHeight() ) / 2);
				$.extend( this.options.position, {
					my: "left top",
					at: "left top",
					offset: "0 " + _offset
				});
			}

			this.menuWrap
				.zIndex( this.element.zIndex() + 1 )
				.position( $.extend({
					of: this.button
				}, this.options.position ));

			this.isOpen = true;
			this._trigger( "open", event );
		}
	},

	close: function( event, focus ) {
		if ( this.isOpen ) {
			if ( this.options.dropdown ) {
				this.button
					.addClass( 'ui-corner-all' )
					.removeClass( 'ui-corner-top' );
			}

			this.menuWrap.removeClass( 'ui-selectmenu-open' );
			this.isOpen = false;

			if ( focus ) {
				this.button.focus();
			}

			this._trigger( "close", event );
		}
	},

	widget: function() {
		return this.buttonWrap.add( this.menuWrap );
	},

	_renderMenu: function( ul, items ) {
		var that = this,
			currentOptgroup = "";

		$.each( items, function( index, item ) {
			if ( item.optgroup != currentOptgroup ) {
				var optgroup = $( '
' + item.optgroup + '
' );
				if ( item.element.parent( "optgroup" ).attr( "disabled" ) ) optgroup.addClass( 'ui-state-disabled' );
				ul.append( optgroup );
				currentOptgroup = item.optgroup;
			}
			that._renderItem( ul, item );
		});
	},

	_renderItem: function( ul, item) {
		var li = $( "
" ).data( "item.selectmenu", item );
		if ( item.disabled ) {
			li.addClass( 'ui-state-disabled' ).text( item.label );
		} else {
			li.append( $( "", {
					text: item.label,
					href: '#'
				})
			);
		}

		return li.appendTo( ul );
	},

	_move: function( key, event ) {
		if ( !this.isOpen )	{
			this.menu.menu( "focus", event, this._getSelectedItem() );
		}

		this.menu.menu( key, event );

		if ( !this.isOpen ) {
			this.menu.menu( "select", event  );
		}
	},

	_getSelectedItem: function() {
		return this.menu.find( "li" ).not( '.ui-selectmenu-optgroup' ).eq( this.element[0].selectedIndex );
	},

	_toggle: function( event ) {
		if ( this.isOpen ) {
			this.close( event );
		} else {
			this.open( event );
		}
	},

	_buttonEvents: {
		click: function( event ) {
			this._toggle( event );
			event.preventDefault();
		},
		keydown: function( event ) {
			switch (event.keyCode) {
				case $.ui.keyCode.TAB:
					if ( this.isOpen ) {
						this.close( event );
					}
					break;
				case $.ui.keyCode.ENTER:
					if ( this.isOpen ) {
						this.menu.menu( "select", this._getSelectedItem() );
					}
					event.preventDefault();
					break;
				case $.ui.keyCode.SPACE:
					event.preventDefault();
					break;
				case $.ui.keyCode.UP:
					if ( event.altKey ) {
						this._toggle( event );
					} else {
						this._move( "previous", event );
					}
					event.preventDefault();
					break;
				case $.ui.keyCode.DOWN:
					if ( event.altKey ) {
						this._toggle( event );
					} else {
						this._move( "next", event );
					}
					event.preventDefault();
					break;
				case $.ui.keyCode.LEFT:
					this._move( "previous", event );
					event.preventDefault();
					break;
				case $.ui.keyCode.RIGHT:
					this._move( "next", event );
					event.preventDefault();
					break;
				default:
					this.menu.trigger( event );
			}
		}
	},

	_setOption: function( key, value ) {
		this._super( key, value );

		if ( key === "appendTo" ) {
			this.menuWrap.appendTo( $( value || "body", this.element[0].ownerDocument )[0] );
		}
		if ( key === "value" && value !== undefined ) {
			this.element[0].value = value;
			this.button.children( '.ui-button-text' ).text( this.items[ this.element[0].selectedIndex ].label );
		}
		if ( key === "disabled" ) {
			this.button.button( "option", "disabled", value );
			if ( value ) {
				this.element.attr( "disabled", "disabled" );
				this.button.attr( "tabindex", -1 );
				this.close();
			} else {
				this.element.removeAttr( "disabled" );
				this.button.attr( "tabindex", 0 );
			}
			this.menu.attr( "aria-disabled", value );
		}
	},

	_readOptions: function() {
		var data = [];
		$.each( this.element.find( 'option' ), function( index, item ) {
			var option = $( item ),
				optgroup = option.parent( "optgroup" );
			data.push({
				element: option,
				index: index,
				value: option.attr( 'value' ),
				label: option.text(),
				optgroup: optgroup.attr( "label" ) || false,
				disabled: optgroup.attr( "disabled" ) || option.attr( "disabled" )
			});
		});
		this.items = data;
	},

	_destroy: function() {
		this.menuWrap.remove();
		this.buttonWrap.remove();
		this.element.show();
	}
});

}( jQuery ));
<commit_msg>Selectmenu: fixed aria-hidden attribute<commit_after>/*
 * jQuery UI Selectmenu @VERSION
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Selectmenu
 *
 * Depends:
 *	jquery.ui.core.js
 *	jquery.ui.widget.js
 *	jquery.ui.position.js
 *	jquery.ui.menu.js
 *	jquery.ui.button.js
 */
(function( $, undefined ) {

$.widget( "ui.selectmenu", {
	version: "@VERSION",
	defaultElement: "<select>",
	options: {
		dropdown: true,
		appendTo: "body",
		position: {
			my: "left top",
			at: "left bottom",
			collision: "none"
		},
		value: null,
		// callbacks
		open: null,
		focus: null,
		select: null,
		close: null,
		change: null
	},

	_create: function() {
		// set a default id value, generate a new random one if not set by developer
		var selectmenuId = this.element.attr( 'id' ) || 'ui-selectmenu-' + Math.random().toString( 16 ).slice( 2, 10 );

		// array of button and menu id's
		this.ids = { id: selectmenuId, button: selectmenuId + '-button', menu: selectmenuId + '-menu' };

		// set current value
		if ( this.options.value ) {
			this.element[0].value = this.options.value;
		} else {
			this.options.value = this.element[0].value;
		}

		// catch click event of the label
		this._bind({
			'click':  function( event ) {
				this.button.focus();
				event.preventDefault();
			}
		});

		this._drawButton();
		this._bind( this.button, this._buttonEvents );

		this._drawMenu();
		this.refresh();
	},

	_drawButton: function() {
		var tabindex = this.element.attr( 'tabindex' );

		// hide original select tag
		this.element.hide();

		// create button
		this.button = $( '', {
				href: '#' + this.ids.id,
				tabindex: ( tabindex ? tabindex : this.element.attr( 'disabled' ) ? -1 : 0 ),
				id: this.ids.button,
				css: {
					width: this.element.outerWidth()
				},
				'aria-disabled': this.options.disabled,
				'aria-owns': this.ids.menu,
				'aria-haspopup': true
			})
			.button({
				label: this.element.find( "option:selected" ).text(),
				icons: {
					primary: ( this.options.dropdown ? 'ui-icon-triangle-1-s' : 'ui-icon-triangle-2-n-s' )
				}
			});

		// wrap and insert new button
		this.buttonWrap = $( '' )
			.addClass( 'ui-selectmenu-button' )
			.append( this.button )
			.insertAfter( this.element );
	},

	_drawMenu: function() {
		var that = this;

		// create menu portion, append to body
		this.menu = $( '
', {
			'class': 'ui-widget ui-widget-content',
			'aria-hidden': true,
			'aria-labelledby': this.ids.button,
			role: 'menubox',
			id: this.ids.menu
		});

		// set width
		if ( this.options.dropdown ) {
			var setWidth = this.button.outerWidth();
		} else {
			var text = this.button.find( "span.ui-button-text");
			var setWidth = text.width() + parseFloat( text.css( "padding-left" ) ) || 0 + parseFloat( text.css( "margin-left" ) || 0 );
		}

		// wrap menu
		this.menuWrap = $( '
' )
			.addClass( 'ui-selectmenu-menu' )
			.width( setWidth )
			.append( this.menu )
			.appendTo( this.options.appendTo );

		// init menu widget
		this.menu.menu({
			select: function( event, ui ) {
				var flag = false,
					item = ui.item.data( "item.selectmenu" ),
					oldIndex = that.element[0].selectedIndex;

				that._setOption( "value", item.value );
				that._trigger( "select", event, { item: item } );

				if ( item.index != oldIndex ) {
					that._trigger( "change", event, { item: item } );
				}

				if ( that.isOpen ) {
					event.preventDefault();
					that.close( event, true);
				}
			},
			focus: function( event, ui ) {
				var item = ui.item.data( "item.selectmenu" );

				if ( that.focus !== undefined && item.index != that.focus ) {
					that._trigger( "focus", event, { item: item } );
				}

				that.focus = item.index;
			}
		});

		// document click closes menu
		this._bind( document, {
			'click': function( event ) {
				if ( this.isOpen && !$( event.target ).closest( "#" + this.ids.button).length ) {
					this.close( event );
				}
			}
		});
	},

	refresh: function() {
		this.menu.empty();

		this._readOptions();
		this._renderMenu( this.menu, this.items );

		this.menu.menu( "refresh" );

		// adjust ARIA
		this.menu.find( "li" ).not( '.ui-selectmenu-optgroup' ).find( 'a' ).attr( 'role', 'option' );

		if ( this.options.dropdown ) {
			this.menu
				.addClass( 'ui-corner-bottom' )
				.removeClass( 'ui-corner-all' );
		}

		// transfer disabled state
		if ( this.element.attr( 'disabled' ) ) {
			this.disable();
		} else {
			this.enable()
		}
	},

	open: function( event ) {
		var currentItem = this._getSelectedItem();

		if ( !this.options.disabled ) {
			if ( this.options.dropdown ) {
				this.button
					.addClass( 'ui-corner-top' )
					.removeClass( 'ui-corner-all' );
			}

			this.menuWrap.addClass( 'ui-selectmenu-open' );
			this.menu.attr("aria-hidden", false);
			// needs to be fired after the document click event has closed all other Selectmenus
			// otherwise the current item is not indicated
			// TODO check if this should be handled by Menu
			this._delay( function(){
				this.menu.menu( "focus", event, currentItem );
			}, 1);

			if ( !this.options.dropdown ) {
				// center current item
				if ( this.menu.css("overflow") == "auto" ) {
					this.menu.scrollTop( this.menu.scrollTop() + currentItem.position().top - this.menu.outerHeight()/2 + currentItem.outerHeight()/2 );
				}
				// calculate offset
				var _offset = ( this.menu.offset().top  - currentItem.offset().top + ( this.button.outerHeight() - currentItem.outerHeight() ) / 2);
				$.extend( this.options.position, {
					my: "left top",
					at: "left top",
					offset: "0 " + _offset
				});
			}

			this.menuWrap
				.zIndex( this.element.zIndex() + 1 )
				.position( $.extend({
					of: this.button
				}, this.options.position ));

			this.isOpen = true;
			this._trigger( "open", event );
		}
	},

	close: function( event, focus ) {
		if ( this.isOpen ) {
			if ( this.options.dropdown ) {
				this.button
					.addClass( 'ui-corner-all' )
					.removeClass( 'ui-corner-top' );
			}

			this.menuWrap.removeClass( 'ui-selectmenu-open' );
			this.menu.attr("aria-hidden", true);
			this.isOpen = false;

			if ( focus ) {
				this.button.focus();
			}

			this._trigger( "close", event );
		}
	},

	widget: function() {
		return this.buttonWrap.add( this.menuWrap );
	},

	_renderMenu: function( ul, items ) {
		var that = this,
			currentOptgroup = "";

		$.each( items, function( index, item ) {
			if ( item.optgroup != currentOptgroup ) {
				var optgroup = $( '
' + item.optgroup + '
' );
				if ( item.element.parent( "optgroup" ).attr( "disabled" ) ) optgroup.addClass( 'ui-state-disabled' );
				ul.append( optgroup );
				currentOptgroup = item.optgroup;
			}
			that._renderItem( ul, item );
		});
	},

	_renderItem: function( ul, item) {
		var li = $( "
" ).data( "item.selectmenu", item );
		if ( item.disabled ) {
			li.addClass( 'ui-state-disabled' ).text( item.label );
		} else {
			li.append( $( "", {
					text: item.label,
					href: '#'
				})
			);
		}

		return li.appendTo( ul );
	},

	_move: function( key, event ) {
		if ( !this.isOpen )	{
			this.menu.menu( "focus", event, this._getSelectedItem() );
		}

		this.menu.menu( key, event );

		if ( !this.isOpen ) {
			this.menu.menu( "select", event  );
		}
	},

	_getSelectedItem: function() {
		return this.menu.find( "li" ).not( '.ui-selectmenu-optgroup' ).eq( this.element[0].selectedIndex );
	},

	_toggle: function( event ) {
		if ( this.isOpen ) {
			this.close( event );
		} else {
			this.open( event );
		}
	},

	_buttonEvents: {
		click: function( event ) {
			this._toggle( event );
			event.preventDefault();
		},
		keydown: function( event ) {
			switch (event.keyCode) {
				case $.ui.keyCode.TAB:
					if ( this.isOpen ) {
						this.close( event );
					}
					break;
				case $.ui.keyCode.ENTER:
					if ( this.isOpen ) {
						this.menu.menu( "select", this._getSelectedItem() );
					}
					event.preventDefault();
					break;
				case $.ui.keyCode.SPACE:
					event.preventDefault();
					break;
				case $.ui.keyCode.UP:
					if ( event.altKey ) {
						this._toggle( event );
					} else {
						this._move( "previous", event );
					}
					event.preventDefault();
					break;
				case $.ui.keyCode.DOWN:
					if ( event.altKey ) {
						this._toggle( event );
					} else {
						this._move( "next", event );
					}
					event.preventDefault();
					break;
				case $.ui.keyCode.LEFT:
					this._move( "previous", event );
					event.preventDefault();
					break;
				case $.ui.keyCode.RIGHT:
					this._move( "next", event );
					event.preventDefault();
					break;
				default:
					this.menu.trigger( event );
			}
		}
	},

	_setOption: function( key, value ) {
		this._super( key, value );

		if ( key === "appendTo" ) {
			this.menuWrap.appendTo( $( value || "body", this.element[0].ownerDocument )[0] );
		}
		if ( key === "value" && value !== undefined ) {
			this.element[0].value = value;
			this.button.children( '.ui-button-text' ).text( this.items[ this.element[0].selectedIndex ].label );
		}
		if ( key === "disabled" ) {
			this.button.button( "option", "disabled", value );
			if ( value ) {
				this.element.attr( "disabled", "disabled" );
				this.button.attr( "tabindex", -1 );
				this.close();
			} else {
				this.element.removeAttr( "disabled" );
				this.button.attr( "tabindex", 0 );
			}
			this.menu.attr( "aria-disabled", value );
		}
	},

	_readOptions: function() {
		var data = [];
		$.each( this.element.find( 'option' ), function( index, item ) {
			var option = $( item ),
				optgroup = option.parent( "optgroup" );
			data.push({
				element: option,
				index: index,
				value: option.attr( 'value' ),
				label: option.text(),
				optgroup: optgroup.attr( "label" ) || false,
				disabled: optgroup.attr( "disabled" ) || option.attr( "disabled" )
			});
		});
		this.items = data;
	},

	_destroy: function() {
		this.menuWrap.remove();
		this.buttonWrap.remove();
		this.element.show();
	}
});

}( jQuery ));
<|endoftext|>


<commit_before>const util = require('util');
import {
    translateSearch,
    translateAggBuckets,
    translateCrowdAggBuckets,
    translateOpenAggBuckets,
    translateOpenCrowdAggBuckets,
} from './translator';
import * as elastic from './elastic';
import { keysToCamel } from '../util/case.convert';
import logger from '../util/logger';
import { query } from '../util/db';

const QUERY_SHORT_LINK = 'select * from short_links where short=$1';
const QUERY_LONG_LINK = 'select * from short_links where long=$1';
const QUERY_NEW_HASH = `insert into short_links (short,long, created_at, updated_at) values ($1,$2, to_timestamp(${Date.now()} / 1000.0), to_timestamp(${Date.now()} / 1000.0))`;
const crypto = require('crypto');

export async function search(args) {
    logger.info('ARGS:', + args)
    try {
        // console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
        const translated = await translateSearch(args.params, true);
        // console.log("-------------->  ELASTIC SEARCH QUERY <------------- " + util.inspect(translated, false, null, true))
        let esResults = await elastic.query(translated);

        const studies = esResults.body.hits.hits
            .filter(study => (study._source.nct_id ? true : false))
            .map(study => esToGraphql(study));
        let aggs = [];
        for (const [key, value] of Object.entries(
            esResults.body.aggregations
        )) {
            const agg = aggToGraphql(key, value);
            aggs.push(agg);
        }
        // console.log(studies)
        return {
            recordsTotal: esResults.body.hits.total,
            studies,
            aggs,
        };
    } catch (err) {
        logger.error('Error running search: ' + err);
    }
}
export async function searchParams(args) {
    try {
        let params;
        const results = await query(QUERY_SHORT_LINK, [args.hash]);
        //logger.info('PARAMS', results)
        if (results.rows.length === 1) {
            const link = results.rows[0];
            params = link.long;
        }

        let parsedParams = JSON.parse(params);
        // The following if block is currently needed as there is still old hashes we need to handle.
        //Ruby syntax is to snake case so all hashes prior to node where using snake_case variables
        //Now that functionality of our searchPageHash mutation is being handled by node our hashes are being created with camelCased Values
        if (parsedParams['agg_filters'] || parsedParams['crowd_agg_filters']) {
            let aggFilter = [];
            parsedParams['agg_filters'].map((agg, index) => {
                let tempAgg = {};
                for (const [key, value] of Object.entries(agg)) {
                    if (key == 'include_missing_fields') {
                        tempAgg['includeMissingFields'] = value;
                    } else {
                        tempAgg[key] = value;
                    }
                }
                aggFilter.push(tempAgg);
            });
            parsedParams['agg_filters'] = aggFilter;

            let crowdAggFilter = [];
            parsedParams['crowd_agg_filters'].map((agg, index) => {
                let tempAgg = {};

                for (const [key, value] of Object.entries(agg)) {
                    if (key == 'include_missing_fields') {
                        tempAgg['includeMissingFields'] = value;
                    } else {
                        tempAgg[key] = value;
                    }
                }
                crowdAggFilter.push(tempAgg);
            });
            parsedParams['crowd_agg_filters'] = crowdAggFilter;
        }

        return {
            //reParsing to string as app is expecting that. May want to rework to just return JSON
            searchParams: JSON.stringify(parsedParams),
        };
    } catch (err) {
        logger.error('Error running search: ' + err);
    }
}
export async function provisionSearchHash(args) {
    try {
        logger.info('SEARCH_PAGE_HASH_MUTATION');
        let paramString = JSON.stringify(args.input.params);
        const results = await query(QUERY_LONG_LINK, [paramString]);
        let hash_short;
        if (results.rows.length === 1) {
            const link = results.rows[0];
            hash_short = link.short;
            console.log('HASH FOUND', hash_short);
            return { searchHash: { short: hash_short } };
        }
        console.log('No HASH!');
        const hash = crypto
            .createHash('sha256')
            .update(paramString)
            .digest('hex');
        console.log(hash);
        let short = hash.slice(0, 8);
        console.log('SHORT', short);
        const newHash = await query(QUERY_NEW_HASH, [short, paramString]);
        console.log('NewHASH', newHash);

        return { searchHash: { short: short } };
    } catch (err) {
        logger.error('Error running search: ' + err);
    }
}

export async function openCrowdAggBuckets(args) {
    try {
        const translated = await translateOpenCrowdAggBuckets(
            args.params,
            args.bucketsWanted
        );
        let esResults = await elastic.query(translated);
        // console.log("TRANSLATED OPEN Crowd Buckets" + util.inspect(translated, true, null, false))
        const studies = esResults.body.hits.hits.map(study =>
            esToGraphql(study)
        );
        let aggs = [];
        let i = 0;
        for (const [key, value] of Object.entries(
            esResults.body.aggregations
        )) {
            const agg = aggToGraphql2(key, value);
            if (args.bucketsWanted[i].values.length !== 0) {
                let finalBuckets = [];
                agg.buckets.map(bucket => {
                    for (const key of args.bucketsWanted[i].values) {
                        if (key == bucket.key) {
                            finalBuckets.push(bucket);
                        }
                    }
                });
                aggs.push({ ...agg, buckets: finalBuckets });
                i++;
            } else {
                aggs.push(agg);
                i++;
            }
        }
        return {
            recordsTotal: esResults.body.hits.total,
            aggs: aggs,
        };
    } catch (err) {
        logger.error(err);
    }
}
export async function openAggBuckets(args) {
    try {
        const translated = await translateOpenAggBuckets(
            args.params,
            args.bucketsWanted
        );
        let esResults = await elastic.query(translated);
        const studies = esResults.body.hits.hits.map(study =>
            esToGraphql(study)
        );
        let aggs = [];
        let i = 0;
        // console.log("TRANSLATED OPEN  Buckets" + util.inspect(translated,false,null,true))
        for (const [key, value] of Object.entries(
            esResults.body.aggregations
        )) {
            const agg = aggToGraphql2(key, value);
            if (args.bucketsWanted[i].values.length !== 0) {
                let finalBuckets = [];
                agg.buckets.map(bucket => {
                    for (const key of args.bucketsWanted[i].values) {
                        if (key == bucket.key) {
                            finalBuckets.push(bucket);
                        }
                    }
                });
                aggs.push({ ...agg, buckets: finalBuckets });
                i++;
            } else {
                aggs.push(agg);
                i++;
            }
        }
        return {
            recordsTotal: esResults.body.hits.total,
            aggs: aggs,
        };
    } catch (err) {
        logger.error(err);
    }
}

function esToGraphql(study) {
    let obj = keysToCamel(study._source);
    // console.log("--------->>>>>> STUDY <<<<<<-----------")
    //  console.log(study)
    obj.studyViewCount = obj.studyViewsCount;
    obj.isFdaRegulated = obj.isFdaRegulatedDrug | obj.isFdaRegulatedDevice;
    obj.averageRating = 0;
    return obj;
}

function aggToGraphql(key, value) {
    let buckets = [];
    if (value[key].buckets) {
        buckets = value[key].buckets.map(bucket => ({
            key: bucket.key,
            keyAsString: bucket.key,
            docCount: bucket.doc_count,
        }));
    }

    let agg = {
        name: key,
        buckets,
    };

    return agg;
}
function aggToGraphql2(key, value) {
    let buckets = [];
    if (value.buckets) {
        buckets = value.buckets.map(bucket => ({
            key: bucket.key,
            keyAsString: bucket.key,
            docCount: bucket.doc_count,
        }));
    }

    let agg = {
        name: key,
        buckets,
    };

    return agg;
}
<commit_msg>added log<commit_after>const util = require('util');
import {
    translateSearch,
    translateAggBuckets,
    translateCrowdAggBuckets,
    translateOpenAggBuckets,
    translateOpenCrowdAggBuckets,
} from './translator';
import * as elastic from './elastic';
import { keysToCamel } from '../util/case.convert';
import logger from '../util/logger';
import { query } from '../util/db';

const QUERY_SHORT_LINK = 'select * from short_links where short=$1';
const QUERY_LONG_LINK = 'select * from short_links where long=$1';
const QUERY_NEW_HASH = `insert into short_links (short,long, created_at, updated_at) values ($1,$2, to_timestamp(${Date.now()} / 1000.0), to_timestamp(${Date.now()} / 1000.0))`;
const crypto = require('crypto');

export async function search(args) {
    logger.info('ARGS!:', + args)

    try {
        // console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
        const translated = await translateSearch(args.params, true);
        // console.log("-------------->  ELASTIC SEARCH QUERY <------------- " + util.inspect(translated, false, null, true))
        let esResults = await elastic.query(translated);

        const studies = esResults.body.hits.hits
            .filter(study => (study._source.nct_id ? true : false))
            .map(study => esToGraphql(study));
        let aggs = [];
        for (const [key, value] of Object.entries(
            esResults.body.aggregations
        )) {
            const agg = aggToGraphql(key, value);
            aggs.push(agg);
        }
        // console.log(studies)
        return {
            recordsTotal: esResults.body.hits.total,
            studies,
            aggs,
        };
    } catch (err) {
        logger.error('Error running search: ' + err);
    }
}
export async function searchParams(args) {
    try {
        let params;
        const results = await query(QUERY_SHORT_LINK, [args.hash]);
        //logger.info('PARAMS', results)
        if (results.rows.length === 1) {
            const link = results.rows[0];
            params = link.long;
        }

        let parsedParams = JSON.parse(params);
        // The following if block is currently needed as there is still old hashes we need to handle.
        //Ruby syntax is to snake case so all hashes prior to node where using snake_case variables
        //Now that functionality of our searchPageHash mutation is being handled by node our hashes are being created with camelCased Values
        if (parsedParams['agg_filters'] || parsedParams['crowd_agg_filters']) {
            let aggFilter = [];
            parsedParams['agg_filters'].map((agg, index) => {
                let tempAgg = {};
                for (const [key, value] of Object.entries(agg)) {
                    if (key == 'include_missing_fields') {
                        tempAgg['includeMissingFields'] = value;
                    } else {
                        tempAgg[key] = value;
                    }
                }
                aggFilter.push(tempAgg);
            });
            parsedParams['agg_filters'] = aggFilter;

            let crowdAggFilter = [];
            parsedParams['crowd_agg_filters'].map((agg, index) => {
                let tempAgg = {};

                for (const [key, value] of Object.entries(agg)) {
                    if (key == 'include_missing_fields') {
                        tempAgg['includeMissingFields'] = value;
                    } else {
                        tempAgg[key] = value;
                    }
                }
                crowdAggFilter.push(tempAgg);
            });
            parsedParams['crowd_agg_filters'] = crowdAggFilter;
        }

        return {
            //reParsing to string as app is expecting that. May want to rework to just return JSON
            searchParams: JSON.stringify(parsedParams),
        };
    } catch (err) {
        logger.error('Error running search: ' + err);
    }
}
export async function provisionSearchHash(args) {
    try {
        logger.info('SEARCH_PAGE_HASH_MUTATION');
        let paramString = JSON.stringify(args.input.params);
        const results = await query(QUERY_LONG_LINK, [paramString]);
        let hash_short;
        if (results.rows.length === 1) {
            const link = results.rows[0];
            hash_short = link.short;
            console.log('HASH FOUND', hash_short);
            return { searchHash: { short: hash_short } };
        }
        console.log('No HASH!');
        const hash = crypto
            .createHash('sha256')
            .update(paramString)
            .digest('hex');
        console.log(hash);
        let short = hash.slice(0, 8);
        console.log('SHORT', short);
        const newHash = await query(QUERY_NEW_HASH, [short, paramString]);
        console.log('NewHASH', newHash);

        return { searchHash: { short: short } };
    } catch (err) {
        logger.error('Error running search: ' + err);
    }
}

export async function openCrowdAggBuckets(args) {
    try {
        const translated = await translateOpenCrowdAggBuckets(
            args.params,
            args.bucketsWanted
        );
        let esResults = await elastic.query(translated);
        // console.log("TRANSLATED OPEN Crowd Buckets" + util.inspect(translated, true, null, false))
        const studies = esResults.body.hits.hits.map(study =>
            esToGraphql(study)
        );
        let aggs = [];
        let i = 0;
        for (const [key, value] of Object.entries(
            esResults.body.aggregations
        )) {
            const agg = aggToGraphql2(key, value);
            if (args.bucketsWanted[i].values.length !== 0) {
                let finalBuckets = [];
                agg.buckets.map(bucket => {
                    for (const key of args.bucketsWanted[i].values) {
                        if (key == bucket.key) {
                            finalBuckets.push(bucket);
                        }
                    }
                });
                aggs.push({ ...agg, buckets: finalBuckets });
                i++;
            } else {
                aggs.push(agg);
                i++;
            }
        }
        return {
            recordsTotal: esResults.body.hits.total,
            aggs: aggs,
        };
    } catch (err) {
        logger.error(err);
    }
}
export async function openAggBuckets(args) {
    try {
        const translated = await translateOpenAggBuckets(
            args.params,
            args.bucketsWanted
        );
        let esResults = await elastic.query(translated);
        const studies = esResults.body.hits.hits.map(study =>
            esToGraphql(study)
        );
        let aggs = [];
        let i = 0;
        // console.log("TRANSLATED OPEN  Buckets" + util.inspect(translated,false,null,true))
        for (const [key, value] of Object.entries(
            esResults.body.aggregations
        )) {
            const agg = aggToGraphql2(key, value);
            if (args.bucketsWanted[i].values.length !== 0) {
                let finalBuckets = [];
                agg.buckets.map(bucket => {
                    for (const key of args.bucketsWanted[i].values) {
                        if (key == bucket.key) {
                            finalBuckets.push(bucket);
                        }
                    }
                });
                aggs.push({ ...agg, buckets: finalBuckets });
                i++;
            } else {
                aggs.push(agg);
                i++;
            }
        }
        return {
            recordsTotal: esResults.body.hits.total,
            aggs: aggs,
        };
    } catch (err) {
        logger.error(err);
    }
}

function esToGraphql(study) {
    let obj = keysToCamel(study._source);
    // console.log("--------->>>>>> STUDY <<<<<<-----------")
    //  console.log(study)
    obj.studyViewCount = obj.studyViewsCount;
    obj.isFdaRegulated = obj.isFdaRegulatedDrug | obj.isFdaRegulatedDevice;
    obj.averageRating = 0;
    return obj;
}

function aggToGraphql(key, value) {
    let buckets = [];
    if (value[key].buckets) {
        buckets = value[key].buckets.map(bucket => ({
            key: bucket.key,
            keyAsString: bucket.key,
            docCount: bucket.doc_count,
        }));
    }

    let agg = {
        name: key,
        buckets,
    };

    return agg;
}
function aggToGraphql2(key, value) {
    let buckets = [];
    if (value.buckets) {
        buckets = value.buckets.map(bucket => ({
            key: bucket.key,
            keyAsString: bucket.key,
            docCount: bucket.doc_count,
        }));
    }

    let agg = {
        name: key,
        buckets,
    };

    return agg;
}
<|endoftext|>


<commit_before>const DrawCard = require('../../../drawcard.js');

class LadyInWaiting extends DrawCard {
    setupCardAbilities() {
        this.playAction({
            title: 'Marshal as dupe',
            condition: () => this.canMarshalAsDupe(),
            handler: () => {
                this.game.promptForSelect(this.controller, {
                    activePromptTitle: 'Select a Lady character',
                    cardCondition: card => card.location === 'play area' && card.getType() === 'character' && card.hasTrait('Lady'),
                    onSelect: (player, card) => this.marshalAsDupe(card)
                });
            }
        });
    }

    canMarshalAsDupe() {
        return (
            this.game.currentPhase === 'marshal' &&
            this.canBeMarshaled() &&
            this.controller.isCardInPlayableLocation(this, 'marshal') &&
            this.controller.anyCardsInPlay(card => card.getType() === 'character' && card.hasTrait('Lady'))
        );
    }

    marshalAsDupe(card) {
        this.controller.removeCardFromPile(this);
        card.addDuplicate(this);
        this.game.addMessage('{0} places {1} on {2} as a duplicate', this.controller, this, card);
        return true;
    }
}

LadyInWaiting.code = '02023';

module.exports = LadyInWaiting;
<commit_msg>Allow Lady-In-Waiting to only target cards that can be duped (owned and controlled)<commit_after>const DrawCard = require('../../../drawcard.js');

class LadyInWaiting extends DrawCard {
    setupCardAbilities() {
        this.playAction({
            title: 'Marshal as dupe',
            condition: () => this.canMarshalAsDupe(),
            handler: () => {
                this.game.promptForSelect(this.controller, {
                    activePromptTitle: 'Select a Lady character',
                    cardCondition: card => card.location === 'play area' && card.getType() === 'character' && card.hasTrait('Lady') &&
                                           card.controller === this.controller && card.owner === this.controller,
                    onSelect: (player, card) => this.marshalAsDupe(card)
                });
            }
        });
    }

    canMarshalAsDupe() {
        return (
            this.game.currentPhase === 'marshal' &&
            this.canBeMarshaled() &&
            this.controller.isCardInPlayableLocation(this, 'marshal') &&
            this.controller.anyCardsInPlay(card => card.getType() === 'character' && card.hasTrait('Lady'))
        );
    }

    marshalAsDupe(card) {
        this.controller.removeCardFromPile(this);
        card.addDuplicate(this);
        this.game.addMessage('{0} places {1} on {2} as a duplicate', this.controller, this, card);
        return true;
    }
}

LadyInWaiting.code = '02023';

module.exports = LadyInWaiting;
<|endoftext|>


<commit_before>/**
	_moon.ExpandablePicker_ is based on _moon.ExpandableListItem_, and is used to as a
	drop-down picker menu that solicits a choice from the user. The picker's child
	components, typically multiple _moon.LabeledCheckbox_es, become the options for
	the picker.

		{kind: "moon.ExpandablePicker", noneText: "None Selected", content: "Choose City", components: [
			{content: "San Francisco"},
			{content: "Boston"},
			{content: "Tokyo"}
		]}

	The picker can be programmatically changed by modifying the published properties
	_selectedIndex_ or _selected_ by calling the appropriate setter functions
	(_setSelectedIndex()_ and _getSelectedIndex()_).

	The _onChange_ event is fired when the selected item changes, and contains the following
	properties:

		{
			selected: [object Object],	// Reference to selected item
			content: "San Francisco",	// Content of selected item
			index: 1					// Index of selected item
		}

	Picker options can be adjusted programmatically using standard means, by calling
	_createComponent()/render()_ or _destroy()_.

		// Add new items to picker
		this.$.expandablePicker.createComponent({"New York"}).render();
		this.$.expandablePicker.createComponent({"London"}).render();

		// Remove currently selected item from picker
		this.$.expandablePicker.getSelected().destroy();

	When the picker is minimized, the content of the currently selected item is displayed
	as subtext below the picker label.
*/
enyo.kind({
	name: "moon.ExpandablePicker",
	kind: "moon.ExpandableListItem",
	classes: "moon-expandable-picker",
	events: {
		/**
			Fires when the currently selected item changes.

			_inEvent.selected_ contains a reference to the currently selected item.
			_inEvent.content_ contains the content of the currently selected item.
			_inEvent.index_ contains the index of the currently selected item.
		*/
		onChange: ""
	},
	published: {
		//* Reference to currently selected item, if any.
		selected: null,
		//* Index of currently selected item, if any.
		selectedIndex: -1,
		//* Text to be displayed in the _currentValue_ control if no item is currently selected.
		noneText: ""
	},
	//* @protected
	defaultKind: "moon.LabeledCheckbox",
	handlers: {
		onActivate: "activated",
		requestScrollIntoView: "requestScrollIntoView"
	},
	components: [
		{name: "header", kind: "moon.Item", classes: "moon-expandable-picker-header", spotlight: true,
			onSpotlightFocus: "headerFocus", ontap: "expandContract", onSpotlightSelect: "expandContract"
		},
		{name: "drawer", kind: "moon.Drawer", onStep: "drawerAnimationStep", components: [
		// NOTE: Replaced moon.Drawer with onyx.Drawer, because moon.Drawer is not in master moonraker branch, please move it to master before using in code. Lex.
			{name: "client", kind: "Group", highlander: true}
		]},
		{name: "currentValue", kind: "moon.Item", spotlight: false, classes: "moon-expandable-picker-current-value", ontap: "expandContract", content: ""},
		{name: "bottom", kind: "enyo.Control", spotlight: true, onSpotlightFocus: "spotlightFocusBottom"}
	],
	create: function() {
		this.inherited(arguments);
		this.initializeActiveItem();
		this.noneTextChanged();
	},
	//* When the _selected_ control changes, update _checked_ values appropriately and fire an onChange event
	selectedChanged: function() {
		var selected = this.getSelected(),
			controls = this.getClientControls(),
			index = -1;

		for(var i=0;i<controls.length;i++) {
			if(controls[i] === selected) {
				controls[i].setChecked(true);
				index = i;
			} else {
				controls[i].setChecked(false);
			}
		}

		if(index > -1 && index !== this.getSelectedIndex()) {
			this.setSelectedIndex(index);
			this.$.currentValue.setContent(selected.getContent());
			this.fireChangeEvent();
		}
	},
	//* When the _selectedIndex_ changes, call _this.setChecked()_ on the appropriate control
	selectedIndexChanged: function() {
		var selected = this.getSelected(),
			controls = this.getClientControls(),
			index = this.getSelectedIndex();

		if(controls[index] && controls[index] !== selected) {
			this.setSelected(controls[index]);
		}
	},
	//* If no selected item, use _this.noneText_ for current value
	noneTextChanged: function() {
		if(this.getSelected() === null && this.getSelectedIndex() === -1) {
			this.$.currentValue.setContent(this.getNoneText());
		}
	},
	//* When _this.open_ changes, show/hide _this.$.currentValue_
	openChanged: function() {
		this.inherited(arguments);
		this.$.currentValue.setShowing(!this.$.drawer.getOpen());
	},
	/*
		When the picker is initialized, look for any items with an active:true flag, and
		set them to be the currently selected item. This is done without triggering an
		onChange event, as this happens during initialization.
	*/
	initializeActiveItem: function() {
		var controls = this.getClientControls();
		for(var i=0;i<controls.length;i++) {
			if(controls[i].active) {
				this.selectedIndex = i;
				this.selected = controls[i];
				this.$.currentValue.setContent(controls[i].getContent());
				controls[i].setChecked(true);
				return;
			}
		}
	},
	//* When an item is chosen, mark it as checked, and close the picker.
	activated: function(inSender, inEvent) {
		var index = this.getClientControls().indexOf(inEvent.toggledControl),
			_this = this;

		if(inEvent.checked && index > -1) {
			this.setSelected(inEvent.toggledControl);
			// If _autoCollapse_ is set to true and this control is rendered, auto collapse.
			if(this.getAutoCollapse() && this.isRendered) {
				setTimeout(function() {
					_this.setOpen(false);
					enyo.Spotlight.spot(_this);
				}, 300);
			}
		}
	},
	//* Fire an onChange event
	fireChangeEvent: function() {
		this.doChange({
			selected: this.getSelected(),
			content: this.getSelected().getContent(),
			index: this.getSelectedIndex()
		});
	}
});
<commit_msg>https://jira2.palm.com/browse/GF-2293 adding call to incorporate the selectedIndex initial value on kind creation<commit_after>/**
	_moon.ExpandablePicker_ is based on _moon.ExpandableListItem_, and is used to as a
	drop-down picker menu that solicits a choice from the user. The picker's child
	components, typically multiple _moon.LabeledCheckbox_es, become the options for
	the picker.

		{kind: "moon.ExpandablePicker", noneText: "None Selected", content: "Choose City", components: [
			{content: "San Francisco"},
			{content: "Boston"},
			{content: "Tokyo"}
		]}

	The picker can be programmatically changed by modifying the published properties
	_selectedIndex_ or _selected_ by calling the appropriate setter functions
	(_setSelectedIndex()_ and _getSelectedIndex()_).

	The _onChange_ event is fired when the selected item changes, and contains the following
	properties:

		{
			selected: [object Object],	// Reference to selected item
			content: "San Francisco",	// Content of selected item
			index: 1					// Index of selected item
		}

	Picker options can be adjusted programmatically using standard means, by calling
	_createComponent()/render()_ or _destroy()_.

		// Add new items to picker
		this.$.expandablePicker.createComponent({"New York"}).render();
		this.$.expandablePicker.createComponent({"London"}).render();

		// Remove currently selected item from picker
		this.$.expandablePicker.getSelected().destroy();

	When the picker is minimized, the content of the currently selected item is displayed
	as subtext below the picker label.
*/
enyo.kind({
	name: "moon.ExpandablePicker",
	kind: "moon.ExpandableListItem",
	classes: "moon-expandable-picker",
	events: {
		/**
			Fires when the currently selected item changes.

			_inEvent.selected_ contains a reference to the currently selected item.
			_inEvent.content_ contains the content of the currently selected item.
			_inEvent.index_ contains the index of the currently selected item.
		*/
		onChange: ""
	},
	published: {
		//* Reference to currently selected item, if any.
		selected: null,
		//* Index of currently selected item, if any.
		selectedIndex: -1,
		//* Text to be displayed in the _currentValue_ control if no item is currently selected.
		noneText: ""
	},
	//* @protected
	defaultKind: "moon.LabeledCheckbox",
	handlers: {
		onActivate: "activated",
		requestScrollIntoView: "requestScrollIntoView"
	},
	components: [
		{name: "header", kind: "moon.Item", classes: "moon-expandable-picker-header", spotlight: true,
			onSpotlightFocus: "headerFocus", ontap: "expandContract", onSpotlightSelect: "expandContract"
		},
		{name: "drawer", kind: "moon.Drawer", onStep: "drawerAnimationStep", components: [
		// NOTE: Replaced moon.Drawer with onyx.Drawer, because moon.Drawer is not in master moonraker branch, please move it to master before using in code. Lex.
			{name: "client", kind: "Group", highlander: true}
		]},
		{name: "currentValue", kind: "moon.Item", spotlight: false, classes: "moon-expandable-picker-current-value", ontap: "expandContract", content: ""},
		{name: "bottom", kind: "enyo.Control", spotlight: true, onSpotlightFocus: "spotlightFocusBottom"}
	],
	create: function() {
		this.inherited(arguments);
		this.initializeActiveItem();
		this.selectedIndexChanged();
		this.noneTextChanged();
	},
	//* When the _selected_ control changes, update _checked_ values appropriately and fire an onChange event
	selectedChanged: function() {
		var selected = this.getSelected(),
			controls = this.getClientControls(),
			index = -1;

		for(var i=0;i<controls.length;i++) {
			if(controls[i] === selected) {
				controls[i].setChecked(true);
				index = i;
			} else {
				controls[i].setChecked(false);
			}
		}

		if(index > -1 && index !== this.getSelectedIndex()) {
			this.setSelectedIndex(index);
			this.$.currentValue.setContent(selected.getContent());
			this.fireChangeEvent();
		}
	},
	//* When the _selectedIndex_ changes, call _this.setChecked()_ on the appropriate control
	selectedIndexChanged: function() {
		var selected = this.getSelected(),
			controls = this.getClientControls(),
			index = this.getSelectedIndex();

		if(controls[index] && controls[index] !== selected) {
			this.setSelected(controls[index]);
		}
	},
	//* If no selected item, use _this.noneText_ for current value
	noneTextChanged: function() {
		if(this.getSelected() === null && this.getSelectedIndex() === -1) {
			this.$.currentValue.setContent(this.getNoneText());
		}
	},
	//* When _this.open_ changes, show/hide _this.$.currentValue_
	openChanged: function() {
		this.inherited(arguments);
		this.$.currentValue.setShowing(!this.$.drawer.getOpen());
	},
	/*
		When the picker is initialized, look for any items with an active:true flag, and
		set them to be the currently selected item. This is done without triggering an
		onChange event, as this happens during initialization.
	*/
	initializeActiveItem: function() {
		var controls = this.getClientControls();
		for(var i=0;i<controls.length;i++) {
			if(controls[i].active) {
				this.selectedIndex = i;
				this.selected = controls[i];
				this.$.currentValue.setContent(controls[i].getContent());
				controls[i].setChecked(true);
				return;
			}
		}
	},
	//* When an item is chosen, mark it as checked, and close the picker.
	activated: function(inSender, inEvent) {
		var index = this.getClientControls().indexOf(inEvent.toggledControl),
			_this = this;

		if(inEvent.checked && index > -1) {
			this.setSelected(inEvent.toggledControl);
			// If _autoCollapse_ is set to true and this control is rendered, auto collapse.
			if(this.getAutoCollapse() && this.isRendered) {
				setTimeout(function() {
					_this.setOpen(false);
					enyo.Spotlight.spot(_this);
				}, 300);
			}
		}
	},
	//* Fire an onChange event
	fireChangeEvent: function() {
		this.doChange({
			selected: this.getSelected(),
			content: this.getSelected().getContent(),
			index: this.getSelectedIndex()
		});
	}
});
<|endoftext|>


<commit_before>'use strict';

const { URL, URLSearchParams } = require('url');
const axios = require('axios');
const EventSource = require('eventsource');

function formatParams(params)
{
    return new URLSearchParams(params).toString();
}

class TrackedEventSource extends EventSource
{
    constructor(owner, url, config)
    {
        super(url, config);

        this.owner = owner;
    }

    close(unregister = true)
    {
        if (unregister)
            this.owner.unregisterEventSource(this);

        super.close();
    }
}

class RequestHandler
{
    constructor(baseUrl)
    {
        this.baseUrl = baseUrl;
    }

    init(config)
    {
        if (this.axios)
            this.shutdown();

        this.lastStatus = 0;
        this.cancelSource = axios.CancelToken.source();
        this.eventSources = new Set();

        const fullConfig = Object.assign({
            baseURL: this.baseUrl,
            timeout: 5000,
            paramsSerializer: formatParams,
            cancelToken: this.cancelSource.token
        }, config);

        this.axios = axios.create(fullConfig);
        this.auth = fullConfig.auth || null;
    }

    shutdown()
    {
        if (this.cancelSource)
        {
            this.cancelSource.cancel('Abort');
            this.cancelSource = null;
        }

        if (this.eventSources)
        {
            for (let source of this.eventSources)
                source.close(false);

            this.eventSources = null;
        }

        this.axios = null;
        this.auth = null;
    }

    async get(url, params)
    {
        this.lastStatus = 0;
        const config = params ? { params } : undefined;
        const result = await this.axios.get(url, config);
        this.lastStatus = result.status;
        return result.data;
    }

    async post(url, data)
    {
        this.lastStatus = 0;
        const result = await this.axios.post(url, data);
        this.lastStatus = result.status;
        return result.data;
    }

    createEventSource(url, callback, params)
    {
        const urlObj = new URL(url, this.baseUrl);

        if (params)
            urlObj.search = formatParams(params);

        const source = new TrackedEventSource(
            this, urlObj.toString(), this.getEventSourceConfig());

        source.addEventListener('message', event => {
            callback(JSON.parse(event.data));
        });

        this.eventSources.add(source);
        return source;
    }

    unregisterEventSource(source)
    {
        this.eventSources.delete(source);
    }

    getEventSourceConfig()
    {
        if (!this.auth)
            return null;

        const authData = Buffer
            .from(`${this.auth.username}:${this.auth.password}`)
            .toString('base64');

        return {
            headers: {
                'Authorization': 'Basic ' + authData,
            },
        };
    }
}

module.exports = RequestHandler;
<commit_msg>preserve axios config<commit_after>'use strict';

const { URL, URLSearchParams } = require('url');
const axios = require('axios');
const EventSource = require('eventsource');

function formatParams(params)
{
    return new URLSearchParams(params).toString();
}

class TrackedEventSource extends EventSource
{
    constructor(owner, url, config)
    {
        super(url, config);

        this.owner = owner;
    }

    close(unregister = true)
    {
        if (unregister)
            this.owner.unregisterEventSource(this);

        super.close();
    }
}

class RequestHandler
{
    constructor(baseUrl)
    {
        this.baseUrl = baseUrl;
    }

    init(config)
    {
        if (this.axios)
            this.shutdown();

        this.lastStatus = 0;
        this.cancelSource = axios.CancelToken.source();
        this.eventSources = new Set();

        const fullConfig = Object.assign({
            baseURL: this.baseUrl,
            timeout: 5000,
            paramsSerializer: formatParams,
            cancelToken: this.cancelSource.token
        }, config);

        this.axios = axios.create(fullConfig);
        this.axiosConfig = fullConfig;
    }

    shutdown()
    {
        if (this.cancelSource)
        {
            this.cancelSource.cancel('Abort');
            this.cancelSource = null;
        }

        if (this.eventSources)
        {
            for (let source of this.eventSources)
                source.close(false);

            this.eventSources = null;
        }

        this.axios = null;
        this.axiosConfig = null;
    }

    async get(url, params)
    {
        this.lastStatus = 0;
        const config = params ? { params } : undefined;
        const result = await this.axios.get(url, config);
        this.lastStatus = result.status;
        return result.data;
    }

    async post(url, data)
    {
        this.lastStatus = 0;
        const result = await this.axios.post(url, data);
        this.lastStatus = result.status;
        return result.data;
    }

    createEventSource(url, callback, params)
    {
        const urlObj = new URL(url, this.baseUrl);

        if (params)
            urlObj.search = formatParams(params);

        const source = new TrackedEventSource(
            this, urlObj.toString(), this.getEventSourceConfig());

        source.addEventListener('message', event => {
            callback(JSON.parse(event.data));
        });

        this.eventSources.add(source);
        return source;
    }

    unregisterEventSource(source)
    {
        this.eventSources.delete(source);
    }

    getEventSourceConfig()
    {
        if (!this.axiosConfig.auth)
            return null;

        const { username, password } = this.axiosConfig.auth;

        const authData = Buffer
            .from(`${username}:${password}`)
            .toString('base64');

        return {
            headers: {
                'Authorization': 'Basic ' + authData,
            },
        };
    }
}

module.exports = RequestHandler;
<|endoftext|>


<commit_before>const { Command } = require('../../core')

class Slots extends Command {
  constructor (...args) {
    super(...args, {
      name: 'slots',
      description: 'Slot machine command',
      usage: [{ name: 'bet', type: 'int', optional: true, default: 1 }],
      aliases: ['slot'],
      cooldown: 3
    })

    this.reel = [
      '🍇', '🍊', '🇱🇻', '🍈', '🍌', '🍒', '🍉', '🔔', '💎', '🍐', '🍇', '🍊',
      '🍈', '🍌', '🍒', '🍉', '🔔', '🍇', '🇱🇻', '💎', '🍌', '🍐', '🍊'
    ]

    this.wins = {
      '🍒 x 1': 2,
      '🍒 x 2': 5,
      '🍒 x 3': 10,
      '7⃣ x 2': 50,
      '7⃣ x 3': 150,
      '🍐 x 3': 20,
      '🍈 x 3': 20,
      '🍇 x 3': 20,
      '🍊 x 3': 20,
      '💎 x 2': 25,
      '💎 x 3': 200,
      '🔔 x 3': 50,
      '🍉 x 3': 20,
      '🇱🇻 x 2': 40,
      '🇱🇻 x 3': 100
    }
  }

  get generateSlots () {
    const reels = this.reel
    let machine = []
    for (let i = 0; i < 3; i++) {
      const res = ~~(Math.random() * (reels.length - 2))
      machine.push(reels.slice(res, res + 3))
    }
    return machine
  }

  checkWinnings (payline, amt) {
    let wins = []
    const res = payline.reduce((p, c) => {
      p[c] = (p[c] || 0) + 1
      return p
    }, {})
    for (const r in res) {
      const v = `${r} x ${res[r]}`
      if (this.wins[v]) wins.push([v, this.wins[v] * amt])
    }
    return wins
  }

  async handle ({ msg, args, data, settings }, responder) {
    const user = await data.User.fetch(msg.author.id)
    if (args.bet > 1000) args.bet = 1000
    if (user.credits < args.bet) {
      return responder.error('{{insufficient}}', {
        amount: `**${args.bet - user.credits}**`,
        command: `**\`${settings.prefix}wage\`**`
      })
    }

    const machine = this.generateSlots
    let payline = [machine[0][1], machine[1][1], machine[2][1]]

    const winnings = this.checkWinnings(payline, args.bet)
    try {
      user.credits -= args.bet
      for (const win of winnings) {
        user.credits += win[1]
      }
      await user.save()
    } catch (err) {
      return responder.error()
    }
    return responder.send([
      '**__   S   L   O   T   S   __**',
      `|| ${machine[0][0]} ${machine[1][0]} ${machine[2][0]} ||`,
      `> ${payline.join(' ')} <`,
      `|| ${machine[0][2]} ${machine[1][2]} ${machine[2][2]} ||\n`,
      winnings.length
      ? `{{won}}\n\n${winnings.map(w => `${w[0]}: **${w[1]} {{credits}}**`).join('\n')}`
      : '{{lost}}'
    ], {
      user: `**${msg.author.username}**`,
      amount: `**${args.bet}**`
    })
  }
}

module.exports = Slots
<commit_msg>:bug: Slots bet less than 1<commit_after>const { Command } = require('../../core')

class Slots extends Command {
  constructor (...args) {
    super(...args, {
      name: 'slots',
      description: 'Slot machine command',
      usage: [{ name: 'bet', type: 'int', optional: true, default: 1 }],
      aliases: ['slot'],
      cooldown: 3
    })

    this.reel = [
      '🍇', '🍊', '🇱🇻', '🍈', '🍌', '🍒', '🍉', '🔔', '💎', '🍐', '🍇', '🍊',
      '🍈', '🍌', '🍒', '🍉', '🔔', '🍇', '🇱🇻', '💎', '🍌', '🍐', '🍊'
    ]

    this.wins = {
      '🍒 x 1': 2,
      '🍒 x 2': 5,
      '🍒 x 3': 10,
      '7⃣ x 2': 50,
      '7⃣ x 3': 150,
      '🍐 x 3': 20,
      '🍈 x 3': 20,
      '🍇 x 3': 20,
      '🍊 x 3': 20,
      '💎 x 2': 25,
      '💎 x 3': 200,
      '🔔 x 3': 50,
      '🍉 x 3': 20,
      '🇱🇻 x 2': 40,
      '🇱🇻 x 3': 100
    }
  }

  get generateSlots () {
    const reels = this.reel
    let machine = []
    for (let i = 0; i < 3; i++) {
      const res = ~~(Math.random() * (reels.length - 2))
      machine.push(reels.slice(res, res + 3))
    }
    return machine
  }

  checkWinnings (payline, amt) {
    let wins = []
    const res = payline.reduce((p, c) => {
      p[c] = (p[c] || 0) + 1
      return p
    }, {})
    for (const r in res) {
      const v = `${r} x ${res[r]}`
      if (this.wins[v]) wins.push([v, this.wins[v] * amt])
    }
    return wins
  }

  async handle ({ msg, args, data, settings }, responder) {
    const user = await data.User.fetch(msg.author.id)
    if (args.bet > 1000) args.bet = 1000
    if (args.bet < 1) args.bet = 1
    if (user.credits < args.bet) {
      return responder.error('{{insufficient}}', {
        amount: `**${args.bet - user.credits}**`,
        command: `**\`${settings.prefix}wage\`**`
      })
    }

    const machine = this.generateSlots
    let payline = [machine[0][1], machine[1][1], machine[2][1]]

    const winnings = this.checkWinnings(payline, args.bet)
    try {
      user.credits -= args.bet
      for (const win of winnings) {
        user.credits += win[1]
      }
      await user.save()
    } catch (err) {
      return responder.error()
    }
    return responder.send([
      '**__   S   L   O   T   S   __**',
      `|| ${machine[0][0]} ${machine[1][0]} ${machine[2][0]} ||`,
      `> ${payline.join(' ')} <`,
      `|| ${machine[0][2]} ${machine[1][2]} ${machine[2][2]} ||\n`,
      winnings.length
      ? `{{won}}\n\n${winnings.map(w => `${w[0]}: **${w[1]} {{credits}}**`).join('\n')}`
      : '{{lost}}'
    ], {
      user: `**${msg.author.username}**`,
      amount: `**${args.bet}**`
    })
  }
}

module.exports = Slots
<|endoftext|>


<commit_before>//Copyright 2012 Telefonica Investigación y Desarrollo, S.A.U
//
//This file is part of RUSH.
//
//  RUSH is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public
//  License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
//  version.
//  RUSH is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
//
//  You should have received a copy of the GNU Affero General Public License along with RUSH
//  . If not, seehttp://www.gnu.org/licenses/.
//
//For those usages not covered by the GNU Affero General Public License please contact with::dtc_support@tid.es

var stackParser = require('stack-parser');
var globals = require('./globals.js');
var defaultConfig = require('./defaultConfig.js').defaultConfig;
var consoleTransport = require('./transports/console.js');
var fileTransport = require('./transports/file.js');

var config = defaultConfig;
var logger = null;

function createDefaultLogger(config) {

  if (config) {

    logger = {};

    //Copy config
    logger.config = {};
    for (var property in config) {
      if (config.hasOwnProperty(property)) {
        logger.config[property] = config[property];
      }
    }

    //Set default properties
    logger.config.logLevel = logger.config.logLevel || defaultConfig.logLevel;

    if (logger.config.inspectDepth === undefined) {
      logger.config.inspectDepth = defaultConfig.inspectDepth;
    }

    if (logger.config.enableForceLog === undefined) {
      logger.config.enableForceLog = defaultConfig.enableForceLog;
    }

    /**
     *
     * @param level Standard default values (DEBUG, INFO, NOTICE, WARNING, ERROR, CRIT, ALERT, EMERG)
     * @param message Log Message
     * @param logObj An object or an array that will be printed after the message
     * @returns {*}
     */
    logger.log = function (level, message, logObj) {

      for (var i = 0; i < this.transports.length; i++) {

        var transport = this.transports[i];
        var transportLevel = transport.level || this.config.logLevel;

        if (globals.DEFAULTL_LEVELS[level] >= globals.DEFAULTL_LEVELS[transportLevel] ||
            (this.config.enableForceLog && logObj[globals.FORCE])) {
          transport.log(level, message, logObj);
        }
      }
    };

    //Transports
    logger.transports = [];

    if (config.Console) {
      logger.transports.push(new consoleTransport.Console(config.Console, logger.config.inspectDepth));
    }

    if (config.File) {
      logger.transports.push(new fileTransport.File(config.File, logger.config.inspectDepth));
    }

    //Exit on error
    var exitOnError = function (err) {

      var exit = config.exitOnError || true,
          logType, logMsg;

      var component = {};

      //Parse stack
      try {
        var items = stackParser.parse(err.stack);
        component = items[0] || {};
      } catch(e) {
        //Nothing to do...
      }

      //Log message
      logger.log('emerg', err.message, {component: component.file, line: component.line } );

      //Exit (due requirements)
      if (exit) {
        process.exit(-1);
      }
      return exit;
    }

    process.on('uncaughtException', exitOnError);

  } else {
    throw new Error('Logger cannot be created without a configuration');
  }

}

function setConfig(newCfg) {
  'use strict';
  config = newCfg;
  createDefaultLogger(config);
}

function newLogger() {
  'use strict';

  //Create default logger
  if (!logger) {
    createDefaultLogger(config);
  }

  var moduleLogger = {};
  var myLogger = logger;

  moduleLogger.log = function(level, message, logObj) {

    logObj = logObj || {};
    logObj.component = logObj.component === undefined ? this.prefix : logObj.component;

    myLogger.log(level, message, logObj);
  };

  //Methods
  for (var lvl in globals.DEFAULTL_LEVELS) {
    if (globals.DEFAULTL_LEVELS.hasOwnProperty(lvl)) {
      moduleLogger[lvl] = function _block(aLevel) {
        return function (msg, obj) {
          return moduleLogger.log(aLevel, msg, obj);
        };
      }(lvl);
    }
  }

  // legacy
  moduleLogger.warning = moduleLogger.warn;

  return moduleLogger;
}

exports.newLogger = newLogger;
exports.setConfig = setConfig;
/*
 debug: 0,
 info: 1,
 notice: 2,
 warning: 3,
 error: 4,
 crit: 5,
 alert: 6,
 emerg: 7

 The list of syslog severity Levels:
 0 Emergency: system is unusable
 1 Alert: action must be taken immediately
 2 Critical: critical conditions
 3 Error: error conditions
 4 Warning: warning conditions
 5 Notice: normal but significant condition
 6 Informational: informational messages
 7 Debug: debug-level messages
 Recommended practice is to use the Notice or Informational level for normal messages.

 A detailed explanation of the severity Levels:
 DEBUG:
 Info useful to developers for debugging the application, not useful during operations
 INFORMATIONAL:
 Normal operational messages - may be harvested for reporting, measuring throughput, etc - no action required
 NOTICE:
 Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot
 potential problems - no immediate action required
 WARNING:
 Warning messages - not an error, but indication that an error will occur if action is not taken, e.g. file system 85%
 full - each item must be resolved within a given time
 ERROR:
 Non-urgent failures - these should be relayed to developers or admins; each item must be resolved within a given time
 ALERT:
 Should be corrected immediately - notify staff who can fix the problem - example is loss of backup ISP connection
 CRITICAL:
 Should be corrected immediately, but indicates failure in a primary system - fix CRITICAL problems before ALERT -
 example is loss of primary ISP connection
 EMERGENCY:
 A "panic" condition - notify all tech staff on call? (earthquake? tornado?) - affects multiple apps/servers/sites...

 */
<commit_msg>Logger refactor<commit_after>//Copyright 2012 Telefonica Investigación y Desarrollo, S.A.U
//
//This file is part of RUSH.
//
//  RUSH is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public
//  License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
//  version.
//  RUSH is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
//
//  You should have received a copy of the GNU Affero General Public License along with RUSH
//  . If not, seehttp://www.gnu.org/licenses/.
//
//For those usages not covered by the GNU Affero General Public License please contact with::dtc_support@tid.es

var stackParser = require('stack-parser');
var globals = require('./globals.js');
var defaultConfig = require('./defaultConfig.js').defaultConfig;
var consoleTransport = require('./transports/console.js');
var fileTransport = require('./transports/file.js');

var logger = null;            //Current logger used. A new Logger will be created whenever config is changed.
var loggers = [];             //This array is need to log messages on each logger on uncaughtException.

function createDefaultLogger(config) {

  if (!config) {
    throw new Error('Logger cannot be created without a configuration');
  } else {

    logger = {};

    //Copy config
    logger.config = {};
    for (var property in config) {
      if (config.hasOwnProperty(property)) {
        logger.config[property] = config[property];
      }
    }

    //Set default properties
    logger.config.logLevel = logger.config.logLevel || defaultConfig.logLevel;

    logger.config.inspectDepth = logger.config.inspectDepth === undefined ?
        defaultConfig.inspectDepth : logger.config.inspectDepth;

    logger.config.enableForceLog = logger.config.enableForceLog === undefined ?
        defaultConfig.enableForceLog : logger.config.enableForceLog;

    /**
     *
     * @param level Standard default values (DEBUG, INFO, NOTICE, WARNING, ERROR, CRIT, ALERT, EMERG)
     * @param message Log Message
     * @param logObj An object or an array that will be printed after the message
     * @returns {*}
     */
    logger.log = function (level, message, logObj) {

      for (var i = 0; i < this.transports.length; i++) {

        var transport = this.transports[i];
        var transportLevel = transport.level || this.config.logLevel;

        if (globals.DEFAULTL_LEVELS[level] >= globals.DEFAULTL_LEVELS[transportLevel] ||
            (this.config.enableForceLog && logObj[globals.FORCE])) {
          transport.log(level, message, logObj);
        }
      }
    };

    //Transports
    logger.transports = [];

    if (config.Console) {
      logger.transports.push(new consoleTransport.Console(config.Console, logger.config.inspectDepth));
    }

    if (config.File) {
      logger.transports.push(new fileTransport.File(config.File, logger.config.inspectDepth));
    }

    //Push logger into loggers array
    loggers.push(logger);

  }

}

function setConfig(newCfg) {
  'use strict';
  createDefaultLogger(newCfg);
}

function newLogger() {
  'use strict';

  //Create default logger
  if (!logger) {
    createDefaultLogger(defaultConfig);
  }

  var moduleLogger = {};
  var currentLogger = logger;

  moduleLogger.log = function(level, message, logObj) {

    logObj = logObj || {};
    logObj.component = logObj.component === undefined ? this.prefix : logObj.component;

    currentLogger.log(level, message, logObj);
  };

  //Set a method for each log level (debug, info, warn, err,...)
  for (var lvl in globals.DEFAULTL_LEVELS) {
    if (globals.DEFAULTL_LEVELS.hasOwnProperty(lvl)) {
      moduleLogger[lvl] = moduleLogger.log.bind(moduleLogger, lvl);
    }
  }

  // legacy
  moduleLogger.warning = moduleLogger.warn;

  return moduleLogger;
}

//Exit on error
var exitOnError = function (err) {

  var exit, logType = 'emerg';

  var component = {};

  //Parse stack
  try {
    var items = stackParser.parse(err.stack);
    component = items[0] || {};
  } catch(e) {
    //Nothing to do...
  }

  //Log message on each logger
  loggers.forEach(function(logger) {
    exit = exit || logger.config.exitOnError;
    logger.log(logType, err.message, {component: component.file, line: component.line } );
  });

  //Exit (due requirements)
  //Program will exit if at least one logger wants to exit
  if (exit) {
    process.exit(-1);
  }
  return exit;
}

process.on('uncaughtException', exitOnError);

exports.newLogger = newLogger;
exports.setConfig = setConfig;
/*
 debug: 0,
 info: 1,
 notice: 2,
 warning: 3,
 error: 4,
 crit: 5,
 alert: 6,
 emerg: 7

 The list of syslog severity Levels:
 0 Emergency: system is unusable
 1 Alert: action must be taken immediately
 2 Critical: critical conditions
 3 Error: error conditions
 4 Warning: warning conditions
 5 Notice: normal but significant condition
 6 Informational: informational messages
 7 Debug: debug-level messages
 Recommended practice is to use the Notice or Informational level for normal messages.

 A detailed explanation of the severity Levels:
 DEBUG:
 Info useful to developers for debugging the application, not useful during operations
 INFORMATIONAL:
 Normal operational messages - may be harvested for reporting, measuring throughput, etc - no action required
 NOTICE:
 Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot
 potential problems - no immediate action required
 WARNING:
 Warning messages - not an error, but indication that an error will occur if action is not taken, e.g. file system 85%
 full - each item must be resolved within a given time
 ERROR:
 Non-urgent failures - these should be relayed to developers or admins; each item must be resolved within a given time
 ALERT:
 Should be corrected immediately - notify staff who can fix the problem - example is loss of backup ISP connection
 CRITICAL:
 Should be corrected immediately, but indicates failure in a primary system - fix CRITICAL problems before ALERT -
 example is loss of primary ISP connection
 EMERGENCY:
 A "panic" condition - notify all tech staff on call? (earthquake? tornado?) - affects multiple apps/servers/sites...

 */
<|endoftext|>