<commit_before>import Sequelize from 'sequelize';
import parse from './parse';
import {merge} from 'ramda';

const PREBUILT_QUERY = {
    SHOW_DATABASES: 'SHOW_DATABASES',
    SHOW_TABLES: 'SHOW_TABLES',
    SHOW5ROWS: 'SHOW5ROWS'
};

const timestamp = () => (new Date()).toTimeString();
const emptyTableLog = (table) => {
    return `NOTE: table [${table}] seems to be empty`;
};
const emptyTable = {
    columnnames: ['NA'],
    rows: [['empty table']],
    ncols: 1,
    nrows: 1
};
const isEmpty = (table) => {
    return table.length === 0;
};
const intoArray = (objects) => {
    return objects.map(obj => obj[Object.keys(obj)]);
};

function assembleTablesPreviewMessage(tablePreviews) {
    /*
        topRows is an array of one or many responses of top 5 rows queries
        [ {'table1':[top5rows]}, {'table2': [top5rows]} ...]
    */
    let parsedRows;
    return tablePreviews.map( (tablePreview) => {
        const tableName = Object.keys(tablePreview);
        const rawData = tablePreview[tableName];

        if (isEmpty(rawData)) {
            parsedRows = EMPTY_TABLE;
        } else {
            parsedRows = parse(rawData);
        }
        console.log('tableName: parsedRows');
        console.log({[tableName]: parsedRows});
        return {[tableName]: parsedRows};
    });
}

export default class SequelizeManager {
    constructor(log) {
        // TODO: can respondEvent be part of the class?
        this.log = log;
    }

    login({username, password, database, portNumber, engine, databasePath, server}, callback) {
        // create new sequelize object
    getDialect() {
        return this.connection.options.dialect;
    }

    setQueryType(type) {
        // type = SELECT for `SELECT` query
        return {type: this.connection.QueryTypes[type]};
    }

    intoTablesArray(results) {
        let tables;
        if (this.getDialect() === 'sqlite') {
            // sqlite returns an array by default
            tables = results;
        } else {
            // others return list of objects
            tables = intoArray(results);
        }
        return tables;
    }

        this.connection = new Sequelize(database, username, password, {
            dialect: engine,
            host: server,
            port: portNumber,
            storage: databasePath
        });

        if (this.connection.config.dialect === 'mssql') {
            this.connection.config.dialectOptions = {encrypt: true};
        }

        // returns a message promise from the database
        return this.connection.authenticate().then((message) => {
            callback(message);
        });
    }

    raiseErrorLog(error) {
        this.log(merge(error, {timestamp: timestamp()}));
    }

    // built-in query to show available databases/schemes
    showDatabases(callback) {
        // constants for cleaner code
        const query = this.getPresetQuery(PREBUILT_QUERY.SHOW_DATABASES);
        const dialect = this.getDialect();

        // deal with sqlite -> has no databases list
        if (dialect === 'sqlite') {
            callback({
                databases: ['SQLITE database accessed'],
                error: null,
                tables: null
            });
            // skip SHOW_DATABASES query and send SHOW_TABLES query right away
            return this.showTables(callback);
        }

        return this.connection.query(query, this.setQueryType('SELECT'))
            .then(results => {
                callback({
                    databases: intoArray(results),
                    error: null,
                    /*
                        if user wants to see all databases/schemes, clear
                        tables from previously selected database/schemes
                    */
                    tables: null
                });
            });
    }

    // built-in query to show available tables in a database/scheme
    showTables(callback) {
        // constants for cleaner code
        const query = this.getPresetQuery(PREBUILT_QUERY.SHOW_TABLES);
        const dialect = this.getDialect();

        return this.connection.query(showtables, this.setQueryType('SELECT'))
            .then(results => {
                const tables = this.intoTablesArray(results);

                const promises = tables.map(table => {
                    const query = this.getPresetQuery(
                        PREBUILT_QUERY.SHOW5ROWS, table
                    );
                    this.log(ipc, query);
                    return this.connection.query(query, {type: noMetaData});
                });

                    return this.connection.query(show5rows, this.setQueryType('SELECT'))
                        .then((selectTableResults) => {
                            return {
                                [table]: selectTableResults
                            };
                        });
                });

                return Promise.all(promises)
                    .then(tablePreviews => {
                        callback({
                            error: null,
                            tables: assembleTablesPreviewMessage(tablePreviews)
                        });

                });
            });
    }

    sendQuery(respondEvent, query) {
        // TODO: SQL Injection security hole
        return this.connection.query(query)
            .then((results, metadata) => {
                callback({
                    error: null,
                    rows: parse(results)
                });
            });
    }

    disconnect(respondEvent, callback) {
        /*
            does not return a promise for now. open issue here:
            https://github.com/sequelize/sequelize/pull/5776
        */
        this.connection.close();
        callback({
            databases: null,
            error: null,
            rows: null,
            tables: null
        });
    }

    getPresetQuery(showQuerySelector, table = null) {
        const dialect = this.connection.options.dialect;
        switch (showQuerySelector) {
            case PREBUILT_QUERY.SHOW_DATABASES:
                switch (dialect) {
                    case 'mysql':
                    case 'sqlite':
                    case 'mariadb':
                        return 'SHOW DATABASES';
                    case 'postgres':
                        return 'SELECT datname AS database FROM ' +
                        'pg_database WHERE datistemplate = false;';
                    case 'mssql':
                        return 'SELECT name FROM Sys.Databases';
                    default:
                        throw new Error('could not build a presetQuery');
                }

            case PREBUILT_QUERY.SHOW_TABLES:
                switch (dialect) {
                    case 'mysql':
                    case 'mariadb':
                        return 'SHOW TABLES';
                    case 'postgres':
                        return 'SELECT table_name FROM ' +
                            'information_schema.tables WHERE ' +
                            'table_schema = \'public\'';
                    case 'mssql':
                        return 'SELECT TABLE_NAME FROM ' +
                            'information_schema.tables';
                    case 'sqlite':
                        return 'SELECT name FROM ' +
                        'sqlite_master WHERE type="table"';
                    default:
                        throw new Error('could not build a presetQuery');
                }

            case PREBUILT_QUERY.SHOW5ROWS:
                switch (dialect) {
                    case 'mysql':
                    case 'sqlite':
                    case 'mariadb':
                    case 'postgres':
                        return `SELECT * FROM ${table} LIMIT 5`;
                    case 'mssql':
                        return 'SELECT TOP 5 * FROM ' +
                            `${this.connection.config.database}.dbo.${table}`;
                    default:
                        throw new Error('could not build a presetQuery');
                }
        }
    }
}
<commit_msg>:wrench: login log update is in the messageHandler<commit_after>import Sequelize from 'sequelize';
import parse from './parse';
import {merge} from 'ramda';

const PREBUILT_QUERY = {
    SHOW_DATABASES: 'SHOW_DATABASES',
    SHOW_TABLES: 'SHOW_TABLES',
    SHOW5ROWS: 'SHOW5ROWS'
};

const timestamp = () => (new Date()).toTimeString();
const emptyTableLog = (table) => {
    return `NOTE: table [${table}] seems to be empty`;
};
const emptyTable = {
    columnnames: ['NA'],
    rows: [['empty table']],
    ncols: 1,
    nrows: 1
};
const isEmpty = (table) => {
    return table.length === 0;
};
const intoArray = (objects) => {
    return objects.map(obj => obj[Object.keys(obj)]);
};

function assembleTablesPreviewMessage(tablePreviews) {
    /*
        topRows is an array of one or many responses of top 5 rows queries
        [ {'table1':[top5rows]}, {'table2': [top5rows]} ...]
    */
    let parsedRows;
    return tablePreviews.map( (tablePreview) => {
        const tableName = Object.keys(tablePreview);
        const rawData = tablePreview[tableName];

        if (isEmpty(rawData)) {
            parsedRows = EMPTY_TABLE;
        } else {
            parsedRows = parse(rawData);
        }
        console.log('tableName: parsedRows');
        console.log({[tableName]: parsedRows});
        return {[tableName]: parsedRows};
    });
}

export default class SequelizeManager {
    constructor(log) {
        // TODO: can respondEvent be part of the class?
        this.log = log;
    }

    getDialect() {
        return this.connection.options.dialect;
    }

    setQueryType(type) {
        // type = SELECT for `SELECT` query
        return {type: this.connection.QueryTypes[type]};
    }

    intoTablesArray(results) {
        let tables;
        if (this.getDialect() === 'sqlite') {
            // sqlite returns an array by default
            tables = results;
        } else {
            // others return list of objects
            tables = intoArray(results);
        }
        return tables;
    }

    login({username, password, database, portNumber, engine, databasePath, server}) {
        this.connection = new Sequelize(database, username, password, {
            dialect: engine,
            host: server,
            port: portNumber,
            storage: databasePath
        });

        if (this.connection.config.dialect === 'mssql') {
            this.connection.config.dialectOptions = {encrypt: true};
        }
        return this.connection.authenticate();
    }

    }

    raiseErrorLog(error) {
        this.log(merge(error, {timestamp: timestamp()}));
    }

    // built-in query to show available databases/schemes
    showDatabases(callback) {
        // constants for cleaner code
        const query = this.getPresetQuery(PREBUILT_QUERY.SHOW_DATABASES);
        const dialect = this.getDialect();

        // deal with sqlite -> has no databases list
        if (dialect === 'sqlite') {
            callback({
                databases: ['SQLITE database accessed'],
                error: null,
                tables: null
            });
            // skip SHOW_DATABASES query and send SHOW_TABLES query right away
            return this.showTables(callback);
        }

        return this.connection.query(query, this.setQueryType('SELECT'))
            .then(results => {
                callback({
                    databases: intoArray(results),
                    error: null,
                    /*
                        if user wants to see all databases/schemes, clear
                        tables from previously selected database/schemes
                    */
                    tables: null
                });
            });
    }

    // built-in query to show available tables in a database/scheme
    showTables(callback) {
        // constants for cleaner code
        const query = this.getPresetQuery(PREBUILT_QUERY.SHOW_TABLES);
        const dialect = this.getDialect();

        return this.connection.query(showtables, this.setQueryType('SELECT'))
            .then(results => {
                const tables = this.intoTablesArray(results);

                const promises = tables.map(table => {
                    const query = this.getPresetQuery(
                        PREBUILT_QUERY.SHOW5ROWS, table
                    );
                    this.log(ipc, query);
                    return this.connection.query(query, {type: noMetaData});
                });

                    return this.connection.query(show5rows, this.setQueryType('SELECT'))
                        .then((selectTableResults) => {
                            return {
                                [table]: selectTableResults
                            };
                        });
                });

                return Promise.all(promises)
                    .then(tablePreviews => {
                        callback({
                            error: null,
                            tables: assembleTablesPreviewMessage(tablePreviews)
                        });

                });
            });
    }

    sendQuery(respondEvent, query) {
        // TODO: SQL Injection security hole
        return this.connection.query(query)
            .then((results, metadata) => {
                callback({
                    error: null,
                    rows: parse(results)
                });
            });
    }

    disconnect(respondEvent, callback) {
        /*
            does not return a promise for now. open issue here:
            https://github.com/sequelize/sequelize/pull/5776
        */
        this.connection.close();
        callback({
            databases: null,
            error: null,
            rows: null,
            tables: null
        });
    }

    getPresetQuery(showQuerySelector, table = null) {
        const dialect = this.connection.options.dialect;
        switch (showQuerySelector) {
            case PREBUILT_QUERY.SHOW_DATABASES:
                switch (dialect) {
                    case 'mysql':
                    case 'sqlite':
                    case 'mariadb':
                        return 'SHOW DATABASES';
                    case 'postgres':
                        return 'SELECT datname AS database FROM ' +
                        'pg_database WHERE datistemplate = false;';
                    case 'mssql':
                        return 'SELECT name FROM Sys.Databases';
                    default:
                        throw new Error('could not build a presetQuery');
                }

            case PREBUILT_QUERY.SHOW_TABLES:
                switch (dialect) {
                    case 'mysql':
                    case 'mariadb':
                        return 'SHOW TABLES';
                    case 'postgres':
                        return 'SELECT table_name FROM ' +
                            'information_schema.tables WHERE ' +
                            'table_schema = \'public\'';
                    case 'mssql':
                        return 'SELECT TABLE_NAME FROM ' +
                            'information_schema.tables';
                    case 'sqlite':
                        return 'SELECT name FROM ' +
                        'sqlite_master WHERE type="table"';
                    default:
                        throw new Error('could not build a presetQuery');
                }

            case PREBUILT_QUERY.SHOW5ROWS:
                switch (dialect) {
                    case 'mysql':
                    case 'sqlite':
                    case 'mariadb':
                    case 'postgres':
                        return `SELECT * FROM ${table} LIMIT 5`;
                    case 'mssql':
                        return 'SELECT TOP 5 * FROM ' +
                            `${this.connection.config.database}.dbo.${table}`;
                    default:
                        throw new Error('could not build a presetQuery');
                }
        }
    }
}
<|endoftext|>


<commit_before>import * as utils from '../src/utils'

import { config } from '../src/config'
import includes from 'core-js/library/fn/array/includes';
import { registerBidder } from '../src/adapters/bidderFactory'

const BIDDER_CODE = 'gumgum'
const ALIAS_BIDDER_CODE = ['gg']
const BID_ENDPOINT = `https://g2.gumgum.com/hbid/imp`
const DT_CREDENTIALS = { member: 'YcXr87z2lpbB' }
const TIME_TO_LIVE = 60

let browserParams = {};
let pageViewId = null

// TODO: potential 0 values for browserParams sent to ad server
function _getBrowserParams(topWindowUrl) {
  let topWindow
  let topScreen
  let topUrl
  let ggad
  let ns
  function getNetworkSpeed () {
    const connection = window.navigator && (window.navigator.connection || window.navigator.mozConnection || window.navigator.webkitConnection)
    const Mbps = connection && (connection.downlink || connection.bandwidth)
    return Mbps ? Math.round(Mbps * 1024) : null // 1 megabit -> 1024 kilobits
  }
  function getOgURL () {
    let ogURL = ''
    const ogURLSelector = "meta[property='og:url']"
    const head = document && document.getElementsByTagName('head')[0]
    const ogURLElement = head.querySelector(ogURLSelector)
    ogURL = ogURLElement ? ogURLElement.content : null
    return ogURL
  }
  if (browserParams.vw) {
    // we've already initialized browserParams, just return it.
    return browserParams
  }

  try {
    topWindow = global.top;
    topScreen = topWindow.screen;
    topUrl = topWindowUrl || utils.getTopWindowUrl();
  } catch (error) {
    utils.logError(error);
    return browserParams
  }

  browserParams = {
    vw: topWindow.innerWidth,
    vh: topWindow.innerHeight,
    sw: topScreen.width,
    sh: topScreen.height,
    pu: topUrl,
    ce: utils.cookiesAreEnabled(),
    dpr: topWindow.devicePixelRatio || 1,
    jcsi: JSON.stringify({ t: 0, rq: 8 }),
    ogu: getOgURL()
  }

  ns = getNetworkSpeed()
  if (ns) {
    browserParams.ns = ns
  }

  ggad = (topUrl.match(/#ggad=(\w+)$/) || [0, 0])[1]
  if (ggad) {
    browserParams[isNaN(ggad) ? 'eAdBuyId' : 'adBuyId'] = ggad
  }
  return browserParams
}

function getWrapperCode(wrapper, data) {
  return wrapper.replace('AD_JSON', window.btoa(JSON.stringify(data)))
}

function _getTradeDeskIDParam(userId) {
  const unifiedIdObj = {};
  if (userId.tdid) {
    unifiedIdObj.tdid = userId.tdid;
  }
  return unifiedIdObj;
}

function _getDigiTrustQueryParams(userId) {
  let digiTrustId = userId.digitrustid && userId.digitrustid.data;
  if (!digiTrustId) {
    const digiTrustUser = (window.DigiTrust && window.DigiTrust.getUser) ? window.DigiTrust.getUser(DT_CREDENTIALS) : {};
    digiTrustId = (digiTrustUser && digiTrustUser.success && digiTrustUser.identity) || '';
  }
  // Verify there is an ID and this user has not opted out
  if (!digiTrustId || (digiTrustId.privacy && digiTrustId.privacy.optout)) {
    return {};
  }
  return {
    dt: digiTrustId.id
  };
}

/**
 * Determines whether or not the given bid request is valid.
 *
 * @param {BidRequest} bid The bid params to validate.
 * @return boolean True if this is a valid bid, and false otherwise.
 */
function isBidRequestValid (bid) {
  const {
    params,
    adUnitCode
  } = bid;

  switch (true) {
    case !!(params.inScreen): break;
    case !!(params.inSlot): break;
    case !!(params.ICV): break;
    default:
      utils.logWarn(`[GumGum] No product selected for the placement ${adUnitCode}, please check your implementation.`);
      return false;
  }

  if (params.bidfloor && !(typeof params.bidfloor === 'number' && isFinite(params.bidfloor))) {
    utils.logWarn('[GumGum] bidfloor must be a Number');
    return false;
  }

  return true;
}

/**
 * Make a server request from the list of BidRequests.
 *
 * @param {validBidRequests[]} - an array of bids
 * @return ServerRequest Info describing the request to the server.
 */
function buildRequests (validBidRequests, bidderRequest) {
  const bids = [];
  const gdprConsent = Object.assign({ consentString: null, gdprApplies: true }, bidderRequest && bidderRequest.gdprConsent)
  utils._each(validBidRequests, bidRequest => {
    const timeout = config.getConfig('bidderTimeout');
    const {
      bidId,
      params = {},
      transactionId,
      userId = {}
    } = bidRequest;
    const data = {};
    const topWindowUrl = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer;
    if (pageViewId) {
      data.pv = pageViewId
    }
    if (params.bidfloor) {
      data.fp = params.bidfloor;
    }
    if (params.inScreen) {
      data.t = params.inScreen;
      data.pi = 2;
    }
    if (params.inSlot) {
      data.si = parseInt(params.inSlot, 10);
      data.pi = 3;
    }
    if (params.ICV) {
      data.ni = parseInt(params.ICV, 10);
      data.pi = 5;
    }
    data.gdprApplies = gdprConsent.gdprApplies ? 1 : 0;
    if (gdprConsent.gdprApplies) {
      data.gdprConsent = gdprConsent.consentString;
    }

    bids.push({
      id: bidId,
      tmax: timeout,
      tId: transactionId,
      pi: data.pi,
      selector: params.selector,
      sizes: bidRequest.sizes || bidRequest.mediatype[banner].sizes,
      url: BID_ENDPOINT,
      method: 'GET',
      data: Object.assign(data, _getBrowserParams(topWindowUrl), _getDigiTrustQueryParams(userId), _getTradeDeskIDParam(userId))
    })
  });
  return bids;
}

/**
 * Unpack the response from the server into a list of bids.
 *
 * @param {*} serverResponse A successful response from the server.
 * @return {Bid[]} An array of bids which were nested inside the server.
 */
function interpretResponse (serverResponse, bidRequest) {
  const bidResponses = []
  const serverResponseBody = serverResponse.body
  const defaultResponse = {
    ad: {
      price: 0,
      id: 0,
      markup: ''
    },
    pag: {
      pvid: 0
    }
  }
  const {
    ad: {
      price: cpm,
      id: creativeId,
      markup
    },
    cw: wrapper,
    pag: {
      pvid
    }
  } = Object.assign(defaultResponse, serverResponseBody)
  let data = bidRequest.data || {}
  let product = data.pi
  let isTestUnit = (product === 3 && data.si === 9)
  let sizes = utils.parseSizesInput(bidRequest.sizes)
  let [width, height] = sizes[0].split('x')

  // return 1x1 when breakout expected
  if (product === 5 && includes(sizes, '1x1')) {
    width = '1'
    height = '1'
  }

  // update Page View ID from server response
  pageViewId = pvid

  if (creativeId) {
    bidResponses.push({
      // dealId: DEAL_ID,
      // referrer: REFERER,
      ad: wrapper ? getWrapperCode(wrapper, Object.assign({}, serverResponseBody, { bidRequest })) : markup,
      cpm: isTestUnit ? 0.1 : cpm,
      creativeId,
      currency: 'USD',
      height,
      netRevenue: true,
      requestId: bidRequest.id,
      ttl: TIME_TO_LIVE,
      width
    })
  }
  return bidResponses
}

/**
 * Register the user sync pixels which should be dropped after the auction.
 *
 * @param {SyncOptions} syncOptions Which user syncs are allowed?
 * @param {ServerResponse[]} serverResponses List of server's responses.
 * @return {UserSync[]} The user syncs which should be dropped.
 */
function getUserSyncs (syncOptions, serverResponses) {
  const responses = serverResponses.map((response) => {
    return (response.body && response.body.pxs && response.body.pxs.scr) || []
  })
  const userSyncs = responses.reduce(function (usersyncs, response) {
    return usersyncs.concat(response)
  }, [])
  const syncs = userSyncs.map((sync) => {
    return {
      type: sync.t === 'f' ? 'iframe' : 'image',
      url: sync.u
    }
  })
  return syncs;
}

export const spec = {
  code: BIDDER_CODE,
  aliases: ALIAS_BIDDER_CODE,
  isBidRequestValid,
  buildRequests,
  interpretResponse,
  getUserSyncs
}
registerBidder(spec)
<commit_msg>GumGum: only send gdprConsent when found (#4205)<commit_after>import * as utils from '../src/utils'

import { config } from '../src/config'
import includes from 'core-js/library/fn/array/includes';
import { registerBidder } from '../src/adapters/bidderFactory'

const BIDDER_CODE = 'gumgum'
const ALIAS_BIDDER_CODE = ['gg']
const BID_ENDPOINT = `https://g2.gumgum.com/hbid/imp`
const DT_CREDENTIALS = { member: 'YcXr87z2lpbB' }
const TIME_TO_LIVE = 60

let browserParams = {};
let pageViewId = null

// TODO: potential 0 values for browserParams sent to ad server
function _getBrowserParams(topWindowUrl) {
  let topWindow
  let topScreen
  let topUrl
  let ggad
  let ns
  function getNetworkSpeed () {
    const connection = window.navigator && (window.navigator.connection || window.navigator.mozConnection || window.navigator.webkitConnection)
    const Mbps = connection && (connection.downlink || connection.bandwidth)
    return Mbps ? Math.round(Mbps * 1024) : null // 1 megabit -> 1024 kilobits
  }
  function getOgURL () {
    let ogURL = ''
    const ogURLSelector = "meta[property='og:url']"
    const head = document && document.getElementsByTagName('head')[0]
    const ogURLElement = head.querySelector(ogURLSelector)
    ogURL = ogURLElement ? ogURLElement.content : null
    return ogURL
  }
  if (browserParams.vw) {
    // we've already initialized browserParams, just return it.
    return browserParams
  }

  try {
    topWindow = global.top;
    topScreen = topWindow.screen;
    topUrl = topWindowUrl || utils.getTopWindowUrl();
  } catch (error) {
    utils.logError(error);
    return browserParams
  }

  browserParams = {
    vw: topWindow.innerWidth,
    vh: topWindow.innerHeight,
    sw: topScreen.width,
    sh: topScreen.height,
    pu: topUrl,
    ce: utils.cookiesAreEnabled(),
    dpr: topWindow.devicePixelRatio || 1,
    jcsi: JSON.stringify({ t: 0, rq: 8 }),
    ogu: getOgURL()
  }

  ns = getNetworkSpeed()
  if (ns) {
    browserParams.ns = ns
  }

  ggad = (topUrl.match(/#ggad=(\w+)$/) || [0, 0])[1]
  if (ggad) {
    browserParams[isNaN(ggad) ? 'eAdBuyId' : 'adBuyId'] = ggad
  }
  return browserParams
}

function getWrapperCode(wrapper, data) {
  return wrapper.replace('AD_JSON', window.btoa(JSON.stringify(data)))
}

function _getTradeDeskIDParam(userId) {
  const unifiedIdObj = {};
  if (userId.tdid) {
    unifiedIdObj.tdid = userId.tdid;
  }
  return unifiedIdObj;
}

function _getDigiTrustQueryParams(userId) {
  let digiTrustId = userId.digitrustid && userId.digitrustid.data;
  if (!digiTrustId) {
    const digiTrustUser = (window.DigiTrust && window.DigiTrust.getUser) ? window.DigiTrust.getUser(DT_CREDENTIALS) : {};
    digiTrustId = (digiTrustUser && digiTrustUser.success && digiTrustUser.identity) || '';
  }
  // Verify there is an ID and this user has not opted out
  if (!digiTrustId || (digiTrustId.privacy && digiTrustId.privacy.optout)) {
    return {};
  }
  return {
    dt: digiTrustId.id
  };
}

/**
 * Determines whether or not the given bid request is valid.
 *
 * @param {BidRequest} bid The bid params to validate.
 * @return boolean True if this is a valid bid, and false otherwise.
 */
function isBidRequestValid (bid) {
  const {
    params,
    adUnitCode
  } = bid;

  switch (true) {
    case !!(params.inScreen): break;
    case !!(params.inSlot): break;
    case !!(params.ICV): break;
    default:
      utils.logWarn(`[GumGum] No product selected for the placement ${adUnitCode}, please check your implementation.`);
      return false;
  }

  if (params.bidfloor && !(typeof params.bidfloor === 'number' && isFinite(params.bidfloor))) {
    utils.logWarn('[GumGum] bidfloor must be a Number');
    return false;
  }

  return true;
}

/**
 * Make a server request from the list of BidRequests.
 *
 * @param {validBidRequests[]} - an array of bids
 * @return ServerRequest Info describing the request to the server.
 */
function buildRequests (validBidRequests, bidderRequest) {
  const bids = [];
  const gdprConsent = bidderRequest && bidderRequest.gdprConsent;
  utils._each(validBidRequests, bidRequest => {
    const timeout = config.getConfig('bidderTimeout');
    const {
      bidId,
      params = {},
      transactionId,
      userId = {}
    } = bidRequest;
    const data = {};
    const topWindowUrl = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer;
    if (pageViewId) {
      data.pv = pageViewId
    }
    if (params.bidfloor) {
      data.fp = params.bidfloor;
    }
    if (params.inScreen) {
      data.t = params.inScreen;
      data.pi = 2;
    }
    if (params.inSlot) {
      data.si = parseInt(params.inSlot, 10);
      data.pi = 3;
    }
    if (params.ICV) {
      data.ni = parseInt(params.ICV, 10);
      data.pi = 5;
    }
    if (gdprConsent) {
      data.gdprApplies = gdprConsent.gdprApplies ? 1 : 0;
    }
    if (data.gdprApplies) {
      data.gdprConsent = gdprConsent.consentString;
    }

    bids.push({
      id: bidId,
      tmax: timeout,
      tId: transactionId,
      pi: data.pi,
      selector: params.selector,
      sizes: bidRequest.sizes || bidRequest.mediatype[banner].sizes,
      url: BID_ENDPOINT,
      method: 'GET',
      data: Object.assign(data, _getBrowserParams(topWindowUrl), _getDigiTrustQueryParams(userId), _getTradeDeskIDParam(userId))
    })
  });
  return bids;
}

/**
 * Unpack the response from the server into a list of bids.
 *
 * @param {*} serverResponse A successful response from the server.
 * @return {Bid[]} An array of bids which were nested inside the server.
 */
function interpretResponse (serverResponse, bidRequest) {
  const bidResponses = []
  const serverResponseBody = serverResponse.body
  const defaultResponse = {
    ad: {
      price: 0,
      id: 0,
      markup: ''
    },
    pag: {
      pvid: 0
    }
  }
  const {
    ad: {
      price: cpm,
      id: creativeId,
      markup
    },
    cw: wrapper,
    pag: {
      pvid
    }
  } = Object.assign(defaultResponse, serverResponseBody)
  let data = bidRequest.data || {}
  let product = data.pi
  let isTestUnit = (product === 3 && data.si === 9)
  let sizes = utils.parseSizesInput(bidRequest.sizes)
  let [width, height] = sizes[0].split('x')

  // return 1x1 when breakout expected
  if (product === 5 && includes(sizes, '1x1')) {
    width = '1'
    height = '1'
  }

  // update Page View ID from server response
  pageViewId = pvid

  if (creativeId) {
    bidResponses.push({
      // dealId: DEAL_ID,
      // referrer: REFERER,
      ad: wrapper ? getWrapperCode(wrapper, Object.assign({}, serverResponseBody, { bidRequest })) : markup,
      cpm: isTestUnit ? 0.1 : cpm,
      creativeId,
      currency: 'USD',
      height,
      netRevenue: true,
      requestId: bidRequest.id,
      ttl: TIME_TO_LIVE,
      width
    })
  }
  return bidResponses
}

/**
 * Register the user sync pixels which should be dropped after the auction.
 *
 * @param {SyncOptions} syncOptions Which user syncs are allowed?
 * @param {ServerResponse[]} serverResponses List of server's responses.
 * @return {UserSync[]} The user syncs which should be dropped.
 */
function getUserSyncs (syncOptions, serverResponses) {
  const responses = serverResponses.map((response) => {
    return (response.body && response.body.pxs && response.body.pxs.scr) || []
  })
  const userSyncs = responses.reduce(function (usersyncs, response) {
    return usersyncs.concat(response)
  }, [])
  const syncs = userSyncs.map((sync) => {
    return {
      type: sync.t === 'f' ? 'iframe' : 'image',
      url: sync.u
    }
  })
  return syncs;
}

export const spec = {
  code: BIDDER_CODE,
  aliases: ALIAS_BIDDER_CODE,
  isBidRequestValid,
  buildRequests,
  interpretResponse,
  getUserSyncs
}
registerBidder(spec)
<|endoftext|>


<commit_before>var Gaffa = require('gaffa'),
    crel = require('crel'),
    doc = require('doc-js');

function FormElement(){}
FormElement = Gaffa.createSpec(FormElement, Gaffa.View);
FormElement.prototype._type = 'formElement';

FormElement.prototype.render = function(){
    var view = this,
        renderedElement = this.renderedElement = this.renderedElement || crel('input'),
        formElement = this.formElement = this.formElement || renderedElement;

    doc.on(this.updateEventName || "change", formElement, function(){
        view.value.set(formElement.value);
        view.valid.set(formElement.validity.valid);
    });
};

FormElement.prototype.value = new Gaffa.Property(function(view, value){
    value = value || '';

    var element = view.formElement,
        caretPosition = 0,

        // This is only necessary because IE10 and Chrome is a pile of crap (i know what a surprise)
        hasCaret =
            element === document.activeElement &&
            element.type !== 'number' &&
            element.type !== 'email' &&
            element.type !== 'time' &&
            element.type !== 'color' &&
            element.type !== 'month' &&
            element.type !== 'range' &&
            element.type !== 'date';

    // Skip if the text hasnt changed
    if(value === element.value){
        return;
    }

    // Inspiration taken from http://stackoverflow.com/questions/2897155/get-caret-position-within-an-text-input-field
    // but WOW is that some horrendous code!
    if(hasCaret){
        if (window.document.selection) {
            var selection = window.document.selection.createRange();
            selection.moveStart('character', -element.value.length);
            caretPosition = selection.text.length;
        }
        else if (element.selectionStart || element.selectionStart == '0'){
            caretPosition = element.selectionStart;
        }
    }

    element.value = value;

    if(hasCaret){
        if(element.createTextRange) {
            var range = element.createTextRange();

            range.move('character', caretPosition);

            range.select();
        }
        if(element.selectionStart) {
            element.setSelectionRange(caretPosition, caretPosition);
        }
    }

    view.valid.set(element.validity.valid);
});

FormElement.prototype.type = new Gaffa.Property(function(view, value){
    view.formElement.setAttribute('type', value != null ? value : "");
});

FormElement.prototype.placeholder = new Gaffa.Property(function(view, value){
    view.formElement.setAttribute('placeholder', value != null ? value : "");
});

FormElement.prototype.required = new Gaffa.Property(function(view, value){
    if (value){
        view.formElement.setAttribute('required', 'required');
    }else{
        view.formElement.removeAttribute('required');
    }
});

FormElement.prototype.valid = new Gaffa.Property();
FormElement.prototype.validity = new Gaffa.Property(function(view, value){
    value = value || '';

    view.formElement.setCustomValidity(value);
});
FormElement.prototype.enabled = new Gaffa.Property({
    update: function(view, value){
        view.formElement[value ? 'removeAttribute' : 'setAttribute']('disabled','disabled');
    },
    value: true
});

module.exports = FormElement;<commit_msg>put caret check into an array, replace many codes with set-input-value<commit_after>var Gaffa = require('gaffa'),
    crel = require('crel'),
    doc = require('doc-js'),
    setInputValue = require('set-input-value');

function FormElement(){}
FormElement = Gaffa.createSpec(FormElement, Gaffa.View);
FormElement.prototype._type = 'formElement';

FormElement.prototype.render = function(){
    var view = this,
        renderedElement = this.renderedElement = this.renderedElement || crel('input'),
        formElement = this.formElement = this.formElement || renderedElement;

    doc.on(this.updateEventName || "change", formElement, function(){
        view.value.set(formElement.value);
        view.valid.set(formElement.validity.valid);
    });
};

FormElement.prototype.value = new Gaffa.Property(function(view, value){
    value = value || '';

    var element = view.FormElement;

    if(~['number', 'email', 'time', 'color', 'month', 'range', 'date'].indexOf(element.type)){
        element.value = value;
    } else {
        setInputValue(element, value);
    }

    view.valid.set(element.validity.valid);
});

FormElement.prototype.type = new Gaffa.Property(function(view, value){
    view.formElement.setAttribute('type', value != null ? value : "");
});

FormElement.prototype.placeholder = new Gaffa.Property(function(view, value){
    view.formElement.setAttribute('placeholder', value != null ? value : "");
});

FormElement.prototype.required = new Gaffa.Property(function(view, value){
    if (value){
        view.formElement.setAttribute('required', 'required');
    }else{
        view.formElement.removeAttribute('required');
    }
});

FormElement.prototype.valid = new Gaffa.Property();
FormElement.prototype.validity = new Gaffa.Property(function(view, value){
    value = value || '';

    view.formElement.setCustomValidity(value);
});
FormElement.prototype.enabled = new Gaffa.Property({
    update: function(view, value){
        view.formElement[value ? 'removeAttribute' : 'setAttribute']('disabled','disabled');
    },
    value: true
});

module.exports = FormElement;<|endoftext|>


<commit_before>import { recalculateScore } from '../modules/scoring.js';

/*

Update a document's score if necessary.

Returns how many documents have been updated (1 or 0).

*/
export const updateScore = ({collection, item, forceUpdate}) => { // Currently unused

  // Age Check

  const postedAt = item && item.postedAt && item.postedAt.valueOf();
  const now = new Date().getTime();
  const age = now - postedAt;
  const ageInHours = age / (60 * 60 * 1000);

  // If for some reason item doesn't have a "postedAt" property, abort
  // Or, if post has been scheduled in the future, don't update its score
  if (!postedAt || postedAt > now)
    return 0;

  // For performance reasons, the database is only updated if the difference between the old score and the new score
  // is meaningful enough. To find out, we calculate the "power" of a single vote after n days.
  // We assume that after n days, a single vote will not be powerful enough to affect posts' ranking order.
  // Note: sites whose posts regularly get a lot of votes can afford to use a lower n.

  // n =  number of days after which a single vote will not have a big enough effect to trigger a score update
  //      and posts can become inactive
  const n = 30;
  // x = score increase amount of a single vote after n days (for n=100, x=0.000040295)
  const x = 1/Math.pow(n*24+2,1.3);

  // HN algorithm
  const newScore = recalculateScore(item);

  // Note: before the first time updateScore runs on a new item, its score will be at 0
  const scoreDiff = Math.abs(item.score || 0 - newScore);

  // console.log('// now: ', now)
  // console.log('// age: ', age)
  // console.log('// ageInHours: ', ageInHours)
  // console.log('// baseScore: ', baseScore)
  // console.log('// item.score: ', item.score)
  // console.log('// newScore: ', newScore)
  // console.log('// scoreDiff: ', scoreDiff)
  // console.log('// x: ', x)

  // only update database if difference is larger than x to avoid unnecessary updates
  if (forceUpdate || scoreDiff > x) {
    collection.update(item._id, {$set: {score: newScore, inactive: false}});
    return 1;
  } else if(ageInHours > n*24) {
    // only set a post as inactive if it's older than n days
    collection.update(item._id, {$set: {inactive: true}});
  }
  return 0;
};

export const batchUpdateScore = async (collection, inactive = false, forceUpdate = false) => {
  // INACTIVITY_THRESHOLD_DAYS =  number of days after which a single vote will not have a big enough effect to trigger a score update
  //      and posts can become inactive
  const INACTIVITY_THRESHOLD_DAYS = 30;
  // time decay factor
  const TIME_DECAY_FACTOR = 1.15; //LW: Set this to 1.15 from 1.3 for LW purposes (want slower decay)
  // Basescore bonuses for various categories
  const FRONTPAGE_BONUS = 10;
  const FEATURED_BONUS = 10;
  // x = score increase amount of a single vote after n days (for n=100, x=0.000040295)
  const x = 1/Math.pow(INACTIVITY_THRESHOLD_DAYS*24+2,TIME_DECAY_FACTOR);

  const itemsPromise = collection.rawCollection().aggregate([
    {
      $match: {
        $and: [
          {postedAt: {$exists: true}},
          {postedAt: {$lte: new Date()}},
          {inactive: inactive ? true : {$ne: true}}
        ]
      }
    },
    {
      $project: {
        postedAt: 1,
        score: 1,
        frontpageDate: 1,
        curatedDate: 1,
        baseScore: { // Add optional bonuses to baseScore of posts
          $add: [
            "$baseScore",
            {$cond: {if: "$frontpageDate", then: FRONTPAGE_BONUS, else: 0}},
            {$cond: {if: "$curatedDate", then: FEATURED_BONUS, else: 0}}
          ]
        },
      }
    },
    {
      $project: {
        postedAt: 1,
        baseScore: 1,
        score: 1,
        newScore: {
          $divide: [
            "$baseScore",
              {
                $pow: [
                  {
                    $add: [
                      {
                        $divide: [
                          {
                            $subtract: [new Date(), "$postedAt"] // Age in miliseconds
                          },
                          60 * 60 * 1000
                        ]
                      }, // Age in hours
                      2
                    ]
                  },
                  TIME_DECAY_FACTOR
                ]
              }
            ]
        }
      }
    },
    {
      $project: {
        postedAt: 1,
        baseScore: 1,
        score: 1,
        newScore: 1,
        scoreDiffSignificant: {
          $gt: [
            {$abs: {$subtract: ["$score", "$newScore"]}},
            x
          ]
        },
        oldEnough: { // Only set a post as inactive if it's older than n days
          $gt: [
            {$divide: [
              {
                $subtract: [new Date(), "$postedAt"] // Difference in miliseconds
              },
              60 * 60 * 1000 //Difference in hours
            ]},
            INACTIVITY_THRESHOLD_DAYS*24]
        }
      }
    },
  ])

  const items = await itemsPromise;
  const itemsArray = await items.toArray();
  let updatedDocumentsCounter = 0;
  console.log("BatchScoreUpdate updateArray:", itemsArray);
  const itemUpdates = _.compact(itemsArray.map(i => {
    if (forceUpdate || i.scoreDiffSignificant) {
      updatedDocumentsCounter++;
      return {
        updateOne: {
          filter: {_id: i._id},
          update: {$set: {score: i.newScore, inactive: false}},
          upsert: false,
        }
      }
    } else if (i.oldEnough) {
      // only set a post as inactive if it's older than n days
      return {
        updateOne: {
          filter: {_id: i._id},
          update: {$set: {inactive: true}},
          upsert: false,
        }
      }
    }
  }))
  if (itemUpdates && itemUpdates.length) {await collection.rawCollection().bulkWrite(itemUpdates, {ordered: false});}
  return updatedDocumentsCounter;
}
<commit_msg>Removed unnecessary console log<commit_after>import { recalculateScore } from '../modules/scoring.js';

/*

Update a document's score if necessary.

Returns how many documents have been updated (1 or 0).

*/
export const updateScore = ({collection, item, forceUpdate}) => { // Currently unused

  // Age Check

  const postedAt = item && item.postedAt && item.postedAt.valueOf();
  const now = new Date().getTime();
  const age = now - postedAt;
  const ageInHours = age / (60 * 60 * 1000);

  // If for some reason item doesn't have a "postedAt" property, abort
  // Or, if post has been scheduled in the future, don't update its score
  if (!postedAt || postedAt > now)
    return 0;

  // For performance reasons, the database is only updated if the difference between the old score and the new score
  // is meaningful enough. To find out, we calculate the "power" of a single vote after n days.
  // We assume that after n days, a single vote will not be powerful enough to affect posts' ranking order.
  // Note: sites whose posts regularly get a lot of votes can afford to use a lower n.

  // n =  number of days after which a single vote will not have a big enough effect to trigger a score update
  //      and posts can become inactive
  const n = 30;
  // x = score increase amount of a single vote after n days (for n=100, x=0.000040295)
  const x = 1/Math.pow(n*24+2,1.3);

  // HN algorithm
  const newScore = recalculateScore(item);

  // Note: before the first time updateScore runs on a new item, its score will be at 0
  const scoreDiff = Math.abs(item.score || 0 - newScore);

  // console.log('// now: ', now)
  // console.log('// age: ', age)
  // console.log('// ageInHours: ', ageInHours)
  // console.log('// baseScore: ', baseScore)
  // console.log('// item.score: ', item.score)
  // console.log('// newScore: ', newScore)
  // console.log('// scoreDiff: ', scoreDiff)
  // console.log('// x: ', x)

  // only update database if difference is larger than x to avoid unnecessary updates
  if (forceUpdate || scoreDiff > x) {
    collection.update(item._id, {$set: {score: newScore, inactive: false}});
    return 1;
  } else if(ageInHours > n*24) {
    // only set a post as inactive if it's older than n days
    collection.update(item._id, {$set: {inactive: true}});
  }
  return 0;
};

export const batchUpdateScore = async (collection, inactive = false, forceUpdate = false) => {
  // INACTIVITY_THRESHOLD_DAYS =  number of days after which a single vote will not have a big enough effect to trigger a score update
  //      and posts can become inactive
  const INACTIVITY_THRESHOLD_DAYS = 30;
  // time decay factor
  const TIME_DECAY_FACTOR = 1.15; //LW: Set this to 1.15 from 1.3 for LW purposes (want slower decay)
  // Basescore bonuses for various categories
  const FRONTPAGE_BONUS = 10;
  const FEATURED_BONUS = 10;
  // x = score increase amount of a single vote after n days (for n=100, x=0.000040295)
  const x = 1/Math.pow(INACTIVITY_THRESHOLD_DAYS*24+2,TIME_DECAY_FACTOR);

  const itemsPromise = collection.rawCollection().aggregate([
    {
      $match: {
        $and: [
          {postedAt: {$exists: true}},
          {postedAt: {$lte: new Date()}},
          {inactive: inactive ? true : {$ne: true}}
        ]
      }
    },
    {
      $project: {
        postedAt: 1,
        score: 1,
        frontpageDate: 1,
        curatedDate: 1,
        baseScore: { // Add optional bonuses to baseScore of posts
          $add: [
            "$baseScore",
            {$cond: {if: "$frontpageDate", then: FRONTPAGE_BONUS, else: 0}},
            {$cond: {if: "$curatedDate", then: FEATURED_BONUS, else: 0}}
          ]
        },
      }
    },
    {
      $project: {
        postedAt: 1,
        baseScore: 1,
        score: 1,
        newScore: {
          $divide: [
            "$baseScore",
              {
                $pow: [
                  {
                    $add: [
                      {
                        $divide: [
                          {
                            $subtract: [new Date(), "$postedAt"] // Age in miliseconds
                          },
                          60 * 60 * 1000
                        ]
                      }, // Age in hours
                      2
                    ]
                  },
                  TIME_DECAY_FACTOR
                ]
              }
            ]
        }
      }
    },
    {
      $project: {
        postedAt: 1,
        baseScore: 1,
        score: 1,
        newScore: 1,
        scoreDiffSignificant: {
          $gt: [
            {$abs: {$subtract: ["$score", "$newScore"]}},
            x
          ]
        },
        oldEnough: { // Only set a post as inactive if it's older than n days
          $gt: [
            {$divide: [
              {
                $subtract: [new Date(), "$postedAt"] // Difference in miliseconds
              },
              60 * 60 * 1000 //Difference in hours
            ]},
            INACTIVITY_THRESHOLD_DAYS*24]
        }
      }
    },
  ])

  const items = await itemsPromise;
  const itemsArray = await items.toArray();
  let updatedDocumentsCounter = 0;
  const itemUpdates = _.compact(itemsArray.map(i => {
    if (forceUpdate || i.scoreDiffSignificant) {
      updatedDocumentsCounter++;
      return {
        updateOne: {
          filter: {_id: i._id},
          update: {$set: {score: i.newScore, inactive: false}},
          upsert: false,
        }
      }
    } else if (i.oldEnough) {
      // only set a post as inactive if it's older than n days
      return {
        updateOne: {
          filter: {_id: i._id},
          update: {$set: {inactive: true}},
          upsert: false,
        }
      }
    }
  }))
  if (itemUpdates && itemUpdates.length) {await collection.rawCollection().bulkWrite(itemUpdates, {ordered: false});}
  return updatedDocumentsCounter;
}
<|endoftext|>


<commit_before>import ContractAddress from "../fixtures/contractAddress.js";
import ContractStructure from "../fixtures/contractStructure.js";
import web3 from "web3";
import moment from "moment";
import Q from "q";
import PubSub from "pubsub-js"

web3.eth.getBalancePromise = Q.denodeify(web3.eth.getBalance);
web3.eth.getCodePromise = Q.denodeify(web3.eth.getCode);
web3.eth.getBlockPromise = Q.denodeify(web3.eth.getBlock);

class EthClient {
    constructor() {
        try {
            let url = null;
            if (window.localStorage && window.localStorage.getItem('rpc_url')) {
                url = window.localStorage.getItem('rpc_url');
            }
            this.setJsonRPCUrl(url || 'http://localhost:8080');

            let WorkerDispatcher = web3.eth.contract(ContractStructure.WorkerDispatcher);
            this.contract = new WorkerDispatcher(ContractAddress);
            this.identity = web3.shh.newIdentity();
            this._worker = this.isWorker();
        }
        catch(e) {
            console.error(e);
            console.log("Could not contact " + this.getJsonRPCUrl());
        }
    }
    getCoinbase() {
        return web3.eth.coinbase;
    }

    formatBalance(wei) {
        let unit = 'wei';

        if (wei > 10e18) {
            unit = 'ether';
        } else if (wei > 10e15) {
            unit = 'finney';
        }

        return (unit !== 'wei' ? web3.fromWei(wei, unit).toFormat() : wei) + ' ' + unit;
    }

    // returns a work agreement if present for the given worker
    checkForAgreement(worker) {
        let agreementAddress = this.contract.workersInfo(worker)[3];
        if (web3.toDecimal(agreementAddress) != 0) {
            let WorkAgreement = web3.eth.contract(ContractStructure.WorkAgreement);
            return new WorkAgreement(agreementAddress);
        }
    }

    getDashboard() {
        let coinbase = this.getCoinbase();
        let peerCount = web3.net.peerCount;
        return Q.all([
                web3.eth.getBalancePromise(coinbase),
                web3.eth.getCodePromise(ContractAddress),
                web3.eth.getBlockPromise(web3.eth.blockNumber)
        ]).then(([balance, code, block]) => {
            let workers = this.contract.numWorkers();
            let timestamp = moment.unix(block.timestamp);
            if (code.length > 50) {
                code = code.substring(0, 60) + '…';
            }

            return [
                {label: "Coinbase", value: coinbase},
                {label: "Accounts", value: web3.eth.accounts},
                {label: "Balance", value: this.formatBalance(balance), title: balance},
                {label: "Latest block", value: block.number},
                {label: "Latest block hash", value: block.hash},
                {
                    label: "Latest block timestamp",
                    value: timestamp.fromNow(),
                    title: timestamp.format('llll')
                },
                {label: "Contract address", value: ContractAddress},
                {label: "Number of workers", value: workers.toString()},
                {label: "Number of peers", value: peerCount},
                {label: "Code", value: code}
            ];
        });
    }

    registerWorker(maxLength, price, name) {
        this.contract.registerWorker(maxLength, price, name);
        this._worker = true;
    }

    changeWorkerPrice(newPrice) {
        this.contract.changeWorkerPrice(newPrice);
    }

    buyContract(worker, redundancy, price, length) {
        let options = {
            value: length * price,
            gas: 500000
        };
        this.contract.sendTransaction(options)
            .buyContract(worker, redundancy, length);
    }

    isWorker() {
        let numWorkers = this.contract.numWorkers().toNumber();
        for (let i = 0; i < numWorkers; i++) {
            if (web3.eth.coinbase === this.contract.workerList(i)) {
                return true;
            }
        }
        return false;
    }

    findWorkers(length, price) {
        let numWorkers = this.contract.numWorkers().toNumber();
        let workers = [];
        for (let i = 0; i < numWorkers; i++) {
            let address = this.contract.workerList(i);
            let [wName, wLength, wPrice] = this.contract.workersInfo(address);
            wLength = wLength.toNumber()
            wPrice = wPrice.toNumber();

            if (length <= wLength && price >= wPrice) {
                workers.push({
                    pubkey: address,
                    name: wName,
                    length: wLength,
                    price: wPrice
                });
            }
        }

        return workers
    }

    subscribe(callback) {
        return PubSub.subscribe('chain', callback);
    }

    unsubscribe(token) {
        PubSub.unsubscribe(token);
    }

    getJsonRPCUrl() {
        return this._jsonRpcUrl;
    }

    setJsonRPCUrl(url) {
        if (!url.startsWith('http')) {
            url = 'http://' + url;
        }
        this._jsonRpcUrl = url;
        if (window.localStorage) {
            window.localStorage.setItem('rpc_url', this._jsonRpcUrl);
        }
        if (this.chainFilter) {
            // web3.reset();
            this.chainFilter.stopWatching();
        }
        web3.setProvider(new web3.providers.HttpProvider(this._jsonRpcUrl));
        this.chainFilter = web3.eth.filter('chain');

        PubSub.publish('chain');
        this.chainFilter.watch(() => {
            PubSub.publish('chain');
        });
    }

    sendMsg(to, data) {
        web3.shh.post({
            from: this.identity,
            to: to,
            payload: [ web3.fromAscii(data) ],
        });
    }

    askWorker(workerAddress, contractAddress) {
        web3.shh.post({
            from: this.identity,
            topic: workerAddress,
            payload: [ contractAddress ],
        });
    }
}

let ethclient = new EthClient();

export default ethclient;
<commit_msg>Move unrelated calls out of try catch block<commit_after>import ContractAddress from "../fixtures/contractAddress.js";
import ContractStructure from "../fixtures/contractStructure.js";
import web3 from "web3";
import moment from "moment";
import Q from "q";
import PubSub from "pubsub-js"

web3.eth.getBalancePromise = Q.denodeify(web3.eth.getBalance);
web3.eth.getCodePromise = Q.denodeify(web3.eth.getCode);
web3.eth.getBlockPromise = Q.denodeify(web3.eth.getBlock);

class EthClient {
    constructor() {
        let url = null;
        if (window.localStorage && window.localStorage.getItem('rpc_url')) {
            url = window.localStorage.getItem('rpc_url');
        }
        try {
            this.setJsonRPCUrl(url || 'http://localhost:8080');
        } catch(e) {
            console.error("Could not contact %s, due to: %O", this.getJsonRPCUrl(), e);
        }

        let WorkerDispatcher = web3.eth.contract(ContractStructure.WorkerDispatcher);
        this.contract = new WorkerDispatcher(ContractAddress);
        this.identity = web3.shh.newIdentity();
        this._worker = this.isWorker();
    }
    getCoinbase() {
        return web3.eth.coinbase;
    }

    formatBalance(wei) {
        let unit = 'wei';

        if (wei > 10e18) {
            unit = 'ether';
        } else if (wei > 10e15) {
            unit = 'finney';
        }

        return (unit !== 'wei' ? web3.fromWei(wei, unit).toFormat() : wei) + ' ' + unit;
    }

    // returns a work agreement if present for the given worker
    checkForAgreement(worker) {
        let agreementAddress = this.contract.workersInfo(worker)[3];
        if (web3.toDecimal(agreementAddress) != 0) {
            let WorkAgreement = web3.eth.contract(ContractStructure.WorkAgreement);
            return new WorkAgreement(agreementAddress);
        }
    }

    getDashboard() {
        let coinbase = this.getCoinbase();
        let peerCount = web3.net.peerCount;
        return Q.all([
                web3.eth.getBalancePromise(coinbase),
                web3.eth.getCodePromise(ContractAddress),
                web3.eth.getBlockPromise(web3.eth.blockNumber)
        ]).then(([balance, code, block]) => {
            let workers = this.contract.numWorkers();
            let timestamp = moment.unix(block.timestamp);
            if (code.length > 50) {
                code = code.substring(0, 60) + '…';
            }

            return [
                {label: "Coinbase", value: coinbase},
                {label: "Accounts", value: web3.eth.accounts},
                {label: "Balance", value: this.formatBalance(balance), title: balance},
                {label: "Latest block", value: block.number},
                {label: "Latest block hash", value: block.hash},
                {
                    label: "Latest block timestamp",
                    value: timestamp.fromNow(),
                    title: timestamp.format('llll')
                },
                {label: "Contract address", value: ContractAddress},
                {label: "Number of workers", value: workers.toString()},
                {label: "Number of peers", value: peerCount},
                {label: "Code", value: code}
            ];
        });
    }

    registerWorker(maxLength, price, name) {
        this.contract.registerWorker(maxLength, price, name);
        this._worker = true;
    }

    changeWorkerPrice(newPrice) {
        this.contract.changeWorkerPrice(newPrice);
    }

    buyContract(worker, redundancy, price, length) {
        let options = {
            value: length * price,
            gas: 500000
        };
        this.contract.sendTransaction(options)
            .buyContract(worker, redundancy, length);
    }

    isWorker() {
        let numWorkers = this.contract.numWorkers().toNumber();
        for (let i = 0; i < numWorkers; i++) {
            if (web3.eth.coinbase === this.contract.workerList(i)) {
                return true;
            }
        }
        return false;
    }

    findWorkers(length, price) {
        let numWorkers = this.contract.numWorkers().toNumber();
        let workers = [];
        for (let i = 0; i < numWorkers; i++) {
            let address = this.contract.workerList(i);
            let [wName, wLength, wPrice] = this.contract.workersInfo(address);
            wLength = wLength.toNumber()
            wPrice = wPrice.toNumber();

            if (length <= wLength && price >= wPrice) {
                workers.push({
                    pubkey: address,
                    name: wName,
                    length: wLength,
                    price: wPrice
                });
            }
        }

        return workers
    }

    subscribe(callback) {
        return PubSub.subscribe('chain', callback);
    }

    unsubscribe(token) {
        PubSub.unsubscribe(token);
    }

    getJsonRPCUrl() {
        return this._jsonRpcUrl;
    }

    setJsonRPCUrl(url) {
        if (!url.startsWith('http')) {
            url = 'http://' + url;
        }
        this._jsonRpcUrl = url;
        if (window.localStorage) {
            window.localStorage.setItem('rpc_url', this._jsonRpcUrl);
        }
        if (this.chainFilter) {
            // web3.reset();
            this.chainFilter.stopWatching();
        }
        web3.setProvider(new web3.providers.HttpProvider(this._jsonRpcUrl));
        this.chainFilter = web3.eth.filter('chain');

        PubSub.publish('chain');
        this.chainFilter.watch(() => {
            PubSub.publish('chain');
        });
    }

    sendMsg(to, data) {
        web3.shh.post({
            from: this.identity,
            to: to,
            payload: [ web3.fromAscii(data) ],
        });
    }

    askWorker(workerAddress, contractAddress) {
        web3.shh.post({
            from: this.identity,
            topic: workerAddress,
            payload: [ contractAddress ],
        });
    }
}

let ethclient = new EthClient();

export default ethclient;
<|endoftext|>


<commit_before>/*!
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/* global document, window, $, */

import getMetaValue from './meta_value';

function updateQueryStringParameter(uri, key, value) {
  const re = new RegExp(`([?&])${key}=.*?(&|$)`, 'i');
  const separator = uri.indexOf('?') !== -1 ? '&' : '?';
  if (uri.match(re)) {
    return uri.replace(re, `$1${key}=${value}$2`);
  }

  return `${uri}${separator}${key}=${value}`;
}

// Pills highlighting
$(window).on('load', function onLoad() {
  $(`a[href*="${this.location.pathname}"]`).parent().addClass('active');
  $('.never_active').removeClass('active');
});

const dagId = getMetaValue('dag_id');
export const dagTZ = getMetaValue('dag_timezone');
const logsWithMetadataUrl = getMetaValue('logs_with_metadata_url');
const externalLogUrl = getMetaValue('external_log_url');
const extraLinksUrl = getMetaValue('extra_links_url');
const pausedUrl = getMetaValue('paused_url');
let taskId = '';
let executionDate = '';
let subdagId = '';
const showExternalLogRedirect = getMetaValue('show_external_log_redirect') === 'True';

const buttons = Array.from(document.querySelectorAll('a[id^="btn_"][data-base-url]')).reduce((obj, elm) => {
  obj[elm.id.replace('btn_', '')] = elm;
  return obj;
}, {});

function updateButtonUrl(elm, params) {
  elm.setAttribute('href', `${elm.dataset.baseUrl}?${$.param(params)}`);
}

function updateModalUrls() {
  updateButtonUrl(buttons.subdag, {
    dag_id: subdagId,
    execution_date: executionDate,
  });

  updateButtonUrl(buttons.task, {
    dag_id: dagId,
    task_id: taskId,
    execution_date: executionDate,
  });

  updateButtonUrl(buttons.rendered, {
    dag_id: dagId,
    task_id: taskId,
    execution_date: executionDate,
  });

  if (buttons.rendered_k8s) {
    updateButtonUrl(buttons.rendered_k8s, {
      dag_id: dagId,
      task_id: taskId,
      execution_date: executionDate,
    });
  }

  updateButtonUrl(buttons.ti, {
    flt1_dag_id_equals: dagId,
    _flt_3_task_id: taskId,
    _oc_TaskInstanceModelView: executionDate,
  });

  updateButtonUrl(buttons.log, {
    dag_id: dagId,
    task_id: taskId,
    execution_date: executionDate,
  });
}

// Update modal urls on toggle
document.addEventListener('click', (event) => {
  if (event.target.matches('button[data-toggle="button"]')) {
    updateModalUrls();
  }
});

export function callModal(t, d, extraLinks, tryNumbers, sd) {
  taskId = t;
  const location = String(window.location);
  $('#btn_filter').on('click', () => {
    window.location = updateQueryStringParameter(location, 'root', taskId);
  });
  subdagId = sd;
  executionDate = d;
  $('#task_id').text(t);
  $('#execution_date').text(d);
  $('#taskInstanceModal').modal({});
  $('#taskInstanceModal').css('margin-top', '0');
  $('#extra_links').prev('hr').hide();
  $('#extra_links').empty().hide();
  if (subdagId === undefined) $('#div_btn_subdag').hide();
  else {
    $('#div_btn_subdag').show();
    subdagId = `${dagId}.${t}`;
  }

  $('#dag_dl_logs').hide();
  $('#dag_redir_logs').hide();
  if (tryNumbers > 0) {
    $('#dag_dl_logs').show();
    if (showExternalLogRedirect) {
      $('#dag_redir_logs').show();
    }
  }

  updateModalUrls();

  $('#try_index > li').remove();
  $('#redir_log_try_index > li').remove();
  const startIndex = (tryNumbers > 2 ? 0 : 1);
  for (let index = startIndex; index < tryNumbers; index += 1) {
    let url = `${logsWithMetadataUrl
    }?dag_id=${encodeURIComponent(dagId)
    }&task_id=${encodeURIComponent(taskId)
    }&execution_date=${encodeURIComponent(executionDate)
    }&metadata=null`
      + '&format=file';

    let showLabel = index;
    if (index !== 0) {
      url += `&try_number=${index}`;
    } else {
      showLabel = 'All';
    }

    $('#try_index').append(`

       ${showLabel}

`);

    if (index !== 0 || showExternalLogRedirect) {
      const redirLogUrl = `${externalLogUrl
      }?dag_id=${encodeURIComponent(dagId)
      }&task_id=${encodeURIComponent(taskId)
      }&execution_date=${encodeURIComponent(executionDate)
      }&try_number=${index}`;
      $('#redir_log_try_index').append(`

       ${showLabel}

`);
    }
  }

  if (extraLinks && extraLinks.length > 0) {
    const markupArr = [];
    extraLinks.sort();
    $.each(extraLinks, (i, link) => {
      const url = `${extraLinksUrl
      }?task_id=${encodeURIComponent(taskId)
      }&dag_id=${encodeURIComponent(dagId)
      }&execution_date=${encodeURIComponent(executionDate)
      }&link_name=${encodeURIComponent(link)}`;
      const externalLink = $('');
      const linkTooltip = $('');
      linkTooltip.append(externalLink);
      externalLink.text(link);

      $.ajax(
        {
          url,
          cache: false,
          success(data) {
            externalLink.attr('href', data.url);
            externalLink.removeClass('disabled');
            linkTooltip.tooltip('disable');
          },
          error(data) {
            linkTooltip.tooltip('hide').attr('title', data.responseJSON.error).tooltip('fixTitle');
          },
        },
      );

      markupArr.push(linkTooltip);
    });

    const extraLinksSpan = $('#extra_links');
    extraLinksSpan.prev('hr').show();
    extraLinksSpan.append(markupArr).show();
    extraLinksSpan.find('[data-toggle="tooltip"]').tooltip();
  }
}

export function callModalDag(dag) {
  $('#dagModal').modal({});
  $('#dagModal').css('margin-top', '0');
  updateButtonUrl(buttons.dag_graph_view, {
    dag_id: dag && dag.execution_date,
    execution_date: dag && dag.dag_id,
  });
}

// Task Instance Modal actions
$('form[data-action]').on('submit', function submit(e) {
  e.preventDefault();
  const form = $(this).get(0);
  form.execution_date.value = executionDate;
  form.origin.value = window.location;
  if (form.task_id) {
    form.task_id.value = taskId;
  }
  form.action = $(this).data('action');
  form.submit();
});

// DAG Modal actions
$('form button[data-action]').on('click', function onClick() {
  const form = $(this).closest('form').get(0);
  form.execution_date.value = executionDate;
  form.origin.value = window.location;
  if (form.task_id) {
    form.task_id.value = taskId;
  }
  form.action = $(this).data('action');
  form.submit();
});

$('#pause_resume').on('change', function onChange() {
  const $input = $(this);
  const id = $input.data('dag-id');
  const isPaused = $input.is(':checked');
  const url = `${pausedUrl}?is_paused=${isPaused}&dag_id=${encodeURIComponent(id)}`;
  $input.removeClass('switch-input--error');
  $.post(url).fail(() => {
    setTimeout(() => {
      $input.prop('checked', !isPaused);
      $input.addClass('switch-input--error');
    }, 500);
  });
});
<commit_msg>fix modal actions (#15896)<commit_after>/*!
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/* global document, window, $, */

import getMetaValue from './meta_value';

function updateQueryStringParameter(uri, key, value) {
  const re = new RegExp(`([?&])${key}=.*?(&|$)`, 'i');
  const separator = uri.indexOf('?') !== -1 ? '&' : '?';
  if (uri.match(re)) {
    return uri.replace(re, `$1${key}=${value}$2`);
  }

  return `${uri}${separator}${key}=${value}`;
}

// Pills highlighting
$(window).on('load', function onLoad() {
  $(`a[href*="${this.location.pathname}"]`).parent().addClass('active');
  $('.never_active').removeClass('active');
});

const dagId = getMetaValue('dag_id');
export const dagTZ = getMetaValue('dag_timezone');
const logsWithMetadataUrl = getMetaValue('logs_with_metadata_url');
const externalLogUrl = getMetaValue('external_log_url');
const extraLinksUrl = getMetaValue('extra_links_url');
const pausedUrl = getMetaValue('paused_url');
let taskId = '';
let executionDate = '';
let subdagId = '';
const showExternalLogRedirect = getMetaValue('show_external_log_redirect') === 'True';

const buttons = Array.from(document.querySelectorAll('a[id^="btn_"][data-base-url]')).reduce((obj, elm) => {
  obj[elm.id.replace('btn_', '')] = elm;
  return obj;
}, {});

function updateButtonUrl(elm, params) {
  elm.setAttribute('href', `${elm.dataset.baseUrl}?${$.param(params)}`);
}

function updateModalUrls() {
  updateButtonUrl(buttons.subdag, {
    dag_id: subdagId,
    execution_date: executionDate,
  });

  updateButtonUrl(buttons.task, {
    dag_id: dagId,
    task_id: taskId,
    execution_date: executionDate,
  });

  updateButtonUrl(buttons.rendered, {
    dag_id: dagId,
    task_id: taskId,
    execution_date: executionDate,
  });

  if (buttons.rendered_k8s) {
    updateButtonUrl(buttons.rendered_k8s, {
      dag_id: dagId,
      task_id: taskId,
      execution_date: executionDate,
    });
  }

  updateButtonUrl(buttons.ti, {
    flt1_dag_id_equals: dagId,
    _flt_3_task_id: taskId,
    _oc_TaskInstanceModelView: executionDate,
  });

  updateButtonUrl(buttons.log, {
    dag_id: dagId,
    task_id: taskId,
    execution_date: executionDate,
  });
}

// Update modal urls on toggle
document.addEventListener('click', (event) => {
  if (event.target.matches('button[data-toggle="button"]')) {
    updateModalUrls();
  }
});

export function callModal(t, d, extraLinks, tryNumbers, sd) {
  taskId = t;
  const location = String(window.location);
  $('#btn_filter').on('click', () => {
    window.location = updateQueryStringParameter(location, 'root', taskId);
  });
  subdagId = sd;
  executionDate = d;
  $('#task_id').text(t);
  $('#execution_date').text(d);
  $('#taskInstanceModal').modal({});
  $('#taskInstanceModal').css('margin-top', '0');
  $('#extra_links').prev('hr').hide();
  $('#extra_links').empty().hide();
  if (subdagId === undefined) $('#div_btn_subdag').hide();
  else {
    $('#div_btn_subdag').show();
    subdagId = `${dagId}.${t}`;
  }

  $('#dag_dl_logs').hide();
  $('#dag_redir_logs').hide();
  if (tryNumbers > 0) {
    $('#dag_dl_logs').show();
    if (showExternalLogRedirect) {
      $('#dag_redir_logs').show();
    }
  }

  updateModalUrls();

  $('#try_index > li').remove();
  $('#redir_log_try_index > li').remove();
  const startIndex = (tryNumbers > 2 ? 0 : 1);
  for (let index = startIndex; index < tryNumbers; index += 1) {
    let url = `${logsWithMetadataUrl
    }?dag_id=${encodeURIComponent(dagId)
    }&task_id=${encodeURIComponent(taskId)
    }&execution_date=${encodeURIComponent(executionDate)
    }&metadata=null`
      + '&format=file';

    let showLabel = index;
    if (index !== 0) {
      url += `&try_number=${index}`;
    } else {
      showLabel = 'All';
    }

    $('#try_index').append(`

       ${showLabel}

`);

    if (index !== 0 || showExternalLogRedirect) {
      const redirLogUrl = `${externalLogUrl
      }?dag_id=${encodeURIComponent(dagId)
      }&task_id=${encodeURIComponent(taskId)
      }&execution_date=${encodeURIComponent(executionDate)
      }&try_number=${index}`;
      $('#redir_log_try_index').append(`

       ${showLabel}

`);
    }
  }

  if (extraLinks && extraLinks.length > 0) {
    const markupArr = [];
    extraLinks.sort();
    $.each(extraLinks, (i, link) => {
      const url = `${extraLinksUrl
      }?task_id=${encodeURIComponent(taskId)
      }&dag_id=${encodeURIComponent(dagId)
      }&execution_date=${encodeURIComponent(executionDate)
      }&link_name=${encodeURIComponent(link)}`;
      const externalLink = $('');
      const linkTooltip = $('');
      linkTooltip.append(externalLink);
      externalLink.text(link);

      $.ajax(
        {
          url,
          cache: false,
          success(data) {
            externalLink.attr('href', data.url);
            externalLink.removeClass('disabled');
            linkTooltip.tooltip('disable');
          },
          error(data) {
            linkTooltip.tooltip('hide').attr('title', data.responseJSON.error).tooltip('fixTitle');
          },
        },
      );

      markupArr.push(linkTooltip);
    });

    const extraLinksSpan = $('#extra_links');
    extraLinksSpan.prev('hr').show();
    extraLinksSpan.append(markupArr).show();
    extraLinksSpan.find('[data-toggle="tooltip"]').tooltip();
  }
}

export function callModalDag(dag) {
  $('#dagModal').modal({});
  $('#dagModal').css('margin-top', '0');
  executionDate = dag.execution_date;
  updateButtonUrl(buttons.dag_graph_view, {
    dag_id: dag && dag.dag_id,
    execution_date: dag && dag.execution_date,
  });
}

// Task Instance Modal actions
$('form[data-action]').on('submit', function submit(e) {
  e.preventDefault();
  const form = $(this).get(0);
  // Somehow submit is fired twice. Only once is the executionDate valid
  if (executionDate) {
    form.execution_date.value = executionDate;
    form.origin.value = window.location;
    if (form.task_id) {
      form.task_id.value = taskId;
    }
    form.action = $(this).data('action');
    form.submit();
  }
});

// DAG Modal actions
$('form button[data-action]').on('click', function onClick() {
  const form = $(this).closest('form').get(0);
  // Somehow submit is fired twice. Only once is the executionDate valid
  if (executionDate) {
    form.execution_date.value = executionDate;
    form.origin.value = window.location;
    if (form.task_id) {
      form.task_id.value = taskId;
    }
    form.action = $(this).data('action');
    form.submit();
  }
});

$('#pause_resume').on('change', function onChange() {
  const $input = $(this);
  const id = $input.data('dag-id');
  const isPaused = $input.is(':checked');
  const url = `${pausedUrl}?is_paused=${isPaused}&dag_id=${encodeURIComponent(id)}`;
  $input.removeClass('switch-input--error');
  $.post(url).fail(() => {
    setTimeout(() => {
      $input.prop('checked', !isPaused);
      $input.addClass('switch-input--error');
    }, 500);
  });
});
<|endoftext|>


<commit_before>var inside = require('turf-inside');

/**
 * Calculates the median value of a field for a set of points within a set of polygons.
 *
 * @module turf/median
 * @category aggregation
 * @param {FeatureCollection<Polygon>} polygons input polygons
 * @param {FeatureCollection<Point>} points input points
 * @param {String} inField the field in input data to analyze
 * @param {String} outField the field in which to store results
 * @return {FeatureCollection<Polygon>} polygons with properties listed as `outField` values
 * @example
 * var polygons = {
 *   "type": "FeatureCollection",
 *   "features": [
 *     {
 *       "type": "Feature",
 *       "properties": {},
 *       "geometry": {
 *         "type": "Polygon",
 *         "coordinates": [[
 *           [18.400039, -33.970697],
 *           [18.400039, -33.818518],
 *           [18.665771, -33.818518],
 *           [18.665771, -33.970697],
 *           [18.400039, -33.970697]
 *         ]]
 *       }
 *     }, {
 *       "type": "Feature",
 *       "properties": {},
 *       "geometry": {
 *         "type": "Polygon",
 *         "coordinates": [[
 *           [18.538742, -34.050383],
 *           [18.538742, -33.98721],
 *           [18.703536, -33.98721],
 *           [18.703536, -34.050383],
 *           [18.538742, -34.050383]
 *         ]]
 *       }
 *     }
 *   ]
 * };
 * var points = {
 *   "type": "FeatureCollection",
 *   "features": [
 *     {
 *       "type": "Feature",
 *       "properties": {
 *         "population": 200
 *       },
 *       "geometry": {
 *         "type": "Point",
 *         "coordinates": [18.514022, -33.860152]
 *       }
 *     }, {
 *       "type": "Feature",
 *       "properties": {
 *         "population": 600
 *       },
 *       "geometry": {
 *         "type": "Point",
 *         "coordinates": [18.48999, -33.926269]
 *       }
 *     }, {
 *       "type": "Feature",
 *       "properties": {
 *         "population": 100
 *       },
 *       "geometry": {
 *         "type": "Point",
 *         "coordinates": [18.583374, -33.905755]
 *       }
 *     }, {
 *       "type": "Feature",
 *       "properties": {
 *         "population": 200
 *       },
 *       "geometry": {
 *         "type": "Point",
 *         "coordinates": [18.591613, -34.024778]
 *       }
 *     }, {
 *       "type": "Feature",
 *       "properties": {
 *         "population": 300
 *       },
 *       "geometry": {
 *         "type": "Point",
 *         "coordinates": [18.653411, -34.017949]
 *       }
 *     }
 *   ]
 * };
 *
 * var medians = turf.median(
 *  polygons, points, 'population', 'median');
 *
 * var resultFeatures = points.features.concat(
 *   medians.features);
 * var result = {
 *   "type": "FeatureCollection",
 *   "features": resultFeatures
 * };
 *
 * //=result
 */
module.exports = function(polyFC, ptFC, inField, outField){
  polyFC.features.forEach(function(poly){
    if(!poly.properties){
      poly.properties = {};
    }
    var values = [];
    ptFC.features.forEach(function(pt){
      if (inside(pt, poly)) {
        values.push(pt.properties[inField]);
      }
    });
    poly.properties[outField] = median(values);
  });

  return polyFC;
};

function median(x) {
    // The median of an empty list is null
    if (x.length === 0) return null;

    // Sorting the array makes it easy to find the center, but
    // use `.slice()` to ensure the original array `x` is not modified
    var sorted = x.slice().sort(function (a, b) { return a - b; });

    // If the length of the list is odd, it's the central number
    if (sorted.length % 2 === 1) {
        return sorted[(sorted.length - 1) / 2];
    // Otherwise, the median is the average of the two numbers
    // at the center of the list
    } else {
        var a = sorted[(sorted.length / 2) - 1];
        var b = sorted[(sorted.length / 2)];
        return (a + b) / 2;
    }
}
<commit_msg>tighten description language<commit_after>var inside = require('turf-inside');

/**
 * Calculates the median value of a field for a set of {@link Point|points} within a set of {@link Polygon|polygons}.
 *
 * @module turf/median
 * @category aggregation
 * @param {FeatureCollection<Polygon>} polygons input polygons
 * @param {FeatureCollection<Point>} points input points
 * @param {String} inField the field in input data to analyze
 * @param {String} outField the field in which to store results
 * @return {FeatureCollection<Polygon>} polygons with properties listed as `outField` values
 * @example
 * var polygons = {
 *   "type": "FeatureCollection",
 *   "features": [
 *     {
 *       "type": "Feature",
 *       "properties": {},
 *       "geometry": {
 *         "type": "Polygon",
 *         "coordinates": [[
 *           [18.400039, -33.970697],
 *           [18.400039, -33.818518],
 *           [18.665771, -33.818518],
 *           [18.665771, -33.970697],
 *           [18.400039, -33.970697]
 *         ]]
 *       }
 *     }, {
 *       "type": "Feature",
 *       "properties": {},
 *       "geometry": {
 *         "type": "Polygon",
 *         "coordinates": [[
 *           [18.538742, -34.050383],
 *           [18.538742, -33.98721],
 *           [18.703536, -33.98721],
 *           [18.703536, -34.050383],
 *           [18.538742, -34.050383]
 *         ]]
 *       }
 *     }
 *   ]
 * };
 * var points = {
 *   "type": "FeatureCollection",
 *   "features": [
 *     {
 *       "type": "Feature",
 *       "properties": {
 *         "population": 200
 *       },
 *       "geometry": {
 *         "type": "Point",
 *         "coordinates": [18.514022, -33.860152]
 *       }
 *     }, {
 *       "type": "Feature",
 *       "properties": {
 *         "population": 600
 *       },
 *       "geometry": {
 *         "type": "Point",
 *         "coordinates": [18.48999, -33.926269]
 *       }
 *     }, {
 *       "type": "Feature",
 *       "properties": {
 *         "population": 100
 *       },
 *       "geometry": {
 *         "type": "Point",
 *         "coordinates": [18.583374, -33.905755]
 *       }
 *     }, {
 *       "type": "Feature",
 *       "properties": {
 *         "population": 200
 *       },
 *       "geometry": {
 *         "type": "Point",
 *         "coordinates": [18.591613, -34.024778]
 *       }
 *     }, {
 *       "type": "Feature",
 *       "properties": {
 *         "population": 300
 *       },
 *       "geometry": {
 *         "type": "Point",
 *         "coordinates": [18.653411, -34.017949]
 *       }
 *     }
 *   ]
 * };
 *
 * var medians = turf.median(
 *  polygons, points, 'population', 'median');
 *
 * var resultFeatures = points.features.concat(
 *   medians.features);
 * var result = {
 *   "type": "FeatureCollection",
 *   "features": resultFeatures
 * };
 *
 * //=result
 */
module.exports = function(polyFC, ptFC, inField, outField){
  polyFC.features.forEach(function(poly){
    if(!poly.properties){
      poly.properties = {};
    }
    var values = [];
    ptFC.features.forEach(function(pt){
      if (inside(pt, poly)) {
        values.push(pt.properties[inField]);
      }
    });
    poly.properties[outField] = median(values);
  });

  return polyFC;
};

function median(x) {
    // The median of an empty list is null
    if (x.length === 0) return null;

    // Sorting the array makes it easy to find the center, but
    // use `.slice()` to ensure the original array `x` is not modified
    var sorted = x.slice().sort(function (a, b) { return a - b; });

    // If the length of the list is odd, it's the central number
    if (sorted.length % 2 === 1) {
        return sorted[(sorted.length - 1) / 2];
    // Otherwise, the median is the average of the two numbers
    // at the center of the list
    } else {
        var a = sorted[(sorted.length / 2) - 1];
        var b = sorted[(sorted.length / 2)];
        return (a + b) / 2;
    }
}
<|endoftext|>


<commit_before><commit_msg>chore: Import Sass styles in top-level React component<commit_after><|endoftext|>


<commit_before>angular.module('pascalprecht.translate')
/**
 * @ngdoc filter
 * @name pascalprecht.translate.filter:translate
 * @requires $parse
 * @requires pascalprecht.translate.$translate
 * @function
 *
 * @description
 * Uses `$translate` service to translate contents. Accepts interpolate parameters
 * to pass dynamized values though translation.
 *
 * @param {string} translationId A translation id to be translated.
 * @param {*=} interpolateParams Optional object literal (as hash or string) to pass values into translation.
 *
 * @returns {string} Translated text.
 *
 * @example
   <example module="ngView">
    <file name="index.html">

{{ 'TRANSLATION_ID' | translate }}

{{ translationId | translate }}

{{ 'WITH_VALUES' | translate:'{value: 5}' }}

{{ 'WITH_VALUES' | translate:values }}

    </file>
    <file name="script.js">
      angular.module('ngView', ['pascalprecht.translate'])

      .config(function ($translateProvider) {

        $translateProvider.translations('en', {
          'TRANSLATION_ID': 'Hello there!',
          'WITH_VALUES': 'The following value is dynamic: {{value}}'
        });
        $translateProvider.preferredLanguage('en');

      });

      angular.module('ngView').controller('TranslateCtrl', function ($scope) {
        $scope.translationId = 'TRANSLATION_ID';

        $scope.values = {
          value: 78
        };
      });
    </file>
   </example>
 */
.filter('translate', translateFilterFactory);

function translateFilterFactory($parse, $translate) {

  'use strict';

  var translateFilter = function (translationId, interpolateParams, interpolation, forceLanguage) {
    if (!angular.isObject(interpolateParams)) {
      interpolateParams = $parse(interpolateParams)(this);
    }

    return $translate.instant(translationId, interpolateParams, interpolation, forceLanguage);
  };

  if ($translate.statefulFilter()) {
    translateFilter.$stateful = true;
  }

  return translateFilter;
}

translateFilterFactory.displayName = 'translateFilterFactory';
<commit_msg>feat(filter): ensure no this==undefined will be injected<commit_after>angular.module('pascalprecht.translate')
/**
 * @ngdoc filter
 * @name pascalprecht.translate.filter:translate
 * @requires $parse
 * @requires pascalprecht.translate.$translate
 * @function
 *
 * @description
 * Uses `$translate` service to translate contents. Accepts interpolate parameters
 * to pass dynamized values though translation.
 *
 * @param {string} translationId A translation id to be translated.
 * @param {*=} interpolateParams Optional object literal (as hash or string) to pass values into translation.
 *
 * @returns {string} Translated text.
 *
 * @example
   <example module="ngView">
    <file name="index.html">

{{ 'TRANSLATION_ID' | translate }}

{{ translationId | translate }}

{{ 'WITH_VALUES' | translate:'{value: 5}' }}

{{ 'WITH_VALUES' | translate:values }}

    </file>
    <file name="script.js">
      angular.module('ngView', ['pascalprecht.translate'])

      .config(function ($translateProvider) {

        $translateProvider.translations('en', {
          'TRANSLATION_ID': 'Hello there!',
          'WITH_VALUES': 'The following value is dynamic: {{value}}'
        });
        $translateProvider.preferredLanguage('en');

      });

      angular.module('ngView').controller('TranslateCtrl', function ($scope) {
        $scope.translationId = 'TRANSLATION_ID';

        $scope.values = {
          value: 78
        };
      });
    </file>
   </example>
 */
.filter('translate', translateFilterFactory);

function translateFilterFactory($parse, $translate) {

  'use strict';

  var translateFilter = function (translationId, interpolateParams, interpolation, forceLanguage) {
    if (!angular.isObject(interpolateParams)) {
      var ctx = this || {
        '__SCOPE_IS_NOT_AVAILABLE': 'More info at https://github.com/angular/angular.js/commit/8863b9d04c722b278fa93c5d66ad1e578ad6eb1f'
        };
      interpolateParams = $parse(interpolateParams)(ctx);
    }

    return $translate.instant(translationId, interpolateParams, interpolation, forceLanguage);
  };

  if ($translate.statefulFilter()) {
    translateFilter.$stateful = true;
  }

  return translateFilter;
}

translateFilterFactory.displayName = 'translateFilterFactory';
<|endoftext|>