<commit_before>import React, { useEffect, useState } from 'react';
import {
  Button,
  Page,
  PageHeader,
  PageSidebar,
  PageHeaderTools,
  PageHeaderToolsItem,
  TextInput,
  Brand,
  Dropdown,
  DropdownToggle,
  DropdownItem,
  DropdownGroup,
  Divider,
  SkipToContent
} from '@patternfly/react-core';
import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
import ExternalLinkAltIcon from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon';
import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
import { SideNav, TopNav, GdprBanner } from '../../components';
import staticVersions from '../../versions.json';
import logo from '../logo.svg';
import './sideNavLayout.css';

const HeaderTools = ({
  versions,
  hasVersionSwitcher,
  hasSearch,
  pathPrefix
}) => {
  const initialVersion = staticVersions.Releases.find(release => release.latest);
  const [isDropdownOpen, setDropdownOpen] = useState(false);
  const [isSearchExpanded, setSearchExpanded] = useState(false);
  const latestVersion = versions.Releases.find(version => version.latest);
  const getDropdownItem = version => (
    <DropdownItem
      key={version.name}
      component={
        <a href={version.latest ? pathPrefix : `/${version.name}`}>
          {`Release ${version.name}`}

      }
    />
  );
  const searchRef = React.useRef();

  return (
    <PageHeaderTools>
      {hasSearch && (
        <PageHeaderToolsItem id="ws-global-search-wrapper" className={isSearchExpanded ? '' : 'ws-hide-search-input'}>
          <TextInput id="ws-global-search" ref={searchRef} placeholder="Search" />
          {isSearchExpanded && <SearchIcon className="global-search-icon" />}
        </PageHeaderToolsItem>
      )}
      {hasSearch && (
        <Button
          aria-label={`${isSearchExpanded ? 'Collapse' : 'Expand'} search input`}
          variant="plain"
          className="ws-toggle-search"
          onClick={() => {
            setSearchExpanded(!isSearchExpanded);
            if (!isSearchExpanded) {
              setTimeout(() => searchRef.current && searchRef.current.focus(), 0);
            }
          }}
        >
          {isSearchExpanded
            ? <TimesIcon />
            : <SearchIcon className="global-search-icon" />
          }
        </Button>
      )}
      {hasVersionSwitcher && (
        <PageHeaderToolsItem>
          <Dropdown
            className="ws-org-version-switcher"
            onSelect={() => setDropdownOpen(!isDropdownOpen)}
            toggle={(
              <DropdownToggle
                className={`ws-org-version-toggle${isDropdownOpen ? '-expanded': ''}`}
                onToggle={() => setDropdownOpen(!isDropdownOpen)}
              >
                Release {initialVersion.name}
              </DropdownToggle>
            )}
            isOpen={isDropdownOpen}
            dropdownItems={[
              <DropdownGroup key="latest" label="Latest">
                {getDropdownItem(latestVersion)}
              </DropdownGroup>,
              <DropdownGroup key="Previous" label="Previous releases">
                {Object.values(versions.Releases)
                  .filter(version => !version.hidden && !version.latest)
                  .slice(0,3)
                  .map(getDropdownItem)}
              </DropdownGroup>,
              <Divider key="divider" className="ws-switcher-divider"/>,
              <DropdownItem
                key="PatternFly 3"
                className="ws-patternfly-3"
                target="_blank"
                href="https://www.patternfly.org/v3"
              >
                PatternFly 3
                <ExternalLinkAltIcon />
              </DropdownItem>
            ]}
          />
        </PageHeaderToolsItem>
      )}
    </PageHeaderTools>
  );
}

// https://github.com/algolia/autocomplete.js#global-options
export function attachDocSearch(algolia, inputSelector, timeout) {
  if (window.docsearch) {
    return window.docsearch({
      inputSelector,
      autocompleteOptions: {
        hint: false,
        appendTo: `${inputSelector}-wrapper`,
      },
      debug: process.env.NODE_ENV !== 'production',
      ...algolia
    });
  }
  else {
    setTimeout(() => attachDocSearch(algolia, inputSelector, timeout), timeout);
  }
}

export const SideNavLayout = ({ children, groupedRoutes }) => {
  const pathPrefix = process.env.pathPrefix;
  const algolia = process.env.algolia;
  const hasGdprBanner = process.env.hasGdprBanner;
  const hasVersionSwitcher = process.env.hasVersionSwitcher;
  const sideNavItems = process.env.sideNavItems;
  const topNavItems = process.env.topNavItems;
  const prnum = process.env.prnum;
  const prurl = process.env.prurl;

  const [versions, setVersions] = useState({ ...staticVersions });

  useEffect(() => {
    if (typeof window === 'undefined') {
      return;
    }
    if (algolia) {
      attachDocSearch(algolia, '#ws-global-search', 1000);
    }
    if (hasVersionSwitcher && window.fetch) {
      fetch('/versions.json').then(res => {
        if (res.ok) {
          res.json().then(json => setVersions(json));
        }
      });
    }
  }, []);

  const SideBar = (
    <PageSidebar
      className="ws-page-sidebar"
      theme="light"
      nav={<SideNav navItems={sideNavItems} groupedRoutes={groupedRoutes} />}
    />
  );

  const Header = (
    <PageHeader
      className="ws-page-header"
      headerTools={(algolia || hasVersionSwitcher) && <HeaderTools
        versions={versions}
        hasSearch={algolia}
        hasVersionSwitcher={hasVersionSwitcher}
        pathPrefix={pathPrefix} />}
      logo={prnum ? `PR #${prnum}` : <Brand src={logo} alt="Patternfly Logo" />}
      logoProps={{ href: prurl || pathPrefix || '/' }}
      showNavToggle
      topNav={topNavItems.length > 0 && <TopNav navItems={topNavItems} />}
    />
  );

  return (
    <React.Fragment>

        {hasGdprBanner && <GdprBanner />}

      <Page
        id="ws-page"
        mainContainerId="ws-page-main"
        header={Header}
        sidebar={SideBar}
        isManagedSidebar
        skipToContent={<SkipToContent href="#ws-page-main">Skip to content</SkipToContent>}
      >
        {children}
      </Page>
    </React.Fragment>
  );
}
<commit_msg>fix latest version switcher (#2257)<commit_after>import React, { useEffect, useState } from 'react';
import {
  Button,
  Page,
  PageHeader,
  PageSidebar,
  PageHeaderTools,
  PageHeaderToolsItem,
  TextInput,
  Brand,
  Dropdown,
  DropdownToggle,
  DropdownItem,
  DropdownGroup,
  Divider,
  SkipToContent
} from '@patternfly/react-core';
import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
import ExternalLinkAltIcon from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon';
import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
import { SideNav, TopNav, GdprBanner } from '../../components';
import staticVersions from '../../versions.json';
import logo from '../logo.svg';
import './sideNavLayout.css';

const HeaderTools = ({
  versions,
  hasVersionSwitcher,
  hasSearch,
  pathPrefix
}) => {
  const initialVersion = staticVersions.Releases.find(release => release.latest);
  const [isDropdownOpen, setDropdownOpen] = useState(false);
  const [isSearchExpanded, setSearchExpanded] = useState(false);
  const latestVersion = versions.Releases.find(version => version.latest);
  const getDropdownItem = version => (
    <DropdownItem
      key={version.name}
      component={
        <a href={version.latest ? '/v4' : `/${version.name}`}>
          {`Release ${version.name}`}

      }
    />
  );
  const searchRef = React.useRef();

  return (
    <PageHeaderTools>
      {hasSearch && (
        <PageHeaderToolsItem id="ws-global-search-wrapper" className={isSearchExpanded ? '' : 'ws-hide-search-input'}>
          <TextInput id="ws-global-search" ref={searchRef} placeholder="Search" />
          {isSearchExpanded && <SearchIcon className="global-search-icon" />}
        </PageHeaderToolsItem>
      )}
      {hasSearch && (
        <Button
          aria-label={`${isSearchExpanded ? 'Collapse' : 'Expand'} search input`}
          variant="plain"
          className="ws-toggle-search"
          onClick={() => {
            setSearchExpanded(!isSearchExpanded);
            if (!isSearchExpanded) {
              setTimeout(() => searchRef.current && searchRef.current.focus(), 0);
            }
          }}
        >
          {isSearchExpanded
            ? <TimesIcon />
            : <SearchIcon className="global-search-icon" />
          }
        </Button>
      )}
      {hasVersionSwitcher && (
        <PageHeaderToolsItem>
          <Dropdown
            className="ws-org-version-switcher"
            onSelect={() => setDropdownOpen(!isDropdownOpen)}
            toggle={(
              <DropdownToggle
                className={`ws-org-version-toggle${isDropdownOpen ? '-expanded': ''}`}
                onToggle={() => setDropdownOpen(!isDropdownOpen)}
              >
                Release {initialVersion.name}
              </DropdownToggle>
            )}
            isOpen={isDropdownOpen}
            dropdownItems={[
              <DropdownGroup key="latest" label="Latest">
                {getDropdownItem(latestVersion)}
              </DropdownGroup>,
              <DropdownGroup key="Previous" label="Previous releases">
                {Object.values(versions.Releases)
                  .filter(version => !version.hidden && !version.latest)
                  .slice(0,3)
                  .map(getDropdownItem)}
              </DropdownGroup>,
              <Divider key="divider" className="ws-switcher-divider"/>,
              <DropdownItem
                key="PatternFly 3"
                className="ws-patternfly-3"
                target="_blank"
                href="https://www.patternfly.org/v3"
              >
                PatternFly 3
                <ExternalLinkAltIcon />
              </DropdownItem>
            ]}
          />
        </PageHeaderToolsItem>
      )}
    </PageHeaderTools>
  );
}

// https://github.com/algolia/autocomplete.js#global-options
export function attachDocSearch(algolia, inputSelector, timeout) {
  if (window.docsearch) {
    return window.docsearch({
      inputSelector,
      autocompleteOptions: {
        hint: false,
        appendTo: `${inputSelector}-wrapper`,
      },
      debug: process.env.NODE_ENV !== 'production',
      ...algolia
    });
  }
  else {
    setTimeout(() => attachDocSearch(algolia, inputSelector, timeout), timeout);
  }
}

export const SideNavLayout = ({ children, groupedRoutes }) => {
  const pathPrefix = process.env.pathPrefix;
  const algolia = process.env.algolia;
  const hasGdprBanner = process.env.hasGdprBanner;
  const hasVersionSwitcher = process.env.hasVersionSwitcher;
  const sideNavItems = process.env.sideNavItems;
  const topNavItems = process.env.topNavItems;
  const prnum = process.env.prnum;
  const prurl = process.env.prurl;

  const [versions, setVersions] = useState({ ...staticVersions });

  useEffect(() => {
    if (typeof window === 'undefined') {
      return;
    }
    if (algolia) {
      attachDocSearch(algolia, '#ws-global-search', 1000);
    }
    if (hasVersionSwitcher && window.fetch) {
      fetch('/versions.json').then(res => {
        if (res.ok) {
          res.json().then(json => setVersions(json));
        }
      });
    }
  }, []);

  const SideBar = (
    <PageSidebar
      className="ws-page-sidebar"
      theme="light"
      nav={<SideNav navItems={sideNavItems} groupedRoutes={groupedRoutes} />}
    />
  );

  const Header = (
    <PageHeader
      className="ws-page-header"
      headerTools={(algolia || hasVersionSwitcher) && <HeaderTools
        versions={versions}
        hasSearch={algolia}
        hasVersionSwitcher={hasVersionSwitcher}
        pathPrefix={pathPrefix} />}
      logo={prnum ? `PR #${prnum}` : <Brand src={logo} alt="Patternfly Logo" />}
      logoProps={{ href: prurl || pathPrefix || '/' }}
      showNavToggle
      topNav={topNavItems.length > 0 && <TopNav navItems={topNavItems} />}
    />
  );

  return (
    <React.Fragment>

        {hasGdprBanner && <GdprBanner />}

      <Page
        id="ws-page"
        mainContainerId="ws-page-main"
        header={Header}
        sidebar={SideBar}
        isManagedSidebar
        skipToContent={<SkipToContent href="#ws-page-main">Skip to content</SkipToContent>}
      >
        {children}
      </Page>
    </React.Fragment>
  );
}
<|endoftext|>


<commit_before>import DS from 'ember-data';

import OsfModel from 'ember-osf/models/base';

export default OsfModel.extend({
    full_name: DS.attr('string'),
    given_name: DS.attr('string'),
    middle_names: DS.attr(),
    family_name: DS.attr('string'),

    nodes: DS.hasMany('nodes')
});
<commit_msg>CamelCase user model fields<commit_after>import DS from 'ember-data';

import OsfModel from 'ember-osf/models/base';

export default OsfModel.extend({
    fullName: DS.attr('string'),
    givenName: DS.attr('string'),
    middleNames: DS.attr(),
    familyName: DS.attr('string'),

    nodes: DS.hasMany('nodes')
});
<|endoftext|>


<commit_before>Router.configure({
    layoutTemplate: 'ApplicationLayout'
});

Router.map(function() {

    this.route('/',
        {
            layoutTemplate: 'ApplicationLayout',
            yieldTemplates: {
                'header': {to: 'header'},
                'footer': {to: 'footer'},
            }
        }
    );

    this.route('login',
        {
            layoutTemplate: 'login',
            onBeforeAction: function(){
                if(Meteor.userId2 === undefined){
                    Router.go('/login');
                }

                Accounts.ui.config({
                    /*requestPermissions: {
                        facebook: ['user_likes']
                    },*/
                    requestOfflineToken: {
                        google: true
                    },
                    passwordSignupFields: 'EMAIL_ONLY'
                });

                this.next();
            }
        }
    );

});
<commit_msg>Alterando alguns espaços e indentação (OK)<commit_after>Router.configure({
    layoutTemplate: 'ApplicationLayout'
});

Router.map(function() {

    this.route('/', {
      layoutTemplate: 'ApplicationLayout',
      yieldTemplates: {
          'header': {to: 'header'},
          'footer': {to: 'footer'},
      }
    });

    this.route('login', {
      layoutTemplate: 'login',
      onBeforeAction: function(){
        if(Meteor.userId2 === undefined){
            Router.go('/login');
        }

        Accounts.ui.config({
            /*requestPermissions: {
                facebook: ['user_likes']
            },*/
            requestOfflineToken: {
                google: true
            },
            passwordSignupFields: 'EMAIL_ONLY'
        });

        this.next();
      }
    });

});
<|endoftext|>


<commit_before>app.controller('FileEditorController', function($scope, $timeout, WorkspaceService) {

  var aceModeList = ace.require("ace/ext/modelist");

  $scope.files = null;
  $scope.tabsScroll = {};

  function findCurrentActiveFile() {
    for(var i = 0; i < $scope.files.length; i++) {
      if($scope.files[i].active)
        return i;
    }
    return -1;
  }

  function deactivateAll() {
    angular.forEach($scope.files, function(file) {
      file.active = false;
    });
  }

  function saveFile(file) {
    cancelScheduledSave(file);
    WorkspaceService.request('save', file.path, file.data);
  }

  function cancelScheduledSave(file) {
    $timeout.cancel(file.scheduledSave);
    delete file.scheduledSave;
  }

  function scheduleFileSave(file) {
    cancelScheduledSave(file);
    file.scheduledSave = $timeout(function() {
      saveFile(file);
    }, 1000);
  }

  function startWatchingFile(file) {
    $scope.files[file.path] = file;
    file.dismiss = $scope.$watch('files["' + file.path + '"].data', function(newData, oldData) {
      if(newData != oldData)
        scheduleFileSave(file);
    });
  }

  function stopWatchFile(file) {
    delete $scope.files[file.path];
    file.dismiss();
  }

  function initFile(path, data) {
    var pos = findCurrentActiveFile() + 1;
    var file;
    for(var i = 0; i < $scope.files.length; i++) {
      if($scope.files[i].path == path) {
        file = $scope.files[i];
        break;
      }
    }
    if(file == null) {
      file = {
        path: path,
        data: data,
        aceOptions: {
          theme: 'merbivore_soft',
          mode: aceModeList.getModeForPath(path).name
        }
      };
      $scope.files.splice(pos, 0, file);
      startWatchingFile(file);
    }
    showFile(file)
  }

  function prepareTabScroll() {
    $timeout(function() {
      $scope.tabsScroll.doRecalculate();
      $scope.tabsScroll.scrollTabIntoView();
    });
  }

  function showFile(file) {
    deactivateAll();
    file.active = true;
    prepareTabScroll();
  }

  $scope.focusFile = function() {
    for(var i = 0; i < $scope.files.length; i++) {
      var file = $scope.files[i];
      if(file.scheduledSave != null)
        saveFile(file);
    }
  };

  $scope.closeFile = function(file) {
    var index = $scope.files.indexOf(file);
    if(file.active) {
      file.active = false;
      var neighbour = index == $scope.files.length - 1 ? $scope.files[index - 1] : $scope.files[index + 1];
      if(neighbour != null)
        neighbour.active = true;
    }
    $scope.files.splice(index, 1);
    prepareTabScroll();
    stopWatchFile(file);
    saveFile(file);
  };

  $scope._fileClass = function(file) {
    var classes = [];
    if(file.scheduledSave != null)
      classes.push('file-dirty');
    return classes.join(' ');
  };

  $scope.$on('ready', function() {
    $scope.files = [];
  });

  $scope.$on('open-file', function(event, path) {
    var file = $scope.files[path];
    if(file != null)
      showFile(file);
    else
      WorkspaceService.request('file', path);
  });

  $scope.$on('file', function(event, response) {
    initFile(response.target, response.data);
  });

});<commit_msg>use ace callback instead of watch<commit_after>app.controller('FileEditorController', function($scope, $timeout, WorkspaceService) {

  var aceModeList = ace.require("ace/ext/modelist");

  $scope.files = null;
  $scope.tabsScroll = {};

  function findCurrentActiveFile() {
    for(var i = 0; i < $scope.files.length; i++) {
      if($scope.files[i].active)
        return i;
    }
    return -1;
  }

  function deactivateAll() {
    angular.forEach($scope.files, function(file) {
      file.active = false;
    });
  }

  function saveFile(file) {
    cancelScheduledSave(file);
    WorkspaceService.request('save', file.path, file.data);
  }

  function cancelScheduledSave(file) {
    $timeout.cancel(file.scheduledSave);
    delete file.scheduledSave;
  }

  function scheduleFileSave(file) {
    cancelScheduledSave(file);
    file.scheduledSave = $timeout(function() {
      saveFile(file);
    }, 1000);
  }

  function createFileTab(path, data) {
    var ret = {
      path: path,
      data: data,
      initialized: false,
      aceOptions: {
        theme: 'merbivore_soft',
        mode: aceModeList.getModeForPath(path).name,
        onChange: function() {
          if(!ret.initialized)
            ret.initialized = true;
          else
            scheduleFileSave(ret);
        }
      }
    };
    return ret;
  }

  function initFile(path, data) {
    var pos = findCurrentActiveFile() + 1;
    var file = createFileTab(path, data);
    $scope.files.splice(pos, 0, file);
    $scope.files[path] = file;
    showFile(file)
  }

  function prepareTabScroll() {
    $timeout(function() {
      $scope.tabsScroll.doRecalculate();
      $scope.tabsScroll.scrollTabIntoView();
    });
  }

  function showFile(file) {
    deactivateAll();
    file.active = true;
    prepareTabScroll();
  }

  $scope.focusFile = function() {
    for(var i = 0; i < $scope.files.length; i++) {
      var file = $scope.files[i];
      if(file.scheduledSave != null)
        saveFile(file);
    }
  };

  $scope.closeFile = function(file) {
    var index = $scope.files.indexOf(file);
    if(file.active) {
      file.active = false;
      var neighbour = index == $scope.files.length - 1 ? $scope.files[index - 1] : $scope.files[index + 1];
      if(neighbour != null)
        neighbour.active = true;
    }
    $scope.files.splice(index, 1);
    delete $scope.files[file.path];
    prepareTabScroll();
    saveFile(file);
  };

  $scope._fileClass = function(file) {
    var classes = [];
    if(file.scheduledSave != null)
      classes.push('file-dirty');
    return classes.join(' ');
  };

  $scope.$on('ready', function() {
    $scope.files = [];
  });

  $scope.$on('open-file', function(event, path) {
    var file = $scope.files[path];
    if(file != null)
      showFile(file);
    else
      WorkspaceService.request('file', path);
  });

  $scope.$on('file', function(event, response) {
    initFile(response.target, response.data);
  });

});<|endoftext|>


<commit_before>(function() {

  function warnMessage(entry) {
    var markup = "";
    if (entry.warn_message) {
      markup += ""
    }
    return markup;
  }

  function userEntryDefaultFormatter(entry) {
    var markup = "";
    if (entry.displayIcon && entry.type) {
      if (entry.type == "USER_TYPE") {
        markup += "";
      } else if (entry.type == "GROUP_TYPE") {
        markup += "";
      }
    }
    markup += entry.displayLabel;
    markup += warnMessage(entry);
    return markup;
  }

  function docEntryDefaultFormatter(doc) {
    var markup = "

";
    markup += "
";
    if (doc.properties && doc.properties['common:icon']) {
      markup += ""
    }
    markup += "	";
    markup += doc.title;
    markup += warnMessage(doc);
    if (doc.path) {
      markup += "" + doc.path + "";
    }
    markup += "

"
    return markup;
  }

  function dirEntryDefaultFormatter(entry) {
    var markup = entry.displayLabel;
    markup += warnMessage(entry);
    return markup;
  }

  var userSelectionDefaultFormatter = userEntryDefaultFormatter;

  function docSelectionDefaultFormatter(doc) {
    var markup = "";
    if (doc.properties && doc.properties['common:icon']) {
      markup += ""
    }
    markup += getDocLinkElt(doc);
    markup += warnMessage(doc);
    return markup;
  }

  function dirSelectionDefaultFormatter(entry) {
    var markup = entry.absoluteLabel;
    markup += warnMessage(entry);
    return markup;
  }

  function getOperationName(params) {
    var opName = params.operationId;
    if (typeof (opName) == 'undefined' || opName == '') {
      if (params.directoryName && params.directoryName.length > 0) {
        opName = 'Directory.SuggestEntries';
      } else {
        opName = 'Document.PageProvider';
      }
    }
    return opName;
  }

  function getDocLinkElt(doc) {
    if (doc.contextParameters) {
      var url = doc.contextParameters.documentURL;
      var markup = "" + doc.title + ""
      return markup;
    } else {
      return doc.title;
    }
  }

  function getUrlWithConversationId(url) {
    return url + "?conversationId=" + currentConversationId;
  }

  function configureOperationParameters(op, params, query) {
    var temp = {};
    jQuery.extend(temp, params);
    temp.lang = currentUserLang;
    if (params.operationId == 'Directory.SuggestEntries') {
      // build default operation for Directory
      temp.searchTerm = query.term;
    } else if (params.operationId == 'UserGroup.Suggestion') {
      temp.searchTerm = query.term;
      temp.searchType = params.userSuggestionSearchType;
    } else if (params.operationId == 'Document.PageProvider') {
      // build default operation for Document
      temp.searchTerm = query.term + "%";
      temp.query = params.query;
      temp.providerName = params.pageProviderName;
      temp.page = "0";
      temp.pageSize = "20";
    } else {
      // custom operation, pass at least the query term
      temp.searchTerm = query.term;
    }
    if (typeof currentConversationId != 'undefined') {
      // Give needed info to restore Seam context
      op.addParameter("id", getOperationName(params));
      op.addParameter("conversationId", currentConversationId);
      op.opts.automationParams.context = temp;
    } else {
      op.addParameters(temp);
    }
  }

  function fillResult(results, data, params) {
    if (typeof(data.length) != "undefined") {
      // default result parsing for Directory entries
      for (i = 0; i < data.length; i++) {
        var entry = data[i];
        results.push(entry);
      }
    } else if (typeof(data.entries) != "undefined") {
      // default result parsing for Documents
      for (i = 0; i < data.entries.length; i++) {
        var doc = data.entries[i];
        results.push(doc);
      }
    } else {
      alert("Error with suggestion widget");
    }
  }

  function getDefaultLabel(item) {
    if (item.displayLabel) {
      return item.displayLabel;
    } else {
      return item.title;
    }
  }

  function getDefaultId(item) {
    if (item.computedId) {
      return item.computedId;
    } else if (item.uid) {
      return item.uid;
    } else {
      return item.id;
    }
  }

  function initSelect2Widget(el) {
    // retrieve parameters from Html
    var elid = el.attr("id");
    var params = {};

    var paramId = (elid + "_params").split(":").join("\\:");
    var paramsHolder = jQuery("#" + paramId);
    params = JSON.parse(paramsHolder.val());

    var readonly = params.readonly == 'true';
    var required = params.required == 'true';

    var initId = (elid + "_init").split(":").join("\\:");
    var initHolder = jQuery("#" + initId);
    var initDoc = null;
    try {
      initDoc = JSON.parse(initHolder.val());
    } catch (err) {
      // console.log("Unable to parse initvalue", err, initHolder.val())
    }

    // set style on select
    el.css("width", params.width);

    // determine operation name
    var opName = getOperationName(params);

    // define automation params
    var automationParams = {
      "documentSchemas" : params.documentSchemas
    };

    if (params.repository) {
      automationParams.repository = params.repository;
    }

    // init Automation Operation
    var op = null;
    if (typeof currentConversationId != 'undefined') {
      // If Seam context is available, let's restore it
      op = jQuery().automation('Seam.RunOperation', automationParams);
    } else {
      op = jQuery().automation(opName, automationParams);
    }

    // detect if we need custom selection formatting
    var selectionFormatterFunction = null;
    if (params.selectionFormatter && params.selectionFormatter.length > 0) {
      selectionFormatterFunction = eval(params.selectionFormatter);
    }
    // detect if we need custom suggestion formatting
    var suggestionFormatterFunction = null;
    if (params.suggestionFormatter && params.suggestionFormatter.length > 0) {
      suggestionFormatterFunction = eval(params.suggestionFormatter);
    }

    // build select2 parameters
    var select2_params = {
      containerCssClass : params.containerCssClass,
      dropdownCssClass : params.dropdownCssClass,
      minimumInputLength : params.minChars,
      query : function(query) {

        configureOperationParameters(op, params, query);

        op.execute(function(data, textStatus, xhr) {
          var results = [];
          fillResult(results, data, params)
          query.callback({
            results : results
          });
        });
      }
    }

    // append custom selection formatter if needed
    if (selectionFormatterFunction != null) {
      select2_params.formatSelection = selectionFormatterFunction;
    } else {
      select2_params.formatSelection = function(doc) {
        if (select2_params.labelFieldName != null) {
          return doc.properties[select2_params.labelFieldName];
        } else {
          return getDefaultLabel(doc)
        }
      };
    }
    // append custom suggestion formatter if needed
    if (suggestionFormatterFunction != null) {
      select2_params.formatResult = suggestionFormatterFunction;
    } else {
      select2_params.formatResult = getDefaultLabel;
    }

    // append id formatter if needed
    if (params.idProperty && params.idProperty.length > 0) {
      select2_params.id = function(doc) {
        return doc.properties[params.idProperty];
      };
    } else if (params.idFunction) {
      select2_params.id = eval(params.idFunction);
    } else if (params.prefixed) {
      select2_params.id = function(item) {
        return item.prefixed_id;
      };
    } else {
      select2_params.id = getDefaultId;
    }

    if (initDoc != null) {
      select2_params.initSelection = function(element, callback) {
        callback(initDoc);
      };
    }

    if (params.multiple == 'true') {
      select2_params.maximumSelectionSize = params.maximumSelectionSize;
      select2_params.multiple = true;
    }

    if (params.placeholder && !readonly) {
      select2_params.placeholder = params.placeholder;
      select2_params.allowClear = !required;
    }

    // dropdown on arrow only
    if (params.dropdownOnArrow == 'true' && params.multiple == 'false') {
      select2_params.dropdownOnArrow = true;
    }

    // separator
    if (params.separator) {
      select2_params.separator = params.separator;
    }

    // init select2
    el.select2(select2_params);

    // view or edit mode
    if (readonly) {
      el.select2("readonly", true);
    }

    if (!readonly) {

      // Make selected items sortable
      if (params.multiple == 'true' && params.orderable == 'true') {
        el.select2("container").find("ul.select2-choices").sortable({
          containment : 'parent',
          start : function() {
            el.select2("onSortStart");
          },
          update : function() {
            el.select2("onSortEnd");
          }
        });
      }

      // Handle onclick widget property
      el.on("select2-opening", function(e) {
        if (params.onclick) {
          eval(params.onclick);
        }
      });

      // trigger for safeEdit restore
      el.on("change", function(e) {
        if (e) {
          if (e.added) {
            var newValue;
            if (select2_params.multiple) {
              var newObj = JSON.parse(initHolder.val());
              newObj.push(e.added);
              var newValue = JSON.stringify(newObj);
            } else {
              newValue = JSON.stringify(e.added);
            }
            initHolder.val(newValue);
          }

          if (e.removed) {
            var removedId = select2_params.id(e.removed);
            if (select2_params.multiple) {
              var newValue = '';
              var tempObj = JSON.parse(initHolder.val());
              jQuery.each(tempObj, function(index, result) {
                if (result) {
                  if (select2_params.id(result) == removedId) {
                    tempObj.splice(index, 1);
                  }
                }
              });
              newValue = JSON.stringify(tempObj);
              initHolder.val(newValue);
            } else {
              if (initHolder.val() == removedId) {
                initHolder.val('');
              }
            }
          }
        }

        // ReRender any jsf component if needed.
        if (params.reRenderFunctionName) {
          window[params.reRenderFunctionName]();
        }

        // Handle onchange widget property
        if (params.onchange) {
          eval(params.onchange);
        }

      });
    }

    var $parentForm = jQuery(el).closest("form");
    if ($parentForm.hasClass("safeEditEnabled")) {
        // Register postRestore function for safeEdit
        jQuery(el).closest("form").registerPostRestoreCallBacks(function(data) {
          initSelect2Widget(jQuery(el));
        });
      }
  }

  window.initSelect2AjaxWidget = function initSelect2AjaxWidget(widgetId, index) {

    var selector = "input[type='hidden'][id$=";

    if (index != null && index.length > 0) {
      selector = selector + index + "\\:";
    }
    selector = selector + widgetId + "_select2]";

    jQuery(selector).each(function(idx, el) {
      initSelect2Widget(jQuery(el));
    });

  }

  window.initSelect2Widgets = function initSelect2Widgets() {
    jQuery("input[type='hidden'][id$=select2]").each(function(idx, el) {
      initSelect2Widget(jQuery(el));
    });
  }

})();
<commit_msg>NXP-13838: restore seam context on demand<commit_after>(function() {

  function warnMessage(entry) {
    var markup = "";
    if (entry.warn_message) {
      markup += ""
    }
    return markup;
  }

  function userEntryDefaultFormatter(entry) {
    var markup = "";
    if (entry.displayIcon && entry.type) {
      if (entry.type == "USER_TYPE") {
        markup += "";
      } else if (entry.type == "GROUP_TYPE") {
        markup += "";
      }
    }
    markup += entry.displayLabel;
    markup += warnMessage(entry);
    return markup;
  }

  function docEntryDefaultFormatter(doc) {
    var markup = "

";
    markup += "
";
    if (doc.properties && doc.properties['common:icon']) {
      markup += ""
    }
    markup += "	";
    markup += doc.title;
    markup += warnMessage(doc);
    if (doc.path) {
      markup += "" + doc.path + "";
    }
    markup += "

"
    return markup;
  }

  function dirEntryDefaultFormatter(entry) {
    var markup = entry.displayLabel;
    markup += warnMessage(entry);
    return markup;
  }

  var userSelectionDefaultFormatter = userEntryDefaultFormatter;

  function docSelectionDefaultFormatter(doc) {
    var markup = "";
    if (doc.properties && doc.properties['common:icon']) {
      markup += ""
    }
    markup += getDocLinkElt(doc);
    markup += warnMessage(doc);
    return markup;
  }

  function dirSelectionDefaultFormatter(entry) {
    var markup = entry.absoluteLabel;
    markup += warnMessage(entry);
    return markup;
  }

  function getOperationName(params) {
    var opName = params.operationId;
    if (typeof (opName) == 'undefined' || opName == '') {
      if (params.directoryName && params.directoryName.length > 0) {
        opName = 'Directory.SuggestEntries';
      } else {
        opName = 'Document.PageProvider';
      }
    }
    return opName;
  }

  function getDocLinkElt(doc) {
    if (doc.contextParameters) {
      var url = doc.contextParameters.documentURL;
      var markup = "" + doc.title + ""
      return markup;
    } else {
      return doc.title;
    }
  }

  function getUrlWithConversationId(url) {
    return url + "?conversationId=" + currentConversationId;
  }

  function configureOperationParameters(op, params, query) {
    var restoreSeamCtx = params.restoreSeamCtx == 'true';
    var temp = {};
    jQuery.extend(temp, params);
    temp.lang = currentUserLang;
    if (params.operationId == 'Directory.SuggestEntries') {
      // build default operation for Directory
      temp.searchTerm = query.term;
    } else if (params.operationId == 'UserGroup.Suggestion') {
      temp.searchTerm = query.term;
      temp.searchType = params.userSuggestionSearchType;
    } else if (params.operationId == 'Document.PageProvider') {
      // build default operation for Document
      temp.searchTerm = query.term + "%";
      temp.query = params.query;
      temp.providerName = params.pageProviderName;
      temp.page = "0";
      temp.pageSize = "20";
    } else {
      // custom operation, pass at least the query term
      temp.searchTerm = query.term;
    }
    if (restoreSeamCtx && typeof currentConversationId != 'undefined') {
      // Give needed info to restore Seam context
      op.addParameter("id", getOperationName(params));
      op.addParameter("conversationId", currentConversationId);
      op.opts.automationParams.context = temp;
    } else {
      op.addParameters(temp);
    }
  }

  function fillResult(results, data, params) {
    if (typeof(data.length) != "undefined") {
      // default result parsing for Directory entries
      for (i = 0; i < data.length; i++) {
        var entry = data[i];
        results.push(entry);
      }
    } else if (typeof(data.entries) != "undefined") {
      // default result parsing for Documents
      for (i = 0; i < data.entries.length; i++) {
        var doc = data.entries[i];
        results.push(doc);
      }
    } else {
      alert("Error with suggestion widget");
    }
  }

  function getDefaultLabel(item) {
    if (item.displayLabel) {
      return item.displayLabel;
    } else {
      return item.title;
    }
  }

  function getDefaultId(item) {
    if (item.computedId) {
      return item.computedId;
    } else if (item.uid) {
      return item.uid;
    } else {
      return item.id;
    }
  }

  function initSelect2Widget(el) {
    // retrieve parameters from Html
    var elid = el.attr("id");
    var params = {};

    var paramId = (elid + "_params").split(":").join("\\:");
    var paramsHolder = jQuery("#" + paramId);
    params = JSON.parse(paramsHolder.val());

    var readonly = params.readonly == 'true';
    var required = params.required == 'true';
    var restoreSeamCtx = params.restoreSeamCtx == 'true';

    var initId = (elid + "_init").split(":").join("\\:");
    var initHolder = jQuery("#" + initId);
    var initDoc = null;
    try {
      initDoc = JSON.parse(initHolder.val());
    } catch (err) {
      // console.log("Unable to parse initvalue", err, initHolder.val())
    }

    // set style on select
    el.css("width", params.width);

    // determine operation name
    var opName = getOperationName(params);

    // define automation params
    var automationParams = {
      "documentSchemas" : params.documentSchemas
    };

    if (params.repository) {
      automationParams.repository = params.repository;
    }

    // init Automation Operation
    var op = null;
    if (restoreSeamCtx && typeof currentConversationId != 'undefined') {
      // If Seam context is available, let's restore it
      op = jQuery().automation('Seam.RunOperation', automationParams);
    } else {
      op = jQuery().automation(opName, automationParams);
    }

    // detect if we need custom selection formatting
    var selectionFormatterFunction = null;
    if (params.selectionFormatter && params.selectionFormatter.length > 0) {
      selectionFormatterFunction = eval(params.selectionFormatter);
    }
    // detect if we need custom suggestion formatting
    var suggestionFormatterFunction = null;
    if (params.suggestionFormatter && params.suggestionFormatter.length > 0) {
      suggestionFormatterFunction = eval(params.suggestionFormatter);
    }

    // build select2 parameters
    var select2_params = {
      containerCssClass : params.containerCssClass,
      dropdownCssClass : params.dropdownCssClass,
      minimumInputLength : params.minChars,
      query : function(query) {

        configureOperationParameters(op, params, query);

        op.execute(function(data, textStatus, xhr) {
          var results = [];
          fillResult(results, data, params)
          query.callback({
            results : results
          });
        });
      }
    }

    // append custom selection formatter if needed
    if (selectionFormatterFunction != null) {
      select2_params.formatSelection = selectionFormatterFunction;
    } else {
      select2_params.formatSelection = function(doc) {
        if (select2_params.labelFieldName != null) {
          return doc.properties[select2_params.labelFieldName];
        } else {
          return getDefaultLabel(doc)
        }
      };
    }
    // append custom suggestion formatter if needed
    if (suggestionFormatterFunction != null) {
      select2_params.formatResult = suggestionFormatterFunction;
    } else {
      select2_params.formatResult = getDefaultLabel;
    }

    // append id formatter if needed
    if (params.idProperty && params.idProperty.length > 0) {
      select2_params.id = function(doc) {
        return doc.properties[params.idProperty];
      };
    } else if (params.idFunction) {
      select2_params.id = eval(params.idFunction);
    } else if (params.prefixed) {
      select2_params.id = function(item) {
        return item.prefixed_id;
      };
    } else {
      select2_params.id = getDefaultId;
    }

    if (initDoc != null) {
      select2_params.initSelection = function(element, callback) {
        callback(initDoc);
      };
    }

    if (params.multiple == 'true') {
      select2_params.maximumSelectionSize = params.maximumSelectionSize;
      select2_params.multiple = true;
    }

    if (params.placeholder && !readonly) {
      select2_params.placeholder = params.placeholder;
      select2_params.allowClear = !required;
    }

    // dropdown on arrow only
    if (params.dropdownOnArrow == 'true' && params.multiple == 'false') {
      select2_params.dropdownOnArrow = true;
    }

    // separator
    if (params.separator) {
      select2_params.separator = params.separator;
    }

    // init select2
    el.select2(select2_params);

    // view or edit mode
    if (readonly) {
      el.select2("readonly", true);
    }

    if (!readonly) {

      // Make selected items sortable
      if (params.multiple == 'true' && params.orderable == 'true') {
        el.select2("container").find("ul.select2-choices").sortable({
          containment : 'parent',
          start : function() {
            el.select2("onSortStart");
          },
          update : function() {
            el.select2("onSortEnd");
          }
        });
      }

      // Handle onclick widget property
      el.on("select2-opening", function(e) {
        if (params.onclick) {
          eval(params.onclick);
        }
      });

      // trigger for safeEdit restore
      el.on("change", function(e) {
        if (e) {
          if (e.added) {
            var newValue;
            if (select2_params.multiple) {
              var newObj = JSON.parse(initHolder.val());
              newObj.push(e.added);
              var newValue = JSON.stringify(newObj);
            } else {
              newValue = JSON.stringify(e.added);
            }
            initHolder.val(newValue);
          }

          if (e.removed) {
            var removedId = select2_params.id(e.removed);
            if (select2_params.multiple) {
              var newValue = '';
              var tempObj = JSON.parse(initHolder.val());
              jQuery.each(tempObj, function(index, result) {
                if (result) {
                  if (select2_params.id(result) == removedId) {
                    tempObj.splice(index, 1);
                  }
                }
              });
              newValue = JSON.stringify(tempObj);
              initHolder.val(newValue);
            } else {
              if (initHolder.val() == removedId) {
                initHolder.val('');
              }
            }
          }
        }

        // ReRender any jsf component if needed.
        if (params.reRenderFunctionName) {
          window[params.reRenderFunctionName]();
        }

        // Handle onchange widget property
        if (params.onchange) {
          eval(params.onchange);
        }

      });
    }

    var $parentForm = jQuery(el).closest("form");
    if ($parentForm.hasClass("safeEditEnabled")) {
        // Register postRestore function for safeEdit
        jQuery(el).closest("form").registerPostRestoreCallBacks(function(data) {
          initSelect2Widget(jQuery(el));
        });
      }
  }

  window.initSelect2AjaxWidget = function initSelect2AjaxWidget(widgetId, index) {

    var selector = "input[type='hidden'][id$=";

    if (index != null && index.length > 0) {
      selector = selector + index + "\\:";
    }
    selector = selector + widgetId + "_select2]";

    jQuery(selector).each(function(idx, el) {
      initSelect2Widget(jQuery(el));
    });

  }

  window.initSelect2Widgets = function initSelect2Widgets() {
    jQuery("input[type='hidden'][id$=select2]").each(function(idx, el) {
      initSelect2Widget(jQuery(el));
    });
  }

})();
<|endoftext|>


<commit_before>var fs     = require('fs-extra');
var chalk  = require('chalk');
var path   = require('path');

module.exports = function(moduleName, config) {
  var projectPath = config.get('projectPath');
  var templatesPath = path.join(__dirname, '../..', 'templates');

  return function (callback) {
    var destination = path.join(projectPath, 'ember/app', moduleName);
    var source = path.join(templatesPath, 'ember/app', moduleName);

    console.log('');
    process.stdout.write('Copying default ember ' + moduleName + ' to ember project...');

    fs.copy(source, destination, function(err) {
      if(err) callback(err);
      process.stdout.write(chalk.green('done'));
      callback(null);
    });

  }
}
<commit_msg>update copy to not throw errors if the path doesn't exist<commit_after>var fs     = require('fs-extra');
var chalk  = require('chalk');
var path   = require('path');

module.exports = function(moduleName, config) {
  var projectPath = config.get('projectPath');
  var templatesPath = path.join(__dirname, '../..', 'templates');

  return function (callback) {
    var destination = path.join(projectPath, 'ember/app', moduleName);
    var source = path.join(templatesPath, 'ember/app', moduleName);

    console.log();
    process.stdout.write('Copying default ember ' + moduleName + ' to ember project...');

    if(fs.existsSync(source)) {
      fs.copy(source, destination, function(err) {
        if(err) callback(err);
        process.stdout.write(chalk.green('done'));
        callback(null);
      });
    } else {
      process.stdout.write(chalk.green('done'));
      callback(null);
    }
  }
}
<|endoftext|>


<commit_before>(function (root) {
    "use strict";
    const isFunc = o => typeof o === 'function',
        isString = o => typeof o === 'string',
        isBool = o => typeof o === 'boolean',
        isObj = o => toString.call(o) === '[object Object]',
        undef = undefined,
        concatObjects = Object.assign,
        defineprop = Object.defineProperty,
        desc = (value, write, enumerable) => ({
            value,
            write: isBool(write) ? write : false,
            enumerable: isBool(enumerable) ? enumerable : false,
        })

    function listener() {
        const container = new Map,
            actions = {
                delete(type, func) {
                    if (actions.has(type, func)) {
                        const handlers = container.get(type);
                        if (!handlers.size) container.delete(type);
                        if (handlers.has(func)) handlers.delete(func);
                    }
                },
                set(type, func, once) {
                    if (isFunc(func)) {
                        if (!container.has(type)) container.set(type, new Set);
                        if (once === true) func.__isOnce = true;
                        container.get(type).add(func);
                    }
                },
                get(type) {
                    return container.get(type);
                },
                has(type, func) {
                    return container.size > 0 && container.has(type) && container.get(type).has(func);
                },
                loop(type, fn) {
                    if (container.size > 0 && container.has(type)) {
                        const handlers = container.get(type);
                        handlers.forEach(handler => {
                            fn(handler);
                            if (handler.__isOnce === true) handlers.delete(handler);
                        });
                    }

                },
                makeHandle(type, func) {
                    if (!isFunc(func)) throw new TypeError('eventsys : listener needs a function');
                    return {
                        on() {
                            Array.isArray(type) ? type.map(t => {
                                actions.set(t, func);
                            }) : actions.set(type, func);
                            return this;
                        },
                        once() {
                            Array.isArray(type) ? type.map(t => {
                                actions.set(t, func, true);
                            }) : actions.set(type, func, true);
                            return this;
                        },
                        off() {
                            Array.isArray(type) ? type.map(t => {
                                actions.delete(t, func);
                            }) : actions.delete(type, func);
                            return this;
                        }
                    };
                }
            };
        return actions;
    }

    /**
     * Adds an Event System to Arbitrary Objects and Classes.
     * @method eventsys
     * @param {Object|Function|Class} obj - object to convert
     */
    function eventsys(obj) {
        if (!obj) obj = {};
        const listeners = listener();
        let stop = false;
        return concatObjects(obj, {
            on: (type, func) => listeners.makeHandle(type, func).on(),
            once: (type, func) => listeners.makeHandle(type, func).once(),
            off: (type, func) => listeners.makeHandle(type, func).off(),
            emit(type) {
                if (!stop && isString(type)) {
                    const args = [].slice.call(arguments, 1);
                    listeners.loop(type, handle => {
                        handle.apply(obj, args);
                    });
                } else throw new TypeError('eventsys : you cannot emit that! ' + type);
            },
            stopall: state => stop = isBool(state) ? state : true,
            defineHandle(name, type) {
                if (!type) type = name;
                obj[name] = (fn, useOnce) => obj[useOnce ? 'once' : 'on'](type, fn);
            }
        });
    }
    /**
     * Creates observables.
     * @method observable
     * @param {Object|Function|Class} obj - object to convert
     */
    function observable(obj, noEventSys) {
        if (!obj) obj = {};
        if (!noEventSys) obj = eventsys(obj);
        const listeners = listener();
        defineprop(obj, 'isObservable', desc(true));
        ['$get', '$set'].map(prop => {
            const accessor = prop == '$get' ? 'Get' : 'Set';
            defineprop(obj, prop, desc((prop, func) => {
                if (isFunc(prop)) {
                    func = prop;
                    prop = '*';
                }
                if (!isFunc(func)) throw new Error('.' + prop + ' no function');
                func.prop = isString(prop) ? prop : '*';
                return listeners.makeHandle(accessor, func).on();
            }));
        });
        defineprop(obj, 'get', desc(key => {
            if (key != 'get' && key != 'set') {
                let val;
                listeners.loop('Get', ln => {
                    if (ln.prop === '*' || ln.prop === key) val = ln(key, obj);
                });
                return val != undef ? val : obj[key];
            } else return obj[key];
        }));
        defineprop(obj, 'set', desc((key, value) => {
            let val;
            listeners.loop('Set', ln => {
                if (ln.prop === '*' || ln.prop === key) val = ln(key, value, obj, Object.hasOwnProperty(obj, key));
            });
            val = val != undef ? val : value;
            if (isObj(val) && !val.isObservable) val = observable(val);
            obj.emit('$uberset:' + key, val);
            obj[key] = val;
        }));
        for (let key in obj)
            if (isObj(obj[key]) && !obj[key].isObservable) obj[key] = observable(obj[key]);
        if (typeof Proxy != 'undefined') return new Proxy(obj, {
            get(target, key) {
                if (key != 'get' && key != 'set') {
                    let val;
                    listeners.loop('Get', ln => {
                        if (ln.prop === '*' || ln.prop === key) val = ln(key, target);
                    });
                    return val != undef ? val : Reflect.get(target, key);
                } else return Reflect.get(target, key);
            },
            set(target, key, value) {
                let val, onetime = false;
                listeners.loop('Set', ln => {
                    if (ln.prop === '*' || ln.prop === key) {
                        if (onetime) {
                            value = val;
                            onetime = false;
                        } else onetime = true;
                        val = ln(key, value, target, !Reflect.has(target, key));
                    }
                });
                val = val != undef ? val : value;
                if (isObj(val) && !val.isObservable) val = observable(val);
                target.emit('$uberset:' + key, val);
                return Reflect.set(target, key, val);
            }
        });

        console.warn('This JavaScript Environment does not support Proxy, observables need to use the .set and .get accessors to work');
        return obj;
    }

    if (typeof exports !== 'undefined') {
        module.exports = {
            observable,
            eventsys,
            listener,
        }
    } else {
        root.observable = observable;
        root.eventsys = eventsys;
        root.listener = listener;
    }
})(this);
<commit_msg>bit of spring cleaning it's been a while<commit_after>;(function (root) {
  'use strict'
  const isFunc = o => o instanceof Function
  const isString = o => typeof o === 'string'
  const isBool = o => typeof o === 'boolean'
  const isObj = o => toString.call(o) === '[object Object]'
  const undef = undefined
  const {assign, defineProperty: defineprop} = Object

  const desc = (value, write, enumerable) => ({
    value,
    write: isBool(write) ? write : false,
    enumerable: isBool(enumerable) ? enumerable : false
  })

  function listener () {
    const container = new Map()
    const actions = {
      delete (type, func) {
        if (actions.has(type, func)) {
          const handlers = container.get(type)
          if (handlers.has(func)) handlers.delete(func)
          if (!handlers.size) container.delete(type)
        }
      },

      set (type, func, once) {
        if (isFunc(func)) {
          if (!container.has(type)) container.set(type, new Set())
          if (once === true) func.__isOnce = true
          container.get(type).add(func)
        }
      },

      get: type => container.get(type),

      has: (type, func) => container.size > 0 && container.has(type) && container.get(type).has(func),

      loop (type, fn) {
        container.has(type) &&
        container.get(type).forEach((handler, handlers) => {
          fn(handler)
          if (handler.__isOnce === true) handlers.delete(handler)
        })
      },

      makeHandle(type, func) {
        if (!isFunc(func)) throw new TypeError('eventsys : listener needs a function')
        const H = {
          on () {
            if (Array.isArray(type)) {
              for (const t of type) actions.set(t, func)
            } else {
              actions.set(type, func)
            }
            return H
          },
          once () {
            if (Array.isArray(type)) {
              for (const t of type) actions.set(t, func, true)
            } else {
              actions.set(type, func, true)
            }
            return H
          },
          off () {
            if (Array.isArray(type)) {
              for (const t of type) actions.delete(t, func)
            } else {
              actions.delete(type, func)
            }
            return H
          }
        }
        return H
      }
    }
    return actions
  }

  /**
   * Adds an Event System to Arbitrary Objects and Classes.
   * @method eventsys
   * @param {Object|Function|Class} obj - object to convert
   */
  function eventsys (obj) {
    if (!obj) obj = {}
    const listeners = listener()
    let stop = false
    return assign(obj, {
      on: (type, func) => listeners.makeHandle(type, func).on(),
      once: (type, func) => listeners.makeHandle(type, func).once(),
      off: (type, func) => listeners.makeHandle(type, func).off(),
      emit(type) {
        if (!stop && isString(type)) {
          const args = [].slice.call(arguments, 1)
          listeners.loop(type, handle => handle.apply(obj, args))
        } else throw new TypeError('eventsys : you cannot emit that! ' + type)
      },
      stopall: state => stop = isBool(state) ? state : true,
      defineHandle(name, type) {
        if (!type) type = name
        obj[name] = (fn, useOnce) => obj[useOnce ? 'once' : 'on'](type, fn)
      }
    })
  }
  /**
   * Creates observables.
   * @method observable
   * @param {Object|Function|Class} obj - object to convert
   */
  function observable (obj, noEventSys) {
    if (!obj) obj = {}
    if (!noEventSys) obj = eventsys(obj)
    const listeners = listener()
    defineprop(obj, 'isObservable', desc(true))
    ;['$get', '$set'].map(prop => {
      const accessor = prop == '$get' ? 'Get' : 'Set'
      defineprop(obj, prop, desc((prop, func) => {
        if (isFunc(prop)) {
          func = prop
          prop = '*'
        }
        if (!isFunc(func)) throw new Error('.' + prop + ' no function')
        func.prop = isString(prop) ? prop : '*'
        return listeners.makeHandle(accessor, func).on()
      }))
    })
    defineprop(obj, 'get', desc(key => {
      if (key != 'get' && key != 'set') {
        let val
        listeners.loop('Get', ln => {
          if (ln.prop === '*' || ln.prop === key) val = ln(key, obj)
        })
        return val != undef ? val : obj[key]
      } else return obj[key]
    }))
    defineprop(obj, 'set', desc((key, value) => {
      let val
      listeners.loop('Set', ln => {
        if (ln.prop === '*' || ln.prop === key) val = ln(key, value, obj, Object.hasOwnProperty(obj, key))
      })
      val = val != undef ? val : value
      if (isObj(val) && !val.isObservable) val = observable(val)
      obj.emit('$uberset:' + key, val)
      obj[key] = val
    }))
    for (let key in obj)
      if (isObj(obj[key]) && !obj[key].isObservable) obj[key] = observable(obj[key])
    if (typeof Proxy != 'undefined') return new Proxy(obj, {
        get(target, key) {
          if (key != 'get' && key != 'set') {
            let val
            listeners.loop('Get', ln => {
              if (ln.prop === '*' || ln.prop === key) val = ln(key, target)
            })
            return val != undef ? val : Reflect.get(target, key)
          } else return Reflect.get(target, key)
        },
        set(target, key, value) {
          let val, onetime = false
          listeners.loop('Set', ln => {
            if (ln.prop === '*' || ln.prop === key) {
              if (onetime) {
                value = val
                onetime = false
              } else onetime = true
              val = ln(key, value, target, !Reflect.has(target, key))
            }
          })
          val = val != undef ? val : value
          if (isObj(val) && !val.isObservable) val = observable(val)
          target.emit('$uberset:' + key, val)
          return Reflect.set(target, key, val)
        }
      })

    console.warn('This JavaScript Environment does not support Proxy, observables need to use the .set and .get accessors to work')
    return obj
  }

  observable.observable = observable
  observable.eventsys = eventsys
  observable.listener = listener

  typeof module !== 'undefined'
    ? module.exports = observable
    : root.define instanceof Function && root.define.amd
      ? root.define(['craft-observable'], () => observable)
      : root.observable = observable
})(typeof global !== 'undefined' ? global : window)
<|endoftext|>


<commit_before>/**
 * @file RadioGroup component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

// Components
import Radio from '../Radio';

// Statics
import Theme from '../Theme';
import Position from '../_statics/Position';

// Vendors
import classNames from 'classnames';
import Util from '../_vendors/Util';
import ComponentUtil from '../_vendors/ComponentUtil';

class RadioGroup extends Component {

    static Theme = Theme;

    static getDerivedStateFromProps(props, state) {
        return {
            prevProps: props,
            value: ComponentUtil.getDerivedState(props, state, 'value')
        };
    }

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            value: props.value
        };

    }

    handleChange = item => {

        const {valueField, disabled} = this.props;

        this.setState({
            value: item[valueField]
        }, () => !disabled && this.props.onChange?.(item.value));

    };

    render() {

        const {
                className, style, theme, name,
                valueField, displayField, uncheckedIconCls, checkedIconCls,
                disabled, data, onCheck
            } = this.props,
            {value} = this.state;

        return (

                {
                    data?.map((item, index) => item ?
                        <Radio key={index}
                               className={item.className || null}
                               style={item.style}
                               uncheckedIconCls={item.uncheckedIconCls || uncheckedIconCls}
                               checkedIconCls={item.checkedIconCls || checkedIconCls}
                               theme={item.theme || theme}
                               name={name}
                               label={item[displayField]}
                               value={item[valueField]}
                               checked={item[valueField] === value}
                               disabled={disabled || item.disabled}
                               tip={item.tip}
                               tipPosition={item.tipPosition}
                               onChange={() => this.handleChange(item)}
                               onCheck={e => onCheck?.(item, e)}/>
                        :
                        null
                    ) || null
                }

        );

    }
}

RadioGroup.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The RadioGroup theme.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The name of Radio.
     */
    name: PropTypes.string,

    /**
     * The data of GroupRadio.
     */
    data: PropTypes.arrayOf(PropTypes.shape({

        /**
         * The CSS class name of Radio component.
         */
        className: PropTypes.string,

        /**
         * Override the styles of Radio component.
         */
        style: PropTypes.object,

        /**
         * The RadioGroup theme.
         */
        theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

        /**
         * The label text of Radio component.
         */
        label: PropTypes.any,

        /**
         * The value of Radio component.
         */
        value: PropTypes.any,

        /**
         * If true,the Radio will be disabled.
         */
        disabled: PropTypes.bool,

        tip: PropTypes.any,
        tipPosition: PropTypes.oneOf(Util.enumerateValue(Position))

    })).isRequired,

    /**
     * The value of RadioGroup component.
     */
    value: PropTypes.any,

    valueField: PropTypes.string,
    displayField: PropTypes.string,

    uncheckedIconCls: PropTypes.string,
    checkedIconCls: PropTypes.string,

    /**
     * If true,the RadioGroup will be disabled.
     */
    disabled: PropTypes.bool,

    /**
     * Callback function fired when the value of RadioGroup changed.
     */
    onChange: PropTypes.func,

    onCheck: PropTypes.func

};

RadioGroup.defaultProps = {

    theme: Theme.DEFAULT,

    data: [],

    valueField: 'value',
    displayField: 'label',

    uncheckedIconCls: 'far fa-circle',
    checkedIconCls: 'fas fa-dot-circle',

    disabled: false

};

export default RadioGroup;
<commit_msg>update RadioGroup<commit_after>/**
 * @file RadioGroup component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

// Components
import Radio from '../Radio';

// Statics
import Theme from '../Theme';
import Position from '../_statics/Position';

// Vendors
import classNames from 'classnames';
import Util from '../_vendors/Util';
import ComponentUtil from '../_vendors/ComponentUtil';

class RadioGroup extends Component {

    static Theme = Theme;

    static getDerivedStateFromProps(props, state) {
        return {
            prevProps: props,
            value: ComponentUtil.getDerivedState(props, state, 'value')
        };
    }

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            value: props.value
        };

    }

    handleChange = item => {

        const {valueField, disabled} = this.props;

        this.setState({
            value: item?.[valueField]
        }, () => !disabled && this.props.onChange?.(item?.[valueField]));

    };

    render() {

        const {
                className, style, theme, name,
                valueField, displayField, uncheckedIconCls, checkedIconCls,
                disabled, data, onCheck
            } = this.props,
            {value} = this.state;

        return (

                {
                    data?.map((item, index) => item ?
                        <Radio key={index}
                               className={item.className || null}
                               style={item.style}
                               uncheckedIconCls={item.uncheckedIconCls || uncheckedIconCls}
                               checkedIconCls={item.checkedIconCls || checkedIconCls}
                               theme={item.theme || theme}
                               name={name}
                               label={item[displayField]}
                               value={item[valueField]}
                               checked={item[valueField] === value}
                               disabled={disabled || item.disabled}
                               tip={item.tip}
                               tipPosition={item.tipPosition}
                               onChange={() => this.handleChange(item)}
                               onCheck={e => onCheck?.(item, e)}/>
                        :
                        null
                    ) || null
                }

        );

    }
}

RadioGroup.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The RadioGroup theme.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The name of Radio.
     */
    name: PropTypes.string,

    /**
     * The data of GroupRadio.
     */
    data: PropTypes.arrayOf(PropTypes.shape({

        /**
         * The CSS class name of Radio component.
         */
        className: PropTypes.string,

        /**
         * Override the styles of Radio component.
         */
        style: PropTypes.object,

        /**
         * The RadioGroup theme.
         */
        theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

        /**
         * The label text of Radio component.
         */
        label: PropTypes.any,

        /**
         * The value of Radio component.
         */
        value: PropTypes.any,

        /**
         * If true,the Radio will be disabled.
         */
        disabled: PropTypes.bool,

        tip: PropTypes.any,
        tipPosition: PropTypes.oneOf(Util.enumerateValue(Position))

    })).isRequired,

    /**
     * The value of RadioGroup component.
     */
    value: PropTypes.any,

    valueField: PropTypes.string,
    displayField: PropTypes.string,

    uncheckedIconCls: PropTypes.string,
    checkedIconCls: PropTypes.string,

    /**
     * If true,the RadioGroup will be disabled.
     */
    disabled: PropTypes.bool,

    /**
     * Callback function fired when the value of RadioGroup changed.
     */
    onChange: PropTypes.func,

    onCheck: PropTypes.func

};

RadioGroup.defaultProps = {

    theme: Theme.DEFAULT,

    data: [],

    valueField: 'value',
    displayField: 'label',

    uncheckedIconCls: 'far fa-circle',
    checkedIconCls: 'fas fa-dot-circle',

    disabled: false

};

export default RadioGroup;
<|endoftext|>


<commit_before>const { join } = require('path')
const { writeFile } = require('fs')

const Khaos = require('khaos')
const beautify = require('js-beautify').js_beautify
const prompt = require('prompt-for')

const { isDirectory, getRelative } = require('northbrook/lib/util')

exports.plugin = create

function create (program, config, workingDir) {
  program
    .command('ts-create <relativePathToPackage>')
    .description('Initialize a new TS package for northbrook to manage')
    .action((packageName, options) => initializePackage(config, workingDir, packageName, options))
}

function initializePackage (config, workingDir, packageName, options) {
  const templateDirectory = join(__dirname, 'template/')
  const destinationDirectory = join(workingDir, packageName)

  if (isDirectory(destinationDirectory)) {
    return console.log('This directory already exists')
  }

  const khaos = new Khaos(templateDirectory)

  readFiles(khaos, function (files) {
    promptForInformation(function (promptAnswers) {
      const answers = generateAnswers(packageName, promptAnswers, workingDir)
      writeFiles(khaos, destinationDirectory, files, answers)
        .catch(err => console.log(err))
        .then(() => addPackageToConfig(packageName, config, workingDir))
    })
  })
}

function generateAnswers (packageName, promptAnswers, workingDir) {
  const {
    author,
    repository: { url: gitUrl },
    bugs: { url: bugsUrl },
    homepage
  } = require(join(workingDir, 'package.json'))

  const relative = getRelative(packageName)
  const bin = `${relative}/node_modules/.bin`

  // creates commands that allow running these commands when in a directory
  const lintCmd = `${bin}/northbrook lint --only ${packageName}`
  const testUnitCmd = `${bin}/northbrook test --only ${packageName}`
  const buildCmd = `${bin}/northbrook build --only ${packageName}`

  return Object.assign({}, promptAnswers, {
    author,
    gitUrl,
    bugsUrl,
    homepage,
    lintCmd,
    testUnitCmd,
    buildCmd
  })
}

// when a new package is created, add it to the northbrookjs config
function addPackageToConfig (packageName, config, workingDir) {
  const packages = config.packages

  if (packages.indexOf(packageName) !== -1) {
    return
  }

  packages.push(packageName)

  const newConfig = Object.assign({}, config, { packages: packages.sort() })
  let data = beautify(JSON.stringify(newConfig))

  console.log('Adding ' + packageName, '...')
  writeFile(join(workingDir, 'northbrook.json'), data, function (err) {
    if (err) throw err
  })
}

function readFiles (khaos, callback) {
  khaos.read(function (err, files) {
    if (err) throw err

    callback(files)
  })
}

const schemaForPrompt =
  {
    'packageName': 'string',
    'description': 'string',
    'private': 'boolean'
  }

function promptForInformation (callback) {
  prompt(schemaForPrompt, function (err, answers) {
    if (err) throw err

    callback(answers)
  })
}

function writeFiles (khaos, destination, files, answers) {
  return new Promise(function (resolve, reject) {
    khaos.write(destination, files, answers, function (err) {
      if (err) reject(err)
      resolve()
    })
  })
}
<commit_msg>feat(northbrook-ts-create): update to latest nortbrook version<commit_after>const { join, relative } = require('path')
const { writeFile } = require('fs')

const Khaos = require('khaos')
const beautify = require('js-beautify').js_beautify
const prompt = require('prompt-for')

const { isDirectory } = require('northbrook/lib/util')

exports.plugin = create

function create (program, config, workingDir) {
  program
    .command('ts-create <relativePathToPackage>')
    .description('Initialize a new TS package for northbrook to manage')
    .action((packageName, options) => initializePackage(config, workingDir, packageName, options))
}

function initializePackage (config, workingDir, packageName, options) {
  const templateDirectory = join(__dirname, 'template/')
  const destinationDirectory = join(workingDir, packageName)

  if (isDirectory(destinationDirectory)) {
    return console.log('This directory already exists')
  }

  const khaos = new Khaos(templateDirectory)

  readFiles(khaos, function (files) {
    promptForInformation(function (promptAnswers) {
      const answers = generateAnswers(packageName, promptAnswers, workingDir)
      writeFiles(khaos, destinationDirectory, files, answers)
        .catch(err => console.log(err))
        .then(() => addPackageToConfig(packageName, config, workingDir))
    })
  })
}

function generateAnswers (packageName, promptAnswers, workingDir) {
  const {
    author,
    repository: { url: gitUrl },
    bugs: { url: bugsUrl },
    homepage
  } = require(join(workingDir, 'package.json'))

  const relativePath = relative(join(workingDir, packageName), workingDir)
  const bin = `${relativePath}/node_modules/.bin`

  // creates commands that allow running these commands when in a directory
  const lintCmd = `${bin}/northbrook lint --only ${packageName}`
  const testUnitCmd = `${bin}/northbrook test --only ${packageName}`
  const buildCmd = `${bin}/northbrook build --only ${packageName}`

  return Object.assign({}, promptAnswers, {
    author,
    gitUrl,
    bugsUrl,
    homepage,
    lintCmd,
    testUnitCmd,
    buildCmd
  })
}

// when a new package is created, add it to the northbrookjs config
function addPackageToConfig (packageName, config, workingDir) {
  const packages = config.packages

  if (packages.indexOf(packageName) !== -1) {
    return
  }

  packages.push(packageName)

  const newConfig = Object.assign({}, config, { packages: packages.sort() })
  let data = beautify(JSON.stringify(newConfig))

  console.log('Adding ' + packageName, '...')
  writeFile(join(workingDir, 'northbrook.json'), data, function (err) {
    if (err) throw err
  })
}

function readFiles (khaos, callback) {
  khaos.read(function (err, files) {
    if (err) throw err

    callback(files)
  })
}

const schemaForPrompt =
  {
    'packageName': 'string',
    'description': 'string',
    'private': 'boolean'
  }

function promptForInformation (callback) {
  prompt(schemaForPrompt, function (err, answers) {
    if (err) throw err

    callback(answers)
  })
}

function writeFiles (khaos, destination, files, answers) {
  return new Promise(function (resolve, reject) {
    khaos.write(destination, files, answers, function (err) {
      if (err) reject(err)
      resolve()
    })
  })
}
<|endoftext|>


<commit_before>( function( window, angular ) {
    angular
        .module( 'app', [ 'visualCaptcha' ] )
        .controller( 'captchaController', function( $scope ) {
            $scope.captchaOptions = {
                imgPath: '/img/',
                captcha: {
                    url: window.location.protocol.origin,
                    numberOfImages: 5
                },
                init: function ( captcha ) {
                    $scope.captcha = captcha;
                }
            };

            $scope.alertCaptchaData = function() {
                if ( $scope.captcha ) {
                    alert( JSON.stringify( $scope.captcha.getCaptchaData(), null, '\t' ) );
                } else {
                    alert( 'Captcha not set' );
                }
            }
        } );
}( window, angular ) );<commit_msg>fixed visualCaptcha endpoint url for demo<commit_after>( function( window, angular ) {
    angular
        .module( 'app', [ 'visualCaptcha' ] )
        .controller( 'captchaController', function( $scope ) {
            $scope.captchaOptions = {
                imgPath: '/img/',
                captcha: {
                    url: window.location.origin,
                    numberOfImages: 5
                },
                init: function ( captcha ) {
                    $scope.captcha = captcha;
                }
            };

            $scope.alertCaptchaData = function() {
                if ( $scope.captcha ) {
                    alert( JSON.stringify( $scope.captcha.getCaptchaData(), null, '\t' ) );
                } else {
                    alert( 'Captcha not set' );
                }
            }
        } );
}( window, angular ) );<|endoftext|>


<commit_before>;(function () {
  'use strict'
  console.log('in main.js')

// SOCKETS
  const ws = io.connect()

  ws.on('connect', () => {
    console.log('browser socket connected')
  })

  ws.on('receiveSound', sound => {
    console.log(sound)
    receiveSound(sound)
  })

  ws.on('receiveNotes', notes => {
    console.log(notes)
    receiveNotes(notes)
  })

// END SOCKETS

// AUDIO CONTEXT
  window.AudioContext = window.AudioContext || window.webkitAudioContext

  if (!AudioContext) {
    alert("Sorry, your browser doesn't support the Web Audio APIs.")
    throw new Error("Sorry, your browser doesn't support the Web Audio APIs. Execution Aborted.") // ABORT ALL
  }

  // default
  const audio = new AudioContext()
  const gain = audio.createGain()
  gain.gain.value = 0.5;
  gain.connect(audio.destination)

  // adjust volume
  function volume () {
    console.log('slider', slider.value)
    gain.gain.value = slider.value
    volumeText.innerHTML = slider.value
  }
  // function testSound () {
  //   const osc = audio.createOscillator();
  //   osc.type = "square";
  //   osc.frequency.value = 3000;
  //   osc.connect(gain);
  // }
// END AUDIO CONTEXT

// TEST
  // const osc = audio.createOscillator()

// LISTENERS
  const slider = document.getElementById('slider')
  slider.addEventListener('input', volume)

  // const test = document.getElementById('test')
  // test.addEventListener('click', testFunc)

  const kill = document.getElementById('kill')
  kill.addEventListener('mouseover', killer)

  // const hertz = document.getElementById('hertz')
  // hertz.addEventListener('input', testFunc)

  // const xy = document.getElementById('xy')
  // xy.addEventListener('mousemove', box)

  // should only listen when this div has focus so typing in chat doesn't trigger sounds
  const pageContentWrapper = document.getElementById('page-content-wrapper')
  // keydown function
  // document.addEventListener('keydown', pressKey)
  pageContentWrapper.addEventListener('keydown', pressKey)
  // keyup function
  pageContentWrapper.addEventListener('keyup', releaseKey)
  // document.addEventListener('keyup', releaseKey)

  // shape listener
  const shape = document.getElementById('shape')
  shape.addEventListener('change', getter(shape))

  // hertz listener
  const hertzText = document.getElementById('hertzText')
  const volumeText = document.getElementById('volumeText')

  // tempo listener
  const tempo = document.getElementById('tempo')
// LISTENERS END

  // gets wave shape from select options
  // function shaper () {
  //   // console.log(shape.value)
  //   return shape.value
  // }

  // a getter that can get lots of things
  function getter (element) {
    return element.value
  }

    // const osc = audio.createOscillator()
    // osc.start()

  // function testFunc (sound) {
  //   gain.connect(audio.destination)
  //   console.log('clicked')
  //   // const slider = document.getElementById('slider')
  //   // console.log('slider', slider.value)
  //   console.log('hertz', hertz.value)
  //   // osc.type = "square";
  //   // osc.type = shaper()
  //   const gotHertz = getter(hertz)

  //   osc.type = getter(shape)

  //   // osc.frequency.value = hertz.value || 100
  //   osc.frequency.value = gotHertz || 100
  //   // osc.frequency.value = sound.frequency || gotHertz
  //   osc.connect(gain);
  //   hertzText.innerHTML = gotHertz
  //   // hertzText.innerHTML = sound.frequency || gotHertz
  //   const soundToSend = {frequency: gotHertz, shape: getter(shape)}
  //   console.log('testFunc soundToSend', soundToSend)
  //   // if (!sound) {
  //     ws.emit('sendSound', soundToSend)
  //   // }
  // }

  function receiveSound (sound) {
    console.log('received', sound)
    gain.connect(audio.destination)
    const osc = audio.createOscillator()
    osc.start()
    // console.log('clicked')
    // const slider = document.getElementById('slider')
    // console.log('slider', slider.value)
    // console.log('hertz', hertz.value)
    // osc.type = "square";
    // osc.type = shaper()
    // const gotHertz = getter(hertz)

    // osc.type = getter(shape)
    osc.type = sound.shape

    // osc.frequency.value = hertz.value || 100
    // osc.frequency.value = gotHertz || 100
    osc.frequency.value = sound.frequency
    osc.connect(gain);
    // hertzText.innerHTML = gotHertz
    hertzText.innerHTML = sound.frequency
    // const soundToSend = {frequency: gotHertz}
    // console.log('testFunc soundToSend', soundToSend)
  }

    // const osc = audio.createOscillator()
    // osc.start()
  function box (e) {
    // console.log(e)
    gain.connect(audio.destination)
    // console.log(e.clientX)
    // osc.type = "square";
    // osc.type = shaper()
    osc.type = getter(shape)
    osc.frequency.value = e.clientX / 3
    osc.connect(gain);
    const soundToSend = {frequency: (e.clientX / 3), shape: getter(shape)}
    ws.emit('sendSound', soundToSend)
  }

  function killer () {
    // const osc = audio.createOscillator()
    osc.frequency.value = 0
    gain.disconnect(audio.destination)
  }
// END TEST

// KEYS

  const frequencyByKey = {
    65: 261.626, // C4
    87: 277.183, // C#4
    83: 293.665, // D4
    69: 311.127, // D#4
    68: 329.628, // E4
    70: 349.228, // F4
    84: 369.994, // F#4
    71: 391.995, // G4
    89: 415.305, // G#4
    72: 440.000, // A4
    85: 466.164, // A#4
    74: 493.883, // B4
    75: 523.251, // C5
    79: 554.365, // C#5
    76: 587.330, // D5
    80: 622.254 // D#5
  }

  const nameByKey = {
    65: "C4",
    87: "C#4",
    83: "D4",
    69: "D#4",
    68: "E4",
    70: "F4",
    84: "F#4",
    71: "G4",
    89: "G#4",
    72: "A4",
    85: "A#4",
    74: "B4",
    75: "C5",
    79: "C#5",
    76: "D5",
    80: "D#5"
  }

  let nodes = [];

  // you need to think about when someone is chatting that this is not triggered
  // keydown press
  function pressKey (event) {
    // console.log('in press key')
    // console.log(event.keyCode)
    let alreadyPressed = false;
    for (let i = 0; i < nodes.length; i++) {
      if (nodes[i].code === event.keyCode) {
        alreadyPressed = true
        break
      }
    }
    if (event.keyCode >= 65 && event.keyCode <= 90 && !alreadyPressed) {
      const startNote = new Date()
      const osc = audio.createOscillator()
      osc.type = getter(shape)
      osc.frequency.value = frequencyByKey[event.keyCode]
      osc.connect(gain)
      osc.start(0)
      // testing length
      // const beat = getter(tempo) / 60 / 16
      const beat = 60 / (getter(tempo) * 4)
      nodes.push({code: event.keyCode, node: osc, length: startNote})
      const notesToSend = {frequency: frequencyByKey[event.keyCode], shape: getter(shape), notes: nodes, beat: beat }
      // console.log("notes", notesToSend)
      ws.emit('sendNotes', notesToSend)

    }
  }

  function receiveNotes (notes) {
    const osc = audio.createOscillator()
    // osc.type = getter(shape)
    osc.type = notes.shape
    // osc.frequency.value = frequencyByKey[event.keyCode]
    osc.frequency.value = notes.frequency
    osc.connect(gain)
    osc.start(0)
    // const beat = getter(tempo) / 60 / 16
    osc.stop(audio.currentTime + notes.beat)
    // console.log(getter(tempo))
    // osc.stop(notes.)

    // console.log('received notes', notes)
    // const garbage = []
    // for (let i = 0; i < nodes.length; i++) {
    //   if (nodes[i].code === event.keyCode) {
    //     nodes[i].node.stop(0)
    //     nodes[i].node.disconnect()
    //     garbage.push(i)
    //   }
    // }
    // for (let i = 0; i < garbage.length; i++) {
    //   nodes.splice(garbage[i], 1)
    // }
    console.log('received notes', notes)
    const garbage = []
    for (let i = 0; i < notes.notes.length; i++) {
      notes.notes[i].node.stop(0)
      notes.notes[i].node.disconnect()
      garbage.push(i)
    }
    for (let i = 0; i < garbage.length; i++) {
      notes.notes.splice(garbage[i], 1)
    }
  }

  function releaseKey (event) {
    console.log('released key')
    const garbage = []
    for (let i = 0; i < nodes.length; i++) {
      if (nodes[i].code === event.keyCode) {
        nodes[i].node.stop(0)
        nodes[i].node.disconnect()
        // testing end note
        const endNote = new Date()
        nodes[i].length = endNote - nodes[i].length
        console.log('nodes i dot length', nodes[i].length)
        ws.emit('sendNoteEnd')
        // end testing
        garbage.push(i)
      }
    }
    for (let i = 0; i < garbage.length; i++) {
      nodes.splice(garbage[i], 1)
    }
  }

// END KEYS

})();
<commit_msg>comment to remember to add in note values<commit_after>;(function () {
  'use strict'
  console.log('in main.js')

// SOCKETS
  const ws = io.connect()

  ws.on('connect', () => {
    console.log('browser socket connected')
  })

  ws.on('receiveSound', sound => {
    console.log(sound)
    receiveSound(sound)
  })

  ws.on('receiveNotes', notes => {
    console.log(notes)
    receiveNotes(notes)
  })

// END SOCKETS

// AUDIO CONTEXT
  window.AudioContext = window.AudioContext || window.webkitAudioContext

  if (!AudioContext) {
    alert("Sorry, your browser doesn't support the Web Audio APIs.")
    throw new Error("Sorry, your browser doesn't support the Web Audio APIs. Execution Aborted.") // ABORT ALL
  }

  // default
  const audio = new AudioContext()
  const gain = audio.createGain()
  gain.gain.value = 0.5;
  gain.connect(audio.destination)

  // adjust volume
  function volume () {
    console.log('slider', slider.value)
    gain.gain.value = slider.value
    volumeText.innerHTML = slider.value
  }
  // function testSound () {
  //   const osc = audio.createOscillator();
  //   osc.type = "square";
  //   osc.frequency.value = 3000;
  //   osc.connect(gain);
  // }
// END AUDIO CONTEXT

// TEST
  // const osc = audio.createOscillator()

// LISTENERS
  const slider = document.getElementById('slider')
  slider.addEventListener('input', volume)

  // const test = document.getElementById('test')
  // test.addEventListener('click', testFunc)

  const kill = document.getElementById('kill')
  kill.addEventListener('mouseover', killer)

  // const hertz = document.getElementById('hertz')
  // hertz.addEventListener('input', testFunc)

  // const xy = document.getElementById('xy')
  // xy.addEventListener('mousemove', box)

  // should only listen when this div has focus so typing in chat doesn't trigger sounds
  const pageContentWrapper = document.getElementById('page-content-wrapper')
  // keydown function
  // document.addEventListener('keydown', pressKey)
  pageContentWrapper.addEventListener('keydown', pressKey)
  // keyup function
  pageContentWrapper.addEventListener('keyup', releaseKey)
  // document.addEventListener('keyup', releaseKey)

  // shape listener
  const shape = document.getElementById('shape')
  shape.addEventListener('change', getter(shape))

  // hertz listener
  const hertzText = document.getElementById('hertzText')
  const volumeText = document.getElementById('volumeText')

  // tempo listener
  const tempo = document.getElementById('tempo')
// LISTENERS END

  // gets wave shape from select options
  // function shaper () {
  //   // console.log(shape.value)
  //   return shape.value
  // }

  // a getter that can get lots of things
  function getter (element) {
    return element.value
  }

    // const osc = audio.createOscillator()
    // osc.start()

  // function testFunc (sound) {
  //   gain.connect(audio.destination)
  //   console.log('clicked')
  //   // const slider = document.getElementById('slider')
  //   // console.log('slider', slider.value)
  //   console.log('hertz', hertz.value)
  //   // osc.type = "square";
  //   // osc.type = shaper()
  //   const gotHertz = getter(hertz)

  //   osc.type = getter(shape)

  //   // osc.frequency.value = hertz.value || 100
  //   osc.frequency.value = gotHertz || 100
  //   // osc.frequency.value = sound.frequency || gotHertz
  //   osc.connect(gain);
  //   hertzText.innerHTML = gotHertz
  //   // hertzText.innerHTML = sound.frequency || gotHertz
  //   const soundToSend = {frequency: gotHertz, shape: getter(shape)}
  //   console.log('testFunc soundToSend', soundToSend)
  //   // if (!sound) {
  //     ws.emit('sendSound', soundToSend)
  //   // }
  // }

  function receiveSound (sound) {
    console.log('received', sound)
    gain.connect(audio.destination)
    const osc = audio.createOscillator()
    osc.start()
    // console.log('clicked')
    // const slider = document.getElementById('slider')
    // console.log('slider', slider.value)
    // console.log('hertz', hertz.value)
    // osc.type = "square";
    // osc.type = shaper()
    // const gotHertz = getter(hertz)

    // osc.type = getter(shape)
    osc.type = sound.shape

    // osc.frequency.value = hertz.value || 100
    // osc.frequency.value = gotHertz || 100
    osc.frequency.value = sound.frequency
    osc.connect(gain);
    // hertzText.innerHTML = gotHertz
    hertzText.innerHTML = sound.frequency
    // const soundToSend = {frequency: gotHertz}
    // console.log('testFunc soundToSend', soundToSend)
  }

    // const osc = audio.createOscillator()
    // osc.start()
  function box (e) {
    // console.log(e)
    gain.connect(audio.destination)
    // console.log(e.clientX)
    // osc.type = "square";
    // osc.type = shaper()
    osc.type = getter(shape)
    osc.frequency.value = e.clientX / 3
    osc.connect(gain);
    const soundToSend = {frequency: (e.clientX / 3), shape: getter(shape)}
    ws.emit('sendSound', soundToSend)
  }

  function killer () {
    // const osc = audio.createOscillator()
    osc.frequency.value = 0
    gain.disconnect(audio.destination)
  }
// END TEST

// KEYS

  const frequencyByKey = {
    65: 261.626, // C4
    87: 277.183, // C#4
    83: 293.665, // D4
    69: 311.127, // D#4
    68: 329.628, // E4
    70: 349.228, // F4
    84: 369.994, // F#4
    71: 391.995, // G4
    89: 415.305, // G#4
    72: 440.000, // A4
    85: 466.164, // A#4
    74: 493.883, // B4
    75: 523.251, // C5
    79: 554.365, // C#5
    76: 587.330, // D5
    80: 622.254 // D#5
  }

  const nameByKey = {
    65: "C4",
    87: "C#4",
    83: "D4",
    69: "D#4",
    68: "E4",
    70: "F4",
    84: "F#4",
    71: "G4",
    89: "G#4",
    72: "A4",
    85: "A#4",
    74: "B4",
    75: "C5",
    79: "C#5",
    76: "D5",
    80: "D#5"
  }

  let nodes = [];

  // you need to think about when someone is chatting that this is not triggered
  // keydown press
  function pressKey (event) {
    // console.log('in press key')
    // console.log(event.keyCode)
    let alreadyPressed = false;
    for (let i = 0; i < nodes.length; i++) {
      if (nodes[i].code === event.keyCode) {
        alreadyPressed = true
        break
      }
    }
    if (event.keyCode >= 65 && event.keyCode <= 90 && !alreadyPressed) {
      const startNote = new Date()
      const osc = audio.createOscillator()
      const beat = 60 / (getter(tempo) * 4)
      osc.type = getter(shape)
      osc.frequency.value = frequencyByKey[event.keyCode]
      osc.connect(gain)
      osc.start(0)
      // HEY MAYBE YOU SHOULD HAVE IT WHERE YOU CAN SELECT THE NOTE LENGTH TOO
      osc.stop(audio.currentTime + beat)
      // testing length
      // const beat = getter(tempo) / 60 / 16
      nodes.push({code: event.keyCode, node: osc, length: startNote})
      const notesToSend = {frequency: frequencyByKey[event.keyCode], shape: getter(shape), notes: nodes, beat: beat }
      // console.log("notes", notesToSend)
      ws.emit('sendNotes', notesToSend)

    }
  }

  function receiveNotes (notes) {
    const osc = audio.createOscillator()
    // osc.type = getter(shape)
    osc.type = notes.shape
    // osc.frequency.value = frequencyByKey[event.keyCode]
    osc.frequency.value = notes.frequency
    osc.connect(gain)
    osc.start(0)
    // const beat = getter(tempo) / 60 / 16
    osc.stop(audio.currentTime + notes.beat)
    // console.log(getter(tempo))
    // osc.stop(notes.)

    // console.log('received notes', notes)
    // const garbage = []
    // for (let i = 0; i < nodes.length; i++) {
    //   if (nodes[i].code === event.keyCode) {
    //     nodes[i].node.stop(0)
    //     nodes[i].node.disconnect()
    //     garbage.push(i)
    //   }
    // }
    // for (let i = 0; i < garbage.length; i++) {
    //   nodes.splice(garbage[i], 1)
    // }
    console.log('received notes', notes)
    const garbage = []
    for (let i = 0; i < notes.notes.length; i++) {
      notes.notes[i].node.stop(0)
      notes.notes[i].node.disconnect()
      garbage.push(i)
    }
    for (let i = 0; i < garbage.length; i++) {
      notes.notes.splice(garbage[i], 1)
    }
  }

  function releaseKey (event) {
    console.log('released key')
    const garbage = []
    for (let i = 0; i < nodes.length; i++) {
      if (nodes[i].code === event.keyCode) {
        nodes[i].node.stop(0)
        nodes[i].node.disconnect()
        // testing end note
        const endNote = new Date()
        nodes[i].length = endNote - nodes[i].length
        console.log('nodes i dot length', nodes[i].length)
        ws.emit('sendNoteEnd')
        // end testing
        garbage.push(i)
      }
    }
    for (let i = 0; i < garbage.length; i++) {
      nodes.splice(garbage[i], 1)
    }
  }

// END KEYS

})();
<|endoftext|>