<commit_before>function handle_input(e) {
    var styleEl = document.getElementById('custom-style');
    var inputEl = document.getElementById('config-area');
    var saveEl = document.getElementById('save');

    styleEl.innerHTML = inputEl.value;
    saveEl.disabled = false;

    repopulate_subtitles();
}

function repopulate_subtitles() {
    $(".most-subtitles").remove();

    var samples = {
        en: "He doesn't have any friends in Korea so he probably doesn't even have anyone to eat with.",
        de: " Er hat keine Freunde in Korea, also wird er wahrscheinlich niemanden haben, mit dem er was essen kann."
    };

    var styleEl = document.getElementById('custom-style');
    var languages = get_used_languages();
    for (var i = 0; i < languages.length; i++) {
        var div = document.createElement("div");
        div.className = "most-subtitles most-" + languages[i];
        div.innerHTML = samples[languages[i]] ||
            "[No sample available for language " + languages[i] + ".]" +
            "
[Some more text.]";
        document.getElementById("common-container").appendChild(div);
    }
}

function get_used_languages() {
    result = [];
    var styleEl = document.getElementById('custom-style');
    for (var i = 0; i < styleEl.sheet.rules.length; i++) {
        var re = /\.most-([A-z][A-z])\W/g;
        var m;
        while (m = re.exec(styleEl.sheet.rules[i].selectorText + " ")) {
            if (result.indexOf(m[1]) == -1) {
                result.push(m[1]);
            }
        }
    }
    return result;
}

function restore_options() {
    var styleEl = document.getElementById('custom-style');
    var inputEl = document.getElementById('config-area');

    chrome.storage.sync.get(null, function(items) {
        if (items.customStyle !== undefined) {
            styleEl.innerHTML = items.customStyle;
        }
        inputEl.innerHTML = styleEl.innerHTML;
    });

    repopulate_subtitles();
}

function save_options() {
    var styleEl = document.getElementById('custom-style')

    chrome.storage.sync.set({customStyle: styleEl.innerHTML}, function() {
        var saveEl = document.getElementById('save');
        saveEl.disabled = true;
    });
}

function remove_storage() {
    chrome.storage.sync.remove('customStyle');
}

$("#config-area").on('input', handle_input);
document.addEventListener('DOMContentLoaded', restore_options);
document.getElementById('save').addEventListener('click', save_options);
document.getElementById('remove').addEventListener('click', remove_storage);
<commit_msg>Use more $ syntax<commit_after>function handle_input(e) {
    $("#custom-style")[0].innerHTML = $("#config-area")[0].value;
    $("#save")[0].disabled = false;

    repopulate_subtitles();
}

function repopulate_subtitles() {
    $(".most-subtitles").remove();

    var samples = {
        en: "He doesn't have any friends in Korea so he probably doesn't even have anyone to eat with.",
        de: " Er hat keine Freunde in Korea, also wird er wahrscheinlich niemanden haben, mit dem er was essen kann."
    };

    var languages = get_used_languages();
    for (var i = 0; i < languages.length; i++) {
        var div = document.createElement("div");
        div.className = "most-subtitles most-" + languages[i];
        div.innerHTML = samples[languages[i]] ||
            "[No sample available for language " + languages[i] + ".]" +
            "
[Some more text.]";
        $("#common-container")[0].appendChild(div);
    }
}

function get_used_languages() {
    result = [];
    var rules = $("#custom-style")[0].sheet.rules;
    for (var i = 0; i < rules.length; i++) {
        var re = /\.most-([A-z][A-z])\W/g;
        var m;
        while (m = re.exec(rules[i].selectorText + " ")) {
            if (result.indexOf(m[1]) == -1) {
                result.push(m[1]);
            }
        }
    }
    return result;
}

function restore_options() {
    chrome.storage.sync.get(null, function(items) {
        if (items.customStyle === undefined) {
            $("#remove")[0].disabled = true;
        } else {
            $("#custom-style")[0].innerHTML = items.customStyle;
        }

        $("#config-area")[0].innerHTML = $("#custom-style")[0].innerHTML;

        repopulate_subtitles();
    });
}

function save_options() {
    var customStyle = $("#custom-style")[0].innerHTML;

    chrome.storage.sync.set({customStyle: customStyle}, function() {
        $("#save")[0].disabled = true;
        $("#remove")[0].disabled = false;
    });
}

function remove_storage() {
    chrome.storage.sync.remove('customStyle');
    $("#remove")[0].disabled = true;
}

$("#config-area").on('input', handle_input);
document.addEventListener('DOMContentLoaded', restore_options);
$("#save")[0].addEventListener('click', save_options);
$("#remove")[0].addEventListener('click', remove_storage);
<|endoftext|>


<commit_before>define([
'angular',
'lodash',
'../utils/utils'
],
function(
  angular,
  _,
  utils ){
  angular.module( 'frottage', [])
  .directive( 'frottage', [
    function(){
      return {
        scope: {},

        // 8.5 * 300 x 11 * 300 - Natch

        template: [

          '<canvas id="frottage" width="2550" height="3300" style="border:1px solid">'

        ].join(' '),
        link: function( scope, elem ){
          var canvas = $( '#frottage', elem ).get( 0 )
          var colors = [ '#AAA', '#BBB', '#CCC', '#DDD', '#EEE', '#FFF' ]
          var rows = 50
          var cols = 50
          var ix = canvas.height / rows
          var jx = canvas.width / cols
          var ctx = canvas.getContext( '2d' )
          var grid = []

          function build(){
            for ( var i=0; i<ix; i++ ){
              grid[i]=[]
              for ( var j=0; j<jx/2; j++ ){
                grid[i][j] = colors[ Math.floor( Math.random() * colors.length )]
              }
              grid[i] = grid[i].concat( grid[i].slice().reverse() )
            }
          }

          function draw(){
            for ( var i=0; i<ix; i++ ){
              for ( var j=0; j<jx; j++ ){
                ctx.beginPath()
                ctx.rect( jx*j, ix*i, jx, ix )
                ctx.fillStyle = grid[i][j]
                ctx.fill()
              }
            }
          }

          build()
          draw()

        }
      }
    }
  ])
})<commit_msg>playing<commit_after>define([
'angular',
'lodash',
'../utils/utils'
],
function(
  angular,
  _,
  utils ){
  angular.module( 'frottage', [])
  .directive( 'frottage', [
    function(){
      return {
        scope: {},
        template: [
          '<button class="btn btn-sm" ng-click="redraw()">redraw</button>',
          '<canvas id="frottage" width="500" height="500">'

        ].join(' '),
        link: function( scope, elem ){
          var canvas = $( '#frottage', elem ).get( 0 )
          var colors = [ '#AAA', '#BBB', '#CCC', '#DDD', '#EEE', '#FFF' ]
          // var colors = [ '#111', '#222', '#333', '#444', '#555', '#666' ]
          //var colors = [ '#DDD', '#EEE', '#FFF' ]
          //var colors = [ 'blue', 'red', 'green' ]
          var rows = 80
          var cols = 80
          var ix = canvas.height / rows
          var jx = canvas.width / cols
          var ctx = canvas.getContext( '2d' )
          var grid = []

          function build(){
            for ( var i=0; i<rows/2; i++ ){
              grid[i]=[]
              for ( var j=0; j<cols/2; j++ ){
                grid[i][j] = colors[ Math.floor( Math.random() * colors.length )]
              }
              grid[i] = grid[i].concat( grid[i].slice().reverse() )
            }
            grid = grid.concat( grid.slice().reverse() )
          }

          function draw(){
            for ( var i=0; i<rows; i++ ){
              for ( var j=0; j<cols; j++ ){
                ctx.beginPath()
                ctx.rect( jx*j+10, jx*i+10, jx, jx )
                ctx.fillStyle = grid[i][j]
                ctx.fill()
              }
            }
          }
          scope.redraw = function(){
            build()
            draw()
          }
          scope.redraw()
        }
      }
    }
  ])
})<|endoftext|>


<commit_before>import * as invoicesController from './invoicesController'
import * as channelController from './channelController'
import * as walletController from './walletController'
import * as peersController from './peersController'
import * as paymentsController from './paymentsController'
import * as networkController from './networkController'

// TODO - GetChanInfo
// TODO - GetTransactions
// TODO - GetNodeInfo
// TODO - DescribeGraph
// TODO - GetNetworkInfo
// TODO - QueryRoutes
// TODO - DecodePayReq
// TODO - SendPayment
// TODO - DeleteAllPayments

export default function(lnd, log, event, msg, data) {
  log.info(`Calling lnd method: %o`, { msg, data })
  switch (msg) {
    case 'info':
      networkController
        .getInfo(lnd)
        .then(infoData => {
          event.sender.send('receiveInfo', infoData)
          event.sender.send('receiveCryptocurrency', infoData.chains[0])
          return infoData
        })
        .catch(error => log.error('info:', error))
      break
    case 'describeNetwork':
      networkController
        .describeGraph(lnd)
        .then(networkData => event.sender.send('receiveDescribeNetwork', networkData))
        .catch(error => log.error('describeGraph:', error))
      break
    case 'queryRoutes':
      // Data looks like { pubkey: String, amount: Number }
      networkController
        .queryRoutes(lnd, data)
        .then(routes => event.sender.send('queryRoutesSuccess', routes))
        .catch(error => {
          log.error('queryRoutes:', error)
          event.sender.send('queryRoutesFailure', { error: error.toString() })
        })
      break
    case 'getInvoiceAndQueryRoutes':
      // Data looks like { pubkey: String, amount: Number }
      invoicesController
        .getInvoice(lnd, { pay_req: data.payreq })
        .then(invoiceData =>
          networkController.queryRoutes(lnd, {
            pubkey: invoiceData.destination,
            amount: invoiceData.num_satoshis
          })
        )
        .then(routes => event.sender.send('receiveInvoiceAndQueryRoutes', routes))
        .catch(error => log.error('getInvoiceAndQueryRoutes invoice:', error))
      break
    case 'newaddress':
      // Data looks like { address: '' }
      walletController
        .newAddress(lnd, data.type)
        .then(({ address }) => event.sender.send('receiveAddress', { type: data.type, address }))
        .catch(error => log.error('newaddress:', error))
      break
    case 'setAlias':
      // Data looks like { new_alias: '' }
      walletController
        .setAlias(lnd, data)
        .then(() => event.sender.send('aliasSet'))
        .catch(error => log.error('setAlias:', error))
      break
    case 'peers':
      // Data looks like { peers: [] }
      peersController
        .listPeers(lnd)
        .then(peersData => event.sender.send('receivePeers', peersData))
        .catch(error => log.error('peers:', error))
      break
    case 'channels':
      // Data looks like
      // [
      //   { channels: [] },
      //   {
      //     total_limbo_balance: 0,
      //     pending_open_channels: [],
      //     pending_closing_channels: [],
      //     pending_force_closing_channels: []
      //   }
      // ]
      Promise.all(
        [channelController.listChannels, channelController.pendingChannels].map(func => func(lnd))
      )
        .then(channelsData =>
          event.sender.send('receiveChannels', {
            channels: channelsData[0].channels,
            pendingChannels: channelsData[1]
          })
        )
        .catch(error => log.error('channels:', error))
      break
    case 'transactions':
      // Data looks like { transactions: [] }
      walletController
        .getTransactions(lnd)
        .then(transactionsData => event.sender.send('receiveTransactions', transactionsData))
        .catch(error => log.error('transactions:', error))
      break
    case 'payments':
      // Data looks like { payments: [] }
      paymentsController
        .listPayments(lnd)
        .then(paymentsData => event.sender.send('receivePayments', paymentsData))
        .catch(error => log.error('payments:', error))
      break
    case 'invoices':
      // Data looks like { invoices: [] }
      invoicesController
        .listInvoices(lnd)
        .then(invoicesData => event.sender.send('receiveInvoices', invoicesData))
        .catch(error => log.error('invoices:', error))
      break
    case 'invoice':
      // Data looks like { invoices: [] }
      invoicesController
        .getInvoice(lnd, { pay_req: data.payreq })
        .then(invoiceData => event.sender.send('receiveInvoice', invoiceData))
        .catch(error => log.error('invoice:', error))
      break
    case 'balance':
      // Balance looks like [ { balance: '129477456' }, { balance: '243914' } ]
      Promise.all(
        [walletController.walletBalance, channelController.channelBalance].map(func => func(lnd))
      )
        .then(balance => {
          event.sender.send('receiveBalance', {
            walletBalance: balance[0].total_balance,
            channelBalance: balance[1].balance
          })
          return balance
        })
        .catch(error => log.error('balance:', error))
      break
    case 'createInvoice':
      // Invoice looks like { r_hash: Buffer, payment_request: '' }
      // { memo, value } = data
      invoicesController
        .addInvoice(lnd, data)
        .then(newinvoice =>
          invoicesController
            .getInvoice(lnd, { pay_req: newinvoice.payment_request })
            .then(decodedInvoice =>
              event.sender.send(
                'createdInvoice',
                Object.assign(decodedInvoice, {
                  memo: data.memo,
                  value: data.value,
                  r_hash: Buffer.from(newinvoice.r_hash, 'hex').toString('hex'),
                  payment_request: newinvoice.payment_request,
                  creation_date: Date.now() / 1000
                })
              )
            )
            .catch(error => {
              log.error('decodedInvoice:', error)
              event.sender.send('invoiceFailed', { error: error.toString() })
            })
        )
        .catch(error => {
          log.error('addInvoice:', error)
          event.sender.send('invoiceFailed', { error: error.toString() })
        })
      break
    case 'sendPayment':
      // Payment looks like { payment_preimage: Buffer, payment_route: Object }
      // { paymentRequest } = data
      paymentsController
        .sendPaymentSync(lnd, data)
        .then(payment => {
          log.info('payment:', payment)
          const { payment_route } = payment
          event.sender.send('paymentSuccessful', Object.assign(data, { payment_route }))
          return payment
        })
        .catch(error => {
          log.error('payment error: ', error)
          event.sender.send('paymentFailed', Object.assign(data, { error: error.toString() }))
        })
      break
    case 'sendCoins':
      // Transaction looks like { txid: String }
      // { amount, addr } = data
      walletController
        .sendCoins(lnd, data)
        .then(({ txid }) =>
          event.sender.send('transactionSuccessful', Object.assign(data, { txid }))
        )
        .catch(error => {
          log.error('error: ', error)
          event.sender.send('transactionFailed', Object.assign(data, { error: error.toString() }))
        })
      break
    case 'openChannel':
      // Response is empty. Streaming updates on channel status and updates
      // { pubkey, localamt, pushamt } = data
      channelController
        .openChannel(lnd, event, data)
        .then(channel => {
          log.info('CHANNEL: ', channel)
          event.sender.send('channelSuccessful', { channel })
          return channel
        })
        .catch(error => log.error('openChannel:', error))
      break
    case 'closeChannel':
      // Response is empty. Streaming updates on channel status and updates
      // { channel_point, force } = data
      channelController
        .closeChannel(lnd, event, data)
        .then(result => {
          log.info('CLOSE CHANNEL: ', result)
          event.sender.send('closeChannelSuccessful')
          return result
        })
        .catch(error => log.error('closeChannel:', error))
      break
    case 'connectPeer':
      // Returns a peer_id. Pass the pubkey, host and peer_id so we can add a new peer to the list
      // { pubkey, host } = data
      peersController
        .connectPeer(lnd, data)
        .then(peer => {
          const { peer_id } = peer
          log.info('peer_id: ', peer_id)
          event.sender.send('connectSuccess', { pub_key: data.pubkey, address: data.host, peer_id })
          return peer
        })
        .catch(error => {
          event.sender.send('connectFailure', { error: error.toString() })
          log.error('connectPeer:', error)
        })
      break
    case 'disconnectPeer':
      // Empty response. Pass back pubkey on success to remove it from the peers list
      // { pubkey } = data
      peersController
        .disconnectPeer(lnd, data)
        .then(() => {
          log.info('pubkey: ', data.pubkey)
          event.sender.send('disconnectSuccess', { pubkey: data.pubkey })
          return null
        })
        .catch(error => log.error('disconnectPeer:', error))
      break
    case 'connectAndOpen':
      // Connects to a peer if we aren't connected already and then attempt to open a channel
      // {} = data
      channelController
        .connectAndOpen(lnd, event, data)
        .then(channelData => {
          log.info('connectAndOpen data: ', channelData)
          // event.sender.send('connectSuccess', { pub_key: data.pubkey, address: data.host, peer_id })
          return channelData
        })
        .catch(error => {
          // event.sender.send('connectFailure', { error: error.toString() })
          log.error('connectAndOpen:', error)
        })
      break
    default:
  }
}
<commit_msg>refactor(lnd): refactor createinvoice to avoid nested promises<commit_after>import * as invoicesController from './invoicesController'
import * as channelController from './channelController'
import * as walletController from './walletController'
import * as peersController from './peersController'
import * as paymentsController from './paymentsController'
import * as networkController from './networkController'

// TODO - GetChanInfo
// TODO - GetTransactions
// TODO - GetNodeInfo
// TODO - DescribeGraph
// TODO - GetNetworkInfo
// TODO - QueryRoutes
// TODO - DecodePayReq
// TODO - SendPayment
// TODO - DeleteAllPayments

export default function(lnd, log, event, msg, data) {
  log.info(`Calling lnd method: %o`, { msg, data })
  switch (msg) {
    case 'info':
      networkController
        .getInfo(lnd)
        .then(infoData => {
          event.sender.send('receiveInfo', infoData)
          event.sender.send('receiveCryptocurrency', infoData.chains[0])
          return infoData
        })
        .catch(error => log.error('info:', error))
      break
    case 'describeNetwork':
      networkController
        .describeGraph(lnd)
        .then(networkData => event.sender.send('receiveDescribeNetwork', networkData))
        .catch(error => log.error('describeGraph:', error))
      break
    case 'queryRoutes':
      // Data looks like { pubkey: String, amount: Number }
      networkController
        .queryRoutes(lnd, data)
        .then(routes => event.sender.send('queryRoutesSuccess', routes))
        .catch(error => {
          log.error('queryRoutes:', error)
          event.sender.send('queryRoutesFailure', { error: error.toString() })
        })
      break
    case 'getInvoiceAndQueryRoutes':
      // Data looks like { pubkey: String, amount: Number }
      invoicesController
        .getInvoice(lnd, { pay_req: data.payreq })
        .then(invoiceData =>
          networkController.queryRoutes(lnd, {
            pubkey: invoiceData.destination,
            amount: invoiceData.num_satoshis
          })
        )
        .then(routes => event.sender.send('receiveInvoiceAndQueryRoutes', routes))
        .catch(error => log.error('getInvoiceAndQueryRoutes invoice:', error))
      break
    case 'newaddress':
      // Data looks like { address: '' }
      walletController
        .newAddress(lnd, data.type)
        .then(({ address }) => event.sender.send('receiveAddress', { type: data.type, address }))
        .catch(error => log.error('newaddress:', error))
      break
    case 'setAlias':
      // Data looks like { new_alias: '' }
      walletController
        .setAlias(lnd, data)
        .then(() => event.sender.send('aliasSet'))
        .catch(error => log.error('setAlias:', error))
      break
    case 'peers':
      // Data looks like { peers: [] }
      peersController
        .listPeers(lnd)
        .then(peersData => event.sender.send('receivePeers', peersData))
        .catch(error => log.error('peers:', error))
      break
    case 'channels':
      // Data looks like
      // [
      //   { channels: [] },
      //   {
      //     total_limbo_balance: 0,
      //     pending_open_channels: [],
      //     pending_closing_channels: [],
      //     pending_force_closing_channels: []
      //   }
      // ]
      Promise.all(
        [channelController.listChannels, channelController.pendingChannels].map(func => func(lnd))
      )
        .then(channelsData =>
          event.sender.send('receiveChannels', {
            channels: channelsData[0].channels,
            pendingChannels: channelsData[1]
          })
        )
        .catch(error => log.error('channels:', error))
      break
    case 'transactions':
      // Data looks like { transactions: [] }
      walletController
        .getTransactions(lnd)
        .then(transactionsData => event.sender.send('receiveTransactions', transactionsData))
        .catch(error => log.error('transactions:', error))
      break
    case 'payments':
      // Data looks like { payments: [] }
      paymentsController
        .listPayments(lnd)
        .then(paymentsData => event.sender.send('receivePayments', paymentsData))
        .catch(error => log.error('payments:', error))
      break
    case 'invoices':
      // Data looks like { invoices: [] }
      invoicesController
        .listInvoices(lnd)
        .then(invoicesData => event.sender.send('receiveInvoices', invoicesData))
        .catch(error => log.error('invoices:', error))
      break
    case 'invoice':
      // Data looks like { invoices: [] }
      invoicesController
        .getInvoice(lnd, { pay_req: data.payreq })
        .then(invoiceData => event.sender.send('receiveInvoice', invoiceData))
        .catch(error => log.error('invoice:', error))
      break
    case 'balance':
      // Balance looks like [ { balance: '129477456' }, { balance: '243914' } ]
      Promise.all(
        [walletController.walletBalance, channelController.channelBalance].map(func => func(lnd))
      )
        .then(balance => {
          event.sender.send('receiveBalance', {
            walletBalance: balance[0].total_balance,
            channelBalance: balance[1].balance
          })
          return balance
        })
        .catch(error => log.error('balance:', error))
      break
    case 'createInvoice':
      invoicesController
        .addInvoice(lnd, data)
        .then(newinvoice =>
          Promise.all([
            newinvoice,
            invoicesController.getInvoice(lnd, { pay_req: newinvoice.payment_request })
          ])
        )
        .then(([newinvoice, decodedInvoice]) =>
          event.sender.send(
            'createdInvoice',
            Object.assign(decodedInvoice, {
              memo: data.memo,
              value: data.value,
              r_hash: Buffer.from(newinvoice.r_hash, 'hex').toString('hex'),
              payment_request: newinvoice.payment_request,
              creation_date: Date.now() / 1000
            })
          )
        )
        .catch(error => {
          log.error('addInvoice:', error)
          event.sender.send('invoiceFailed', { error: error.toString() })
        })

      break
    case 'sendPayment':
      // Payment looks like { payment_preimage: Buffer, payment_route: Object }
      // { paymentRequest } = data
      paymentsController
        .sendPaymentSync(lnd, data)
        .then(payment => {
          log.info('payment:', payment)
          const { payment_route } = payment
          event.sender.send('paymentSuccessful', Object.assign(data, { payment_route }))
          return payment
        })
        .catch(error => {
          log.error('payment error: ', error)
          event.sender.send('paymentFailed', Object.assign(data, { error: error.toString() }))
        })
      break
    case 'sendCoins':
      // Transaction looks like { txid: String }
      // { amount, addr } = data
      walletController
        .sendCoins(lnd, data)
        .then(({ txid }) =>
          event.sender.send('transactionSuccessful', Object.assign(data, { txid }))
        )
        .catch(error => {
          log.error('error: ', error)
          event.sender.send('transactionFailed', Object.assign(data, { error: error.toString() }))
        })
      break
    case 'openChannel':
      // Response is empty. Streaming updates on channel status and updates
      // { pubkey, localamt, pushamt } = data
      channelController
        .openChannel(lnd, event, data)
        .then(channel => {
          log.info('CHANNEL: ', channel)
          event.sender.send('channelSuccessful', { channel })
          return channel
        })
        .catch(error => log.error('openChannel:', error))
      break
    case 'closeChannel':
      // Response is empty. Streaming updates on channel status and updates
      // { channel_point, force } = data
      channelController
        .closeChannel(lnd, event, data)
        .then(result => {
          log.info('CLOSE CHANNEL: ', result)
          event.sender.send('closeChannelSuccessful')
          return result
        })
        .catch(error => log.error('closeChannel:', error))
      break
    case 'connectPeer':
      // Returns a peer_id. Pass the pubkey, host and peer_id so we can add a new peer to the list
      // { pubkey, host } = data
      peersController
        .connectPeer(lnd, data)
        .then(peer => {
          const { peer_id } = peer
          log.info('peer_id: ', peer_id)
          event.sender.send('connectSuccess', { pub_key: data.pubkey, address: data.host, peer_id })
          return peer
        })
        .catch(error => {
          event.sender.send('connectFailure', { error: error.toString() })
          log.error('connectPeer:', error)
        })
      break
    case 'disconnectPeer':
      // Empty response. Pass back pubkey on success to remove it from the peers list
      // { pubkey } = data
      peersController
        .disconnectPeer(lnd, data)
        .then(() => {
          log.info('pubkey: ', data.pubkey)
          event.sender.send('disconnectSuccess', { pubkey: data.pubkey })
          return null
        })
        .catch(error => log.error('disconnectPeer:', error))
      break
    case 'connectAndOpen':
      // Connects to a peer if we aren't connected already and then attempt to open a channel
      // {} = data
      channelController
        .connectAndOpen(lnd, event, data)
        .then(channelData => {
          log.info('connectAndOpen data: ', channelData)
          // event.sender.send('connectSuccess', { pub_key: data.pubkey, address: data.host, peer_id })
          return channelData
        })
        .catch(error => {
          // event.sender.send('connectFailure', { error: error.toString() })
          log.error('connectAndOpen:', error)
        })
      break
    default:
  }
}
<|endoftext|>


<commit_before>/*eslint-disable */
'use strict';

var isArray = require('x-is-array');

import {h} from '@cycle/dom';

var SVGAttributeNamespace = require('virtual-dom/virtual-hyperscript/svg-attribute-namespace');
var attributeHook = require('virtual-dom/virtual-hyperscript/hooks/attribute-hook');

var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';

function svg(tagName, properties, children) {
    if (!children && isChildren(properties)) {
        children = properties;
        properties = {};
    }

    properties = properties || {};

    // set namespace for svg
    properties.namespace = SVG_NAMESPACE;

    var attributes = properties.attributes || (properties.attributes = {});

    for (var key in properties) {
        if (!properties.hasOwnProperty(key)) {
            continue;
        }

        var namespace = SVGAttributeNamespace(key);

        if (namespace === undefined) { // not a svg attribute
            continue;
        }

        var value = properties[key];

        if (typeof value !== 'string' &&
            typeof value !== 'number' &&
            typeof value !== 'boolean'
        ) {
            continue;
        }

        if (namespace !== null) { // namespaced attribute
            properties[key] = attributeHook(namespace, value);
            continue;
        }

        attributes[key] = value
        properties[key] = undefined
    }

    return h(tagName, properties, children);
}

function isChildren(x) {
    return typeof x === 'string' || isArray(x) || (x && typeof x.subscribe === 'function');
}

module.exports = svg;

<commit_msg>code style<commit_after>/*eslint-disable */
'use strict';

var isArray = require('x-is-array');

// START Cycle.js-specific code >>>>>>>>
var h = require('@cycle/dom').h;
// END Cycle.js-specific code <<<<<<<<<<

var SVGAttributeNamespace = require('virtual-dom/virtual-hyperscript/svg-attribute-namespace');
var attributeHook = require('virtual-dom/virtual-hyperscript/hooks/attribute-hook');

var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';

function svg(tagName, properties, children) {
  if (!children && isChildren(properties)) {
    children = properties;
    properties = {};
  }

  properties = properties || {};

  // set namespace for svg
  properties.namespace = SVG_NAMESPACE;

  var attributes = properties.attributes || (properties.attributes = {});

  for (var key in properties) {
    if (!properties.hasOwnProperty(key)) {
      continue;
    }

    var namespace = SVGAttributeNamespace(key);

    if (namespace === undefined) { // not a svg attribute
      continue;
    }

    var value = properties[key];

    if (typeof value !== 'string' &&
      typeof value !== 'number' &&
      typeof value !== 'boolean'
    ) {
      continue;
    }

    if (namespace !== null) { // namespaced attribute
      properties[key] = attributeHook(namespace, value);
      continue;
    }

    attributes[key] = value
    properties[key] = undefined
  }

  return h(tagName, properties, children);
}

// START Cycle.js-specific code >>>>>>>>
function isObservable(x) {
  return x && typeof x.subscribe === 'function';
}

function isChildren(x) {
  return typeof x === 'string' || isArray(x) || isObservable(x);
}
// END Cycle.js-specific code <<<<<<<<<<

module.exports = svg;

<|endoftext|>


<commit_before>var ClaimModel = require('../../models/claim-model');
var validator = require('validator');

function claimFormatter(claim){
    let returnClaim = {
        text: claim.text,
        probability: claim.probability,
        creationDate: claim.creationDate,
        _id: claim._id,
        _key: claim._key,
        arguments: claim.arguments
    }
    return returnClaim;
}
module.exports = function create(req, res){
    //console.log("TODO: CLAIMS.CREATE escape post data: ", JSON.stringify(req.body));

    let errors = [];

    if (!req.body.hasOwnProperty('text') || req.body.text == '') {
        errors.push({title:'Text is required'});
    } else if (!validator.isAlphanumeric(req.body.username + '')) {
        errors.push({title:'Claim can only have alphanumeric characters'});
    }

    if (!validator.isInt(req.body.probability + '', {min: 0, max: 100})) {
        //if this fails, just set it to 50
        req.body.probability = 50;
    }

    if (errors.length > 0) {
        res.status(200);
        res.json({ errors: errors });
        return;
    }

    var text = validator.escape(req.body.text);
    var probability = Number(req.body.probability);

    ClaimModel.getByText(text).then((data) => {
        if (data.length > 0) {
            let returnClaim = claimFormatter(data[0]);
            res.status(200);
            res.json({
                data: {claim:returnClaim} ,
                errors: [{title:'Claim already exists'}]
            });
            return;
        }

        ClaimModel.create({text: text, probability: probability}).then((newClaim) => {
            let returnClaim = claimFormatter(newClaim);
            res.status(200);
            res.json({data:{claim:newClaim}});
        }).catch((err) => {
            console.log("create new claim error", err);
            res.status(500);
            res.json({errors:[{title:'create new claim error'}]});
        });

    }).catch((err) => {
        console.log('get claims by text error: ', err);
        res.status(500);
        res.json({errors:[{title:'get claims by text error'}]});
    });

}
<commit_msg>trying to debug a bit<commit_after>var ClaimModel = require('../../models/claim-model');
var validator = require('validator');

function claimFormatter(claim){
    let returnClaim = {
        text: claim.text,
        probability: claim.probability,
        creationDate: claim.creationDate,
        _id: claim._id,
        _key: claim._key,
        arguments: claim.arguments
    }
    return returnClaim;
}
module.exports = function create(req, res){
    console.log("WHY THIS NO GET TEXT?????: ", JSON.stringify(req.body));

    let errors = [];

    if (!req.body.hasOwnProperty('text') || req.body.text == '') {
        errors.push({title:'Text is requireds'});
    } else if (!validator.isAlphanumeric(req.body.username + '')) {
        errors.push({title:'Claim can only have alphanumeric characters'});
    }

    if (!validator.isInt(req.body.probability + '', {min: 0, max: 100})) {
        //if this fails, just set it to 50
        req.body.probability = 50;
    }

    if (errors.length > 0) {
        res.status(200);
        res.json({ errors: errors });
        return;
    }

    var text = validator.escape(req.body.text);
    var probability = Number(req.body.probability);

    ClaimModel.getByText(text).then((data) => {
        if (data.length > 0) {
            let returnClaim = claimFormatter(data[0]);
            res.status(200);
            res.json({
                data: {claim:returnClaim} ,
                errors: [{title:'Claim already exists'}]
            });
            return;
        }

        ClaimModel.create({text: text, probability: probability}).then((newClaim) => {
            let returnClaim = claimFormatter(newClaim);
            res.status(200);
            res.json({data:{claim:newClaim}});
        }).catch((err) => {
            console.log("create new claim error", err);
            res.status(500);
            res.json({errors:[{title:'create new claim error'}]});
        });

    }).catch((err) => {
        console.log('get claims by text error: ', err);
        res.status(500);
        res.json({errors:[{title:'get claims by text error'}]});
    });

}
<|endoftext|>


<commit_before>import camelCase from 'lodash/camelCase';
import set from 'lodash/set';
import mongoose from 'mongoose';

class ChimeraSchemaError extends Error {
	constructor (message) {
		super(message);
		this.name = 'ChimeraSchemaError';
	}
};

class ChimeraSchema extends mongoose.Schema {
	/**
     * Enhances functionality of the base mongoose Schema class for use by Chimera.
     * * Add a naming identity at the schema level. This value will be used to name the mongoose model and mongodb collection.
     * * Adds association support between collections.
     * @param {string} name - The name to associate with the schema.
     * @param {object} fields - A mongoose schema fields definition object.
     * @param {object} options - A mongoose schema options object.
     */
	constructor (name, fields, options = {}) {
		if (!name) {
			throw new ChimeraSchemaError(`Missing required parameter 'name'`);
		}

		options = {
			timestamps: true,
			...options
		};

		super(fields, options);

		this.name = name;
	}

	/**
     * Creates a foriegn key association, treating this as the dependent schema of the relationship.
     * @param {string} modelName - The name of the mongoose model to associate.
     * @param {object} [options] - Configuration options for the virtual field declaration.
     * @param {string} [options.localField] - The name of the field in this schema that holds the foreign key reference.
     * @param {string} [options.foreignField] - The name of the field on the associated schema that matches the foreign key reference.
     * @param {string} [options.as] - The name to use for the virtual field that describes the association.
     * @param {object} [schemaOptions] - Mongoose schema type options to pass to the localField declaration.
     * @returns {ChimeraSchema} - Mutates the schema by adding a virtual field to describe this association.
     */
	belongsTo (modelName, options = {}, schemaOptions = {}) {
		if (!modelName) {
			throw new ChimeraSchemaError(`Missing required parameter 'modelName'.`);
		}

		const ref = modelName;

		const localField = options.localField || `${camelCase(modelName)}Id`;
		if (!this.path(localField)) {
			this.add({
				[localField]: {
					...schemaOptions,
					type: mongoose.Schema.Types.ObjectId,
					ref
				}
			});
		}

		const associationName = options.as || camelCase(modelName);
		const association = {
			ref,
			localField,
			foreignField: options.foreignField || '_id',
			justOne: true
		};

		this.virtual(associationName, association);

		return this;
	}

	/**
     * Creates a one-to-many association, treating this as the independent schema of the relationship.
     * @param {string} modelName - The name of the mongoose model to associate.
     * @param {object} options - Configuration options for the virtual field declaration.
     * @param {string} options.localField - The name of the field in this schema that holds the foreign key reference.
     * @param {string} [options.foreignField] - The name of the field on the associated schema that matches the foreign key reference.
     * @param {string} [options.as] - The name to use for the virtual field that describes the association.
     * @returns {ChimeraSchema} - Mutates the schema by adding a virtual field to describe this association.
     */
	hasMany (modelName, options = {}) {
		if (!modelName) {
			throw new ChimeraSchemaError(`Missing required parameter 'modelName'.`);
		}

		if (!options.foreignField) {
			throw new ChimeraSchemaError(`Missing required option 'foreignField'.`);
		}

		const ref = modelName;
		const foreignField = options.foreignField;
		const localField = options.localField || '_id';

		const associationName = options.as || `${camelCase(modelName)}Set`;
		const association = {
			ref,
			localField,
			foreignField
		};

		this.virtual(associationName, association);

		return this;
	}

	/**
     * Creates a one-to-one association, treating this as the independent schema of the relationship.
     * To ensure the integrity of the association, a unique index should also be placed on the on the
     * dependent schema of the relationship to protect a one-to-many relationship from forming.
     * @param {string} modelName - The name of the mongoose model to associate.
     * @param {object} options - Configuration options for the virtual field declaration.
     * @param {string} options.localField - The name of the field in this schema that holds the foreign key reference.
     * @param {string} [options.foreignField] - The name of the field on the associated schema that matches the foreign key reference.
     * @param {string} [options.as] - The name to use for the virtual field that describes the association.
     * @returns {ChimeraSchema} - Mutates the schema by adding a virtual field to describe this association.
     */
	hasOne (modelName, options = {}) {
		if (!modelName) {
			throw new ChimeraSchemaError(`Missing required parameter 'modelName'.`);
		}

		if (!options.foreignField) {
			throw new ChimeraSchemaError(`Missing required option 'foreignField'.`);
		}

		const ref = modelName;
		const foreignField = options.foreignField;
		const localField = options.localField || `_id`;

		const associationName = options.as || `${camelCase(modelName)}`;
		const association = {
			ref,
			localField,
			foreignField,
			justOne: true
		};

		this.virtual(associationName, association);

		return this;
	}

	/**
     * Creates a many-to-many association, treating this as an independent schema of the relationship.
     * @param {string} modelName - The name of the mongoose model to associate.
     * @param {object} [options] - Configuration options for the virtual field declaration.
     * @param {string} [options.through] - The name of the model that will contain the association entries.
     * @param {string} [options.localField] - The name of the field in this schema that holds the foreign key reference.
     * @param {string} [options.foreignField] - The name of the field on the associated schema that matches the foreign key reference.
     * @param {string} [options.as] - The name to use for the virtual field that describes the association.
     * @returns {ChimeraSchema} - Mutates the schema by adding a virtual field to describe this association.
     */
	belongsToMany (modelName, options = {}) {
		if (!modelName) {
			throw new ChimeraSchemaError(`Missing required parameter 'modelName'.`);
		}

		const through = options.through || `${this.name}_${modelName}`;
		const localField = options.localField || `_id`;
		const foreignField = options.foreignField || `${camelCase(this.name)}Id`;

		const associationName = options.as || `${modelName}Set`;
		const association = {
			ref: through,
			localField,
			foreignField
		};

		this.virtual(associationName, association);

		return this;
	}
}

export default ChimeraSchema;
<commit_msg>Remove unused dependency.<commit_after>import camelCase from 'lodash/camelCase';
import mongoose from 'mongoose';

class ChimeraSchemaError extends Error {
	constructor (message) {
		super(message);
		this.name = 'ChimeraSchemaError';
	}
};

class ChimeraSchema extends mongoose.Schema {
	/**
     * Enhances functionality of the base mongoose Schema class for use by Chimera.
     * * Add a naming identity at the schema level. This value will be used to name the mongoose model and mongodb collection.
     * * Adds association support between collections.
     * @param {string} name - The name to associate with the schema.
     * @param {object} fields - A mongoose schema fields definition object.
     * @param {object} options - A mongoose schema options object.
     */
	constructor (name, fields, options = {}) {
		if (!name) {
			throw new ChimeraSchemaError(`Missing required parameter 'name'`);
		}

		options = {
			timestamps: true,
			...options
		};

		super(fields, options);

		this.name = name;
	}

	/**
     * Creates a foriegn key association, treating this as the dependent schema of the relationship.
     * @param {string} modelName - The name of the mongoose model to associate.
     * @param {object} [options] - Configuration options for the virtual field declaration.
     * @param {string} [options.localField] - The name of the field in this schema that holds the foreign key reference.
     * @param {string} [options.foreignField] - The name of the field on the associated schema that matches the foreign key reference.
     * @param {string} [options.as] - The name to use for the virtual field that describes the association.
     * @param {object} [schemaOptions] - Mongoose schema type options to pass to the localField declaration.
     * @returns {ChimeraSchema} - Mutates the schema by adding a virtual field to describe this association.
     */
	belongsTo (modelName, options = {}, schemaOptions = {}) {
		if (!modelName) {
			throw new ChimeraSchemaError(`Missing required parameter 'modelName'.`);
		}

		const ref = modelName;

		const localField = options.localField || `${camelCase(modelName)}Id`;
		if (!this.path(localField)) {
			this.add({
				[localField]: {
					...schemaOptions,
					type: mongoose.Schema.Types.ObjectId,
					ref
				}
			});
		}

		const associationName = options.as || camelCase(modelName);
		const association = {
			ref,
			localField,
			foreignField: options.foreignField || '_id',
			justOne: true
		};

		this.virtual(associationName, association);

		return this;
	}

	/**
     * Creates a one-to-many association, treating this as the independent schema of the relationship.
     * @param {string} modelName - The name of the mongoose model to associate.
     * @param {object} options - Configuration options for the virtual field declaration.
     * @param {string} options.localField - The name of the field in this schema that holds the foreign key reference.
     * @param {string} [options.foreignField] - The name of the field on the associated schema that matches the foreign key reference.
     * @param {string} [options.as] - The name to use for the virtual field that describes the association.
     * @returns {ChimeraSchema} - Mutates the schema by adding a virtual field to describe this association.
     */
	hasMany (modelName, options = {}) {
		if (!modelName) {
			throw new ChimeraSchemaError(`Missing required parameter 'modelName'.`);
		}

		if (!options.foreignField) {
			throw new ChimeraSchemaError(`Missing required option 'foreignField'.`);
		}

		const ref = modelName;
		const foreignField = options.foreignField;
		const localField = options.localField || '_id';

		const associationName = options.as || `${camelCase(modelName)}Set`;
		const association = {
			ref,
			localField,
			foreignField
		};

		this.virtual(associationName, association);

		return this;
	}

	/**
     * Creates a one-to-one association, treating this as the independent schema of the relationship.
     * To ensure the integrity of the association, a unique index should also be placed on the on the
     * dependent schema of the relationship to protect a one-to-many relationship from forming.
     * @param {string} modelName - The name of the mongoose model to associate.
     * @param {object} options - Configuration options for the virtual field declaration.
     * @param {string} options.localField - The name of the field in this schema that holds the foreign key reference.
     * @param {string} [options.foreignField] - The name of the field on the associated schema that matches the foreign key reference.
     * @param {string} [options.as] - The name to use for the virtual field that describes the association.
     * @returns {ChimeraSchema} - Mutates the schema by adding a virtual field to describe this association.
     */
	hasOne (modelName, options = {}) {
		if (!modelName) {
			throw new ChimeraSchemaError(`Missing required parameter 'modelName'.`);
		}

		if (!options.foreignField) {
			throw new ChimeraSchemaError(`Missing required option 'foreignField'.`);
		}

		const ref = modelName;
		const foreignField = options.foreignField;
		const localField = options.localField || `_id`;

		const associationName = options.as || `${camelCase(modelName)}`;
		const association = {
			ref,
			localField,
			foreignField,
			justOne: true
		};

		this.virtual(associationName, association);

		return this;
	}

	/**
     * Creates a many-to-many association, treating this as an independent schema of the relationship.
     * @param {string} modelName - The name of the mongoose model to associate.
     * @param {object} [options] - Configuration options for the virtual field declaration.
     * @param {string} [options.through] - The name of the model that will contain the association entries.
     * @param {string} [options.localField] - The name of the field in this schema that holds the foreign key reference.
     * @param {string} [options.foreignField] - The name of the field on the associated schema that matches the foreign key reference.
     * @param {string} [options.as] - The name to use for the virtual field that describes the association.
     * @returns {ChimeraSchema} - Mutates the schema by adding a virtual field to describe this association.
     */
	belongsToMany (modelName, options = {}) {
		if (!modelName) {
			throw new ChimeraSchemaError(`Missing required parameter 'modelName'.`);
		}

		const through = options.through || `${this.name}_${modelName}`;
		const localField = options.localField || `_id`;
		const foreignField = options.foreignField || `${camelCase(this.name)}Id`;

		const associationName = options.as || `${modelName}Set`;
		const association = {
			ref: through,
			localField,
			foreignField
		};

		this.virtual(associationName, association);

		return this;
	}
}

export default ChimeraSchema;
<|endoftext|>


<commit_before>import { handleActions } from 'redux-actions';
import { createPoly } from '../../../../utils/polyvinyl';

import types from './types';
import { HTML, JS } from '../../../utils/challengeTypes';
import { buildSeed, getPath } from '../utils';

const initialState = {
  challenge: '',
  currentStep: 0,
  previousStep: -1,
  filter: '',
  files: {},
  superBlocks: []
};

const mainReducer = handleActions(
  {
    [types.fetchChallengeCompleted]: (state, { payload = '' }) => ({
      ...state,
      challenge: payload
    }),
    [types.updateCurrentChallenge]: (state, { payload: challenge }) => ({
      ...state,
      challenge: challenge.dashedName,
      path: getPath(challenge)
    }),

    // map
    [types.updateFilter]: (state, { payload = ''}) => ({
      ...state,
      filter: payload
    }),
    [types.clearFilter]: (state) => ({
      ...state,
      filter: ''
    }),
    [types.fetchChallengesCompleted]: (state, { payload = [] }) => ({
      ...state,
      superBlocks: payload
    }),

    // step
    [types.resetStep]: () => initialState,
    [types.goToStep]: (state, { payload: step = 0 }) => ({
      ...state,
      currentStep: step,
      previousStep: state.currentStep
    })
  },
  initialState
);

const filesReducer = handleActions(
  {
    [types.updateFile]: (state, { payload: file }) => ({
      ...state,
      [file.path]: file
    }),
    [types.updateFiles]: (state, { payload: files }) => {
      return files
        .reduce((files, file) => {
          files[file.path] = file;
          return files;
        }, { ...state });
    },
    [types.updateCurrentChallenge]: (state, { payload: challenge }) => {
      if (challenge.type === 'mod') {
        return challenge.files;
      }
      if (
        challenge.challengeType !== HTML &&
        challenge.challengeType !== JS
      ) {
        return {};
      }
      const path = getPath(challenge);
      return {
        ...state,
        [path]: createPoly({
          path,
          contents: buildSeed(challenge)
        })
      };
    }
  },
  {}
);

export default function challengeReducers(state, action) {
  const newState = mainReducer(state, action);
  const files = filesReducer(state && state.files || {}, action);
  return newState.files !== files ? { ...newState, files } : newState;
}
<commit_msg>Add bonfire to challenge types<commit_after>import { handleActions } from 'redux-actions';
import { createPoly } from '../../../../utils/polyvinyl';

import types from './types';
import { BONFIRE, HTML, JS } from '../../../utils/challengeTypes';
import { buildSeed, getPath } from '../utils';

const initialState = {
  challenge: '',
  currentStep: 0,
  previousStep: -1,
  filter: '',
  files: {},
  superBlocks: []
};

const mainReducer = handleActions(
  {
    [types.fetchChallengeCompleted]: (state, { payload = '' }) => ({
      ...state,
      challenge: payload
    }),
    [types.updateCurrentChallenge]: (state, { payload: challenge }) => ({
      ...state,
      challenge: challenge.dashedName,
      path: getPath(challenge)
    }),

    // map
    [types.updateFilter]: (state, { payload = ''}) => ({
      ...state,
      filter: payload
    }),
    [types.clearFilter]: (state) => ({
      ...state,
      filter: ''
    }),
    [types.fetchChallengesCompleted]: (state, { payload = [] }) => ({
      ...state,
      superBlocks: payload
    }),

    // step
    [types.resetStep]: () => initialState,
    [types.goToStep]: (state, { payload: step = 0 }) => ({
      ...state,
      currentStep: step,
      previousStep: state.currentStep
    })
  },
  initialState
);

const filesReducer = handleActions(
  {
    [types.updateFile]: (state, { payload: file }) => ({
      ...state,
      [file.path]: file
    }),
    [types.updateFiles]: (state, { payload: files }) => {
      return files
        .reduce((files, file) => {
          files[file.path] = file;
          return files;
        }, { ...state });
    },
    [types.updateCurrentChallenge]: (state, { payload: challenge }) => {
      if (challenge.type === 'mod') {
        return challenge.files;
      }
      if (
        challenge.challengeType !== HTML &&
        challenge.challengeType !== JS &&
        challenge.challengeType !== BONFIRE
      ) {
        return {};
      }
      const path = getPath(challenge);
      return {
        ...state,
        [path]: createPoly({
          path,
          contents: buildSeed(challenge)
        })
      };
    }
  },
  {}
);

export default function challengeReducers(state, action) {
  const newState = mainReducer(state, action);
  const files = filesReducer(state && state.files || {}, action);
  return newState.files !== files ? { ...newState, files } : newState;
}
<|endoftext|>


<commit_before>/*!
 * ${copyright}
 */

// Provides control sap.m.Tree.
sap.ui.define([
	'./ListBase',
	'./library',
	'sap/ui/model/ClientTreeBindingAdapter',
	'sap/ui/model/TreeBindingCompatibilityAdapter',
	'./TreeRenderer',
	"sap/base/Log",
	"sap/base/assert"
],
function(
	ListBase,
	library,
	ClientTreeBindingAdapter,
	TreeBindingCompatibilityAdapter,
	TreeRenderer,
	Log,
	assert
) {
	"use strict";

	/**
	 * Constructor for a new Tree.
	 *
	 * @param {string} [sId] ID for the new control, generated automatically if no id is given
	 * @param {object} [mSettings] Initial settings for the new control
	 *
	 * @class
	 * The Tree control provides a tree structure for displaying data in a hierarchy.
	 * Note: Growing feature is not supported by Tree.
	 * @extends sap.m.ListBase
	 *
	 * @author SAP SE
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @since 1.42
	 * @alias sap.m.Tree
	 * @see {@link fiori:/tree/ Tree}
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var Tree = ListBase.extend("sap.m.Tree", { metadata : {
		library : "sap.m",
		events : {

			/**
			 * Fired when an item has been expanded or collapsed by user interaction.
			 * @since 1.50
			 */
			toggleOpenState : {
				parameters : {

					/**
					 * Index of the expanded/collapsed item
					 */
					itemIndex : {type : "int"},

					/**
					 * Binding context of the item
					 */
					itemContext : {type : "object"},

					/**
					 * Flag that indicates whether the item has been expanded or collapsed
					 */
					expanded : {type : "boolean"}
				}
			}
		}
	}});

	Tree.prototype.isTreeBinding = function(sName) {
		return (sName == "items");
	};

	Tree.prototype.getBinding = function(sName) {
		// adapt TreeBindingAdapter for Tree
		sName = sName || "items";
		var oBinding = ListBase.prototype.getBinding.call(this, sName);

		if (oBinding && sName === "items" && !oBinding.getLength) {
			// try to resolve optional dependencies
			if (oBinding.isA("sap.ui.model.odata.v2.ODataTreeBinding")) {
				oBinding.applyAdapterInterface();
			} else if (oBinding.isA("sap.ui.model.ClientTreeBinding")) {
				ClientTreeBindingAdapter.apply(oBinding);
			} else if (oBinding.isA("sap.ui.model.odata.ODataTreeBinding")) {
				// use legacy tree binding adapter
				TreeBindingCompatibilityAdapter(oBinding, this);
			} else {
				Log.error("TreeBinding is not supported for the " + this);
			}
		}

		return oBinding;
	};

	Tree.prototype.updateAggregation = function(sName) {
		if (sName != "items") {
			return ListBase.prototype.updateAggregation.apply(this, arguments);
		}

		// Reuse the ListBinding from ManagedObject.updataAggregation
		var oBindingInfo = this.getBindingInfo("items"),
			oBinding = this.getBinding("items"),
			fnFactory = oBindingInfo.factory,
			aContexts;

		// Update a single aggregation with the array of contexts. Reuse existing children
		// and just append or remove at the end, if some are missing or too many.
		function update(oControl, aContexts) {
			var aChildren = oControl.getItems() || [],
				oContext,
				oClone;

			if (aChildren.length > aContexts.length) {
				for (var i = aContexts.length; i < aChildren.length; i++) {
					oControl.removeItem(aChildren[i]);
					aChildren[i].destroy("KeepDom");
				}
			}
			for (var i = 0; i < aContexts.length; i++) {
				oContext = aContexts[i];
				oClone = aChildren[i];
				if (oClone) {
					oClone.setBindingContext(oContext, oBindingInfo.model);
				} else {
					oClone = fnFactory(oControl.getId() + "-" + i, oContext);
					oClone.setBindingContext(oContext, oBindingInfo.model);
					oControl.addItem(oClone);
				}
			}

		}

		// Context length will be filled by model.
		aContexts = oBinding.getContexts(0);

		// If factory function is used without extended change detection, destroy aggregation
		if (!oBindingInfo.template) {
			this.destroyItems();
		}
		update(this, aContexts);

	};

	Tree.prototype.validateAggregation = function(sAggregationName, oObject, bMultiple) {
		var oResult = ListBase.prototype.validateAggregation.apply(this, arguments);
		if (sAggregationName === "items" && !oObject.isA("sap.m.TreeItemBase")) {
			throw new Error(oObject + " is not a valid items aggregation of " + this + ". Items aggregation in Tree control only supports TreeItemBase-based objects, e.g. StandardTreeItem.");
		}
		return oResult;
	};

	Tree.prototype.invalidate = function() {
		ListBase.prototype.invalidate.apply(this, arguments);
		this._bInvalidated = true;
	};

	Tree.prototype.onAfterRendering = function() {
		ListBase.prototype.onAfterRendering.apply(this, arguments);
		this._bInvalidated = false;
	};

	Tree.prototype._updateDeepestLevel = function(oItem) {
		// for level change action, e.g. expand
		if (oItem.getLevel() + 1 > this.getDeepestLevel()) {
			this._iDeepestLevel = oItem.getLevel() + 1;
		}
	};

	Tree.prototype.onItemExpanderPressed = function(oItem, bExpand) {
		var iIndex = this.indexOfItem(oItem);
		var oBindingInfo = this.getBindingInfo("items");
		var oItemContext = oItem && oItem.getBindingContext(oBindingInfo.model);

		if (oBindingInfo && oItemContext) {
			var bExpandedBeforePress = oItem.getExpanded();
			var bExpandedAfterPress;

			// make sure when rendering is called, the padding calc uses the correct deepest level
			this._updateDeepestLevel(oItem);

			var oBinding = this.getBinding("items");
			if (bExpand == undefined) {
				oBinding.toggleIndex(iIndex);
			} else if (bExpand) {
				oBinding.expand(iIndex);
			} else {
				oBinding.collapse(iIndex);
			}

			bExpandedAfterPress = oBinding.isExpanded(iIndex);
			if (bExpandedBeforePress !== bExpandedAfterPress && !oItem.isLeaf()) {
				this.fireToggleOpenState({
					itemIndex: iIndex,
					itemContext: oItemContext,
					expanded: bExpandedAfterPress
				});
			}
		}
	};

	/**
	 * The growing property is not supported for control Tree.
	 * @public
	 * @deprecated As of version 1.46.
	 */
	Tree.prototype.setGrowing = function() {
		Log.error("Growing feature of " + this + " is not supported!");
		return this;
	};

	/**
	 * The growingThreshold property is not supported for control Tree.
	 * @public
	 * @deprecated As of version 1.46.
	 */
	Tree.prototype.setGrowingThreshold = function() {
		Log.error("GrowingThreshold of " + this + " is not supported!");
		return this;
	};

	/**
	 * The growingTriggerText property is not supported for control Tree.
	 * @public
	 * @deprecated As of version 1.46.
	 */
	Tree.prototype.setGrowingTriggerText = function() {
		Log.error("GrowingTriggerText of " + this + " is not supported!");
		return this;
	};

	/**
	 * The growingScrollToLoad property is not supported for control Tree.
	 * @public
	 * @deprecated As of version 1.46.
	 */
	Tree.prototype.setGrowingScrollToLoad = function() {
		Log.error("GrowingScrollToLoad of " + this + " is not supported!");
		return this;
	};

	/**
	 * The growingDirection property is not supported for control Tree.
	 * @public
	 * @deprecated As of version 1.46.
	 */
	Tree.prototype.setGrowingDirection = function() {
		Log.error("GrowingDirection of " + this + " is not supported!");
		return this;
	};

	/**
	 * Defines the level to which the tree is expanded.
	 * The function can be used to define the initial expanding state. An alternative way to define the initial expanding state is to set the parameter numberOfExpandedLevels of the binding.
	 *
	 * Example:
	 *

	 *   oTree.bindItems({
	 *      path: "...",
	 *      parameters: {
	 *         numberOfExpandedLevels: 1
	 *      }
	 *   });
	 *

	 * @return {sap.m.Tree} A reference to the Tree control
	 * @public
	 * @param {int} iLevel The level to which the data is expanded
	 * @since 1.48.0
	 */
	Tree.prototype.expandToLevel = function (iLevel) {
		var oBinding = this.getBinding("items");

		assert(oBinding && oBinding.expandToLevel, "Tree.expandToLevel is not supported with your current Binding. Please check if you are running on an ODataModel V2.");

		if (oBinding && oBinding.expandToLevel && oBinding.getNumberOfExpandedLevels) {
			if (oBinding.getNumberOfExpandedLevels() > iLevel) {
				oBinding.collapseToLevel(0);
			}
			oBinding.expandToLevel(iLevel);
		}

		return this;
	};

	Tree.prototype.getNumberOfExpandedLevel = function() {
		return this.getBinding("items").getNumberOfExpandedLevels();
	};

	Tree.prototype.getDeepestLevel = function() {
		if (this._iDeepestLevel === undefined) {
			this._iDeepestLevel = this.getNumberOfExpandedLevel();
		}

		return this._iDeepestLevel;
	};

	/**
	 * Collapses all nodes.
	 *
	 * @return {sap.m.Tree} A reference to the Tree control
	 * @public
	 * @since 1.48.0
	 */
	Tree.prototype.collapseAll = function () {
		var oBinding = this.getBinding("items");

		assert(oBinding && oBinding.expandToLevel, "Tree.collapseAll is not supported with your current Binding. Please check if you are running on an ODataModel V2.");

		if (oBinding) {
			oBinding.collapseToLevel(0);
		}

		return this;
	};

	Tree.prototype._sortHelper = function (vParam) {
		var aIndices = [];

		if ( typeof vParam === "number" ) {
			aIndices.push(vParam);
		} else if ( Array.isArray(vParam) ) {
			//sort
			aIndices = vParam.sort().reverse();
		}

		return aIndices;

	};

	Tree.prototype._removeLeaf = function(aSortedIndices) {
		var oItem = null,
			iItemIndex,
			aIndices = [];

		for (var i = 0; i < aSortedIndices.length; i++) {
			iItemIndex = aSortedIndices[i];
			oItem = this.getItems()[iItemIndex];
			if (oItem && !oItem.isLeaf()) {
				aIndices.push(iItemIndex);
			}
		}

		return aIndices;

	};

	Tree.prototype._preExpand = function(vParam) {
		var aIndices = this._sortHelper(vParam);

		aIndices = this._removeLeaf(aIndices);

		return aIndices;
	};

	/**
	 *
	 * Expands one or multiple items.
	 *
	 * @return {sap.m.Tree} A reference to the Tree control
	 * @public
	 * @param {int|int[]} vParam The index or indices of the item to be expanded
	 * @since 1.56.0
	 */
	Tree.prototype.expand = function(vParam) {
		var oBinding = this.getBinding("items");

		if (oBinding && oBinding.expand) {
			var aIndices = this._preExpand(vParam),
				oItem;
			if (aIndices.length > 0) {
				for (var i = 0; i < aIndices.length - 1; i++) {
					oItem = this.getItems()[aIndices[i]];
					this._updateDeepestLevel(oItem);
					oBinding.expand(aIndices[i], true);
				}

				oItem = this.getItems()[aIndices[aIndices.length - 1]];
				this._updateDeepestLevel(oItem);

				// trigger change
				oBinding.expand(aIndices[aIndices.length - 1], false);
			}

		}

		return this;
	};

	/**
	 *
	 * Collapses one or multiple items.
	 *
	 * @return {sap.m.Tree} A reference to the Tree control
	 * @public
	 * @param {int|int[]} vParam The index or indices of the tree items to be collapsed
	 * @since 1.56.0
	 */
	Tree.prototype.collapse = function(vParam) {
		var oBinding = this.getBinding("items");

		if (oBinding && oBinding.collapse) {
			var aIndices = this._preExpand(vParam);
			for (var i = 0; i < aIndices.length - 1; i++) {
				oBinding.collapse(aIndices[i], true);
			}
			// trigger change
			oBinding.collapse(aIndices[aIndices.length - 1], false);
		}

		return this;
	};

	Tree.prototype.getAccessibilityType = function() {
		return sap.ui.getCore().getLibraryResourceBundle("sap.m").getText("ACC_CTR_TYPE_TREE");
	};

	Tree.prototype.getAccessbilityPosition = function(oItem) {
		var iSetSize,
			iPosInset,
			oNodeContext = oItem.getItemNodeContext();

		if (oNodeContext.parent) {
			iSetSize = oNodeContext.parent.children.length;
		}
		if (oNodeContext.positionInParent != undefined) {
			iPosInset = oNodeContext.positionInParent + 1;
		}

		return {
			setSize: iSetSize,
			posInset: iPosInset
		};
	};

	Tree.prototype.onItemLongDragOver = function(oItem) {
		var iIndex = this.indexOfItem(oItem);
		this._updateDeepestLevel(oItem);

		this.getBinding("items").expand(iIndex);
	};

	Tree.prototype.isGrouped = function() {
		return false;
	};

	return Tree;

});<commit_msg>[INTERNAL] m.Tree: enhance doc for the expand function<commit_after>/*!
 * ${copyright}
 */

// Provides control sap.m.Tree.
sap.ui.define([
	'./ListBase',
	'./library',
	'sap/ui/model/ClientTreeBindingAdapter',
	'sap/ui/model/TreeBindingCompatibilityAdapter',
	'./TreeRenderer',
	"sap/base/Log",
	"sap/base/assert"
],
function(
	ListBase,
	library,
	ClientTreeBindingAdapter,
	TreeBindingCompatibilityAdapter,
	TreeRenderer,
	Log,
	assert
) {
	"use strict";

	/**
	 * Constructor for a new Tree.
	 *
	 * @param {string} [sId] ID for the new control, generated automatically if no id is given
	 * @param {object} [mSettings] Initial settings for the new control
	 *
	 * @class
	 * The Tree control provides a tree structure for displaying data in a hierarchy.
	 * Note: Growing feature is not supported by Tree.
	 * @extends sap.m.ListBase
	 *
	 * @author SAP SE
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @since 1.42
	 * @alias sap.m.Tree
	 * @see {@link fiori:/tree/ Tree}
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var Tree = ListBase.extend("sap.m.Tree", { metadata : {
		library : "sap.m",
		events : {

			/**
			 * Fired when an item has been expanded or collapsed by user interaction.
			 * @since 1.50
			 */
			toggleOpenState : {
				parameters : {

					/**
					 * Index of the expanded/collapsed item
					 */
					itemIndex : {type : "int"},

					/**
					 * Binding context of the item
					 */
					itemContext : {type : "object"},

					/**
					 * Flag that indicates whether the item has been expanded or collapsed
					 */
					expanded : {type : "boolean"}
				}
			}
		}
	}});

	Tree.prototype.isTreeBinding = function(sName) {
		return (sName == "items");
	};

	Tree.prototype.getBinding = function(sName) {
		// adapt TreeBindingAdapter for Tree
		sName = sName || "items";
		var oBinding = ListBase.prototype.getBinding.call(this, sName);

		if (oBinding && sName === "items" && !oBinding.getLength) {
			// try to resolve optional dependencies
			if (oBinding.isA("sap.ui.model.odata.v2.ODataTreeBinding")) {
				oBinding.applyAdapterInterface();
			} else if (oBinding.isA("sap.ui.model.ClientTreeBinding")) {
				ClientTreeBindingAdapter.apply(oBinding);
			} else if (oBinding.isA("sap.ui.model.odata.ODataTreeBinding")) {
				// use legacy tree binding adapter
				TreeBindingCompatibilityAdapter(oBinding, this);
			} else {
				Log.error("TreeBinding is not supported for the " + this);
			}
		}

		return oBinding;
	};

	Tree.prototype.updateAggregation = function(sName) {
		if (sName != "items") {
			return ListBase.prototype.updateAggregation.apply(this, arguments);
		}

		// Reuse the ListBinding from ManagedObject.updataAggregation
		var oBindingInfo = this.getBindingInfo("items"),
			oBinding = this.getBinding("items"),
			fnFactory = oBindingInfo.factory,
			aContexts;

		// Update a single aggregation with the array of contexts. Reuse existing children
		// and just append or remove at the end, if some are missing or too many.
		function update(oControl, aContexts) {
			var aChildren = oControl.getItems() || [],
				oContext,
				oClone;

			if (aChildren.length > aContexts.length) {
				for (var i = aContexts.length; i < aChildren.length; i++) {
					oControl.removeItem(aChildren[i]);
					aChildren[i].destroy("KeepDom");
				}
			}
			for (var i = 0; i < aContexts.length; i++) {
				oContext = aContexts[i];
				oClone = aChildren[i];
				if (oClone) {
					oClone.setBindingContext(oContext, oBindingInfo.model);
				} else {
					oClone = fnFactory(oControl.getId() + "-" + i, oContext);
					oClone.setBindingContext(oContext, oBindingInfo.model);
					oControl.addItem(oClone);
				}
			}

		}

		// Context length will be filled by model.
		aContexts = oBinding.getContexts(0);

		// If factory function is used without extended change detection, destroy aggregation
		if (!oBindingInfo.template) {
			this.destroyItems();
		}
		update(this, aContexts);

	};

	Tree.prototype.validateAggregation = function(sAggregationName, oObject, bMultiple) {
		var oResult = ListBase.prototype.validateAggregation.apply(this, arguments);
		if (sAggregationName === "items" && !oObject.isA("sap.m.TreeItemBase")) {
			throw new Error(oObject + " is not a valid items aggregation of " + this + ". Items aggregation in Tree control only supports TreeItemBase-based objects, e.g. StandardTreeItem.");
		}
		return oResult;
	};

	Tree.prototype.invalidate = function() {
		ListBase.prototype.invalidate.apply(this, arguments);
		this._bInvalidated = true;
	};

	Tree.prototype.onAfterRendering = function() {
		ListBase.prototype.onAfterRendering.apply(this, arguments);
		this._bInvalidated = false;
	};

	Tree.prototype._updateDeepestLevel = function(oItem) {
		// for level change action, e.g. expand
		if (oItem.getLevel() + 1 > this.getDeepestLevel()) {
			this._iDeepestLevel = oItem.getLevel() + 1;
		}
	};

	Tree.prototype.onItemExpanderPressed = function(oItem, bExpand) {
		var iIndex = this.indexOfItem(oItem);
		var oBindingInfo = this.getBindingInfo("items");
		var oItemContext = oItem && oItem.getBindingContext(oBindingInfo.model);

		if (oBindingInfo && oItemContext) {
			var bExpandedBeforePress = oItem.getExpanded();
			var bExpandedAfterPress;

			// make sure when rendering is called, the padding calc uses the correct deepest level
			this._updateDeepestLevel(oItem);

			var oBinding = this.getBinding("items");
			if (bExpand == undefined) {
				oBinding.toggleIndex(iIndex);
			} else if (bExpand) {
				oBinding.expand(iIndex);
			} else {
				oBinding.collapse(iIndex);
			}

			bExpandedAfterPress = oBinding.isExpanded(iIndex);
			if (bExpandedBeforePress !== bExpandedAfterPress && !oItem.isLeaf()) {
				this.fireToggleOpenState({
					itemIndex: iIndex,
					itemContext: oItemContext,
					expanded: bExpandedAfterPress
				});
			}
		}
	};

	/**
	 * The growing property is not supported for control Tree.
	 * @public
	 * @deprecated As of version 1.46.
	 */
	Tree.prototype.setGrowing = function() {
		Log.error("Growing feature of " + this + " is not supported!");
		return this;
	};

	/**
	 * The growingThreshold property is not supported for control Tree.
	 * @public
	 * @deprecated As of version 1.46.
	 */
	Tree.prototype.setGrowingThreshold = function() {
		Log.error("GrowingThreshold of " + this + " is not supported!");
		return this;
	};

	/**
	 * The growingTriggerText property is not supported for control Tree.
	 * @public
	 * @deprecated As of version 1.46.
	 */
	Tree.prototype.setGrowingTriggerText = function() {
		Log.error("GrowingTriggerText of " + this + " is not supported!");
		return this;
	};

	/**
	 * The growingScrollToLoad property is not supported for control Tree.
	 * @public
	 * @deprecated As of version 1.46.
	 */
	Tree.prototype.setGrowingScrollToLoad = function() {
		Log.error("GrowingScrollToLoad of " + this + " is not supported!");
		return this;
	};

	/**
	 * The growingDirection property is not supported for control Tree.
	 * @public
	 * @deprecated As of version 1.46.
	 */
	Tree.prototype.setGrowingDirection = function() {
		Log.error("GrowingDirection of " + this + " is not supported!");
		return this;
	};

	/**
	 * Defines the level to which the tree is expanded.
	 * The function can be used to define the initial expanding state. An alternative way to define the initial expanding state is to set the parameter numberOfExpandedLevels of the binding.
	 *
	 * Example:
	 *

	 *   oTree.bindItems({
	 *      path: "...",
	 *      parameters: {
	 *         numberOfExpandedLevels: 1
	 *      }
	 *   });
	 *

	 * @return {sap.m.Tree} A reference to the Tree control
	 * @public
	 * @param {int} iLevel The level to which the data is expanded
	 * @since 1.48.0
	 */
	Tree.prototype.expandToLevel = function (iLevel) {
		var oBinding = this.getBinding("items");

		assert(oBinding && oBinding.expandToLevel, "Tree.expandToLevel is not supported with your current Binding. Please check if you are running on an ODataModel V2.");

		if (oBinding && oBinding.expandToLevel && oBinding.getNumberOfExpandedLevels) {
			if (oBinding.getNumberOfExpandedLevels() > iLevel) {
				oBinding.collapseToLevel(0);
			}
			oBinding.expandToLevel(iLevel);
		}

		return this;
	};

	Tree.prototype.getNumberOfExpandedLevel = function() {
		return this.getBinding("items").getNumberOfExpandedLevels();
	};

	Tree.prototype.getDeepestLevel = function() {
		if (this._iDeepestLevel === undefined) {
			this._iDeepestLevel = this.getNumberOfExpandedLevel();
		}

		return this._iDeepestLevel;
	};

	/**
	 * Collapses all nodes.
	 *
	 * @return {sap.m.Tree} A reference to the Tree control
	 * @public
	 * @since 1.48.0
	 */
	Tree.prototype.collapseAll = function () {
		var oBinding = this.getBinding("items");

		assert(oBinding && oBinding.expandToLevel, "Tree.collapseAll is not supported with your current Binding. Please check if you are running on an ODataModel V2.");

		if (oBinding) {
			oBinding.collapseToLevel(0);
		}

		return this;
	};

	Tree.prototype._sortHelper = function (vParam) {
		var aIndices = [];

		if ( typeof vParam === "number" ) {
			aIndices.push(vParam);
		} else if ( Array.isArray(vParam) ) {
			//sort
			aIndices = vParam.sort().reverse();
		}

		return aIndices;

	};

	Tree.prototype._removeLeaf = function(aSortedIndices) {
		var oItem = null,
			iItemIndex,
			aIndices = [];

		for (var i = 0; i < aSortedIndices.length; i++) {
			iItemIndex = aSortedIndices[i];
			oItem = this.getItems()[iItemIndex];
			if (oItem && !oItem.isLeaf()) {
				aIndices.push(iItemIndex);
			}
		}

		return aIndices;

	};

	Tree.prototype._preExpand = function(vParam) {
		var aIndices = this._sortHelper(vParam);

		aIndices = this._removeLeaf(aIndices);

		return aIndices;
	};

	/**
	 *
	 * Expands one or multiple items. Note that items that are hidden at the time of calling this API can't be expanded.
	 *
	 * @return {sap.m.Tree} A reference to the Tree control
	 * @public
	 * @param {int|int[]} vParam The index or indices of the item to be expanded
	 * @since 1.56.0
	 */
	Tree.prototype.expand = function(vParam) {
		var oBinding = this.getBinding("items");

		if (oBinding && oBinding.expand) {
			var aIndices = this._preExpand(vParam),
				oItem;
			if (aIndices.length > 0) {
				for (var i = 0; i < aIndices.length - 1; i++) {
					oItem = this.getItems()[aIndices[i]];
					this._updateDeepestLevel(oItem);
					oBinding.expand(aIndices[i], true);
				}

				oItem = this.getItems()[aIndices[aIndices.length - 1]];
				this._updateDeepestLevel(oItem);

				// trigger change
				oBinding.expand(aIndices[aIndices.length - 1], false);
			}

		}

		return this;
	};

	/**
	 *
	 * Collapses one or multiple items.
	 *
	 * @return {sap.m.Tree} A reference to the Tree control
	 * @public
	 * @param {int|int[]} vParam The index or indices of the tree items to be collapsed
	 * @since 1.56.0
	 */
	Tree.prototype.collapse = function(vParam) {
		var oBinding = this.getBinding("items");

		if (oBinding && oBinding.collapse) {
			var aIndices = this._preExpand(vParam);
			for (var i = 0; i < aIndices.length - 1; i++) {
				oBinding.collapse(aIndices[i], true);
			}
			// trigger change
			oBinding.collapse(aIndices[aIndices.length - 1], false);
		}

		return this;
	};

	Tree.prototype.getAccessibilityType = function() {
		return sap.ui.getCore().getLibraryResourceBundle("sap.m").getText("ACC_CTR_TYPE_TREE");
	};

	Tree.prototype.getAccessbilityPosition = function(oItem) {
		var iSetSize,
			iPosInset,
			oNodeContext = oItem.getItemNodeContext();

		if (oNodeContext.parent) {
			iSetSize = oNodeContext.parent.children.length;
		}
		if (oNodeContext.positionInParent != undefined) {
			iPosInset = oNodeContext.positionInParent + 1;
		}

		return {
			setSize: iSetSize,
			posInset: iPosInset
		};
	};

	Tree.prototype.onItemLongDragOver = function(oItem) {
		var iIndex = this.indexOfItem(oItem);
		this._updateDeepestLevel(oItem);

		this.getBinding("items").expand(iIndex);
	};

	Tree.prototype.isGrouped = function() {
		return false;
	};

	return Tree;

});<|endoftext|>