text:
/* jshint maxlen: false */

'use strict';

var createAPIRequest = require('../../lib/apirequest');

/**
 * Content API for Shopping
 *
 * @classdesc Manages product items, inventory, and Merchant Center accounts for Google Shopping.
 * @namespace content
 * @version  v2sandbox
 * @variation v2sandbox
 * @this Content
 * @param {object=} options Options for Content
 */
function Content(options) {

  var self = this;
  this._options = options || {};

  this.orders = {

    /**
     * content.orders.acknowledge
     *
     * @desc Marks an order as acknowledged.
     *
     * @alias content.orders.acknowledge
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {string} params.orderId - The ID of the order.
     * @param  {object} params.resource - Request body data
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    acknowledge: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/orders/{orderId}/acknowledge',
          method: 'POST'
        },
        params: params,
        requiredParams: ['merchantId', 'orderId'],
        pathParams: ['merchantId', 'orderId'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.advancetestorder
     *
     * @desc Sandbox only. Moves a test order from state "inProgress" to state "pendingShipment".
     *
     * @alias content.orders.advancetestorder
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {string} params.orderId - The ID of the test order to modify.
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    advancetestorder: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/testorders/{orderId}/advance',
          method: 'POST'
        },
        params: params,
        requiredParams: ['merchantId', 'orderId'],
        pathParams: ['merchantId', 'orderId'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.cancel
     *
     * @desc Cancels all line items in an order.
     *
     * @alias content.orders.cancel
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {string} params.orderId - The ID of the order to cancel.
     * @param  {object} params.resource - Request body data
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    cancel: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/orders/{orderId}/cancel',
          method: 'POST'
        },
        params: params,
        requiredParams: ['merchantId', 'orderId'],
        pathParams: ['merchantId', 'orderId'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.cancellineitem
     *
     * @desc Cancels a line item.
     *
     * @alias content.orders.cancellineitem
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {string} params.orderId - The ID of the order.
     * @param  {object} params.resource - Request body data
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    cancellineitem: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/orders/{orderId}/cancelLineItem',
          method: 'POST'
        },
        params: params,
        requiredParams: ['merchantId', 'orderId'],
        pathParams: ['merchantId', 'orderId'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.createtestorder
     *
     * @desc Sandbox only. Creates a test order.
     *
     * @alias content.orders.createtestorder
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {object} params.resource - Request body data
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    createtestorder: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/testorders',
          method: 'POST'
        },
        params: params,
        requiredParams: ['merchantId'],
        pathParams: ['merchantId'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.custombatch
     *
     * @desc Retrieves or modifies multiple orders in a single request.
     *
     * @alias content.orders.custombatch
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {object} params.resource - Request body data
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    custombatch: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/orders/batch',
          method: 'POST'
        },
        params: params,
        requiredParams: [],
        pathParams: [],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.get
     *
     * @desc Retrieves an order from your Merchant Center account.
     *
     * @alias content.orders.get
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {string} params.orderId - The ID of the order.
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    get: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/orders/{orderId}',
          method: 'GET'
        },
        params: params,
        requiredParams: ['merchantId', 'orderId'],
        pathParams: ['merchantId', 'orderId'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.getbymerchantorderid
     *
     * @desc Retrieves an order using merchant order id.
     *
     * @alias content.orders.getbymerchantorderid
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {string} params.merchantOrderId - The merchant order id to be looked for.
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    getbymerchantorderid: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/ordersbymerchantid/{merchantOrderId}',
          method: 'GET'
        },
        params: params,
        requiredParams: ['merchantId', 'merchantOrderId'],
        pathParams: ['merchantId', 'merchantOrderId'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.gettestordertemplate
     *
     * @desc Sandbox only. Retrieves an order template that can be used to quickly create a new order in sandbox.
     *
     * @alias content.orders.gettestordertemplate
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {string} params.templateName - The name of the template to retrieve.
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    gettestordertemplate: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/testordertemplates/{templateName}',
          method: 'GET'
        },
        params: params,
        requiredParams: ['merchantId', 'templateName'],
        pathParams: ['merchantId', 'templateName'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.list
     *
     * @desc Lists the orders in your Merchant Center account.
     *
     * @alias content.orders.list
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {boolean=} params.acknowledged - Obtains orders that match the acknowledgement status. When set to true, obtains orders that have been acknowledged. When false, obtains orders that have not been acknowledged. We recommend using this filter set to false, in conjunction with the acknowledge call, such that only un-acknowledged orders are returned.
     * @param  {integer=} params.maxResults - The maximum number of orders to return in the response, used for paging. The default value is 25 orders per page, and the maximum allowed value is 250 orders per page. Known issue: All List calls will return all Orders without limit regardless of the value of this field.
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {string=} params.orderBy - The ordering of the returned list. The only supported value are placedDate desc and placedDate asc for now, which returns orders sorted by placement date. "placedDate desc" stands for listing orders by placement date, from oldest to most recent. "placedDate asc" stands for listing orders by placement date, from most recent to oldest. In future releases we'll support other sorting criteria.
     * @param  {string=} params.pageToken - The token returned by the previous request.
     * @param  {string=} params.placedDateEnd - Obtains orders placed before this date (exclusively), in ISO 8601 format.
     * @param  {string=} params.placedDateStart - Obtains orders placed after this date (inclusively), in ISO 8601 format.
     * @param  {string=} params.statuses - Obtains orders that match any of the specified statuses. Multiple values can be specified with comma separation. Additionally, please note that active is a shortcut for pendingShipment and partiallyShipped, and completed is a shortcut for shipped , partiallyDelivered, delivered, partiallyReturned, returned, and canceled.
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    list: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/orders',
          method: 'GET'
        },
        params: params,
        requiredParams: ['merchantId'],
        pathParams: ['merchantId'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.refund
     *
     * @desc Refund a portion of the order, up to the full amount paid.
     *
     * @alias content.orders.refund
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {string} params.orderId - The ID of the order to refund.
     * @param  {object} params.resource - Request body data
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    refund: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/orders/{orderId}/refund',
          method: 'POST'
        },
        params: params,
        requiredParams: ['merchantId', 'orderId'],
        pathParams: ['merchantId', 'orderId'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.returnlineitem
     *
     * @desc Returns a line item.
     *
     * @alias content.orders.returnlineitem
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {string} params.orderId - The ID of the order.
     * @param  {object} params.resource - Request body data
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    returnlineitem: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/orders/{orderId}/returnLineItem',
          method: 'POST'
        },
        params: params,
        requiredParams: ['merchantId', 'orderId'],
        pathParams: ['merchantId', 'orderId'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.shiplineitems
     *
     * @desc Marks line item(s) as shipped.
     *
     * @alias content.orders.shiplineitems
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {string} params.orderId - The ID of the order.
     * @param  {object} params.resource - Request body data
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    shiplineitems: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/orders/{orderId}/shipLineItems',
          method: 'POST'
        },
        params: params,
        requiredParams: ['merchantId', 'orderId'],
        pathParams: ['merchantId', 'orderId'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.updatemerchantorderid
     *
     * @desc Updates the merchant order ID for a given order.
     *
     * @alias content.orders.updatemerchantorderid
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {string} params.orderId - The ID of the order.
     * @param  {object} params.resource - Request body data
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    updatemerchantorderid: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/orders/{orderId}/updateMerchantOrderId',
          method: 'POST'
        },
        params: params,
        requiredParams: ['merchantId', 'orderId'],
        pathParams: ['merchantId', 'orderId'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    },

    /**
     * content.orders.updateshipment
     *
     * @desc Updates a shipment's status, carrier, and/or tracking ID.
     *
     * @alias content.orders.updateshipment
     * @memberOf! content(v2sandbox)
     *
     * @param  {object} params - Parameters for request
     * @param  {string} params.merchantId - The ID of the managing account.
     * @param  {string} params.orderId - The ID of the order.
     * @param  {object} params.resource - Request body data
     * @param  {callback} callback - The callback that handles the response.
     * @return {object} Request object
     */
    updateshipment: function(params, callback) {
      var parameters = {
        options: {
          url: 'https://www.googleapis.com/content/v2sandbox/{merchantId}/orders/{orderId}/updateShipment',
          method: 'POST'
        },
        params: params,
        requiredParams: ['merchantId', 'orderId'],
        pathParams: ['merchantId', 'orderId'],
        context: self
      };

      return createAPIRequest(parameters, callback);
    }

  };
}

/**
 * Exports Content object
 * @type Content
 */
module.exports = Content;


text:
'use strict';

Object.defineProperty(exports, '__esModule', {
  value: true
});

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _filter = require('./filter');

var _filter2 = _interopRequireDefault(_filter);

var _GeneralId = require('../General/id');

var _GeneralId2 = _interopRequireDefault(_GeneralId);

exports['default'] = (0, _filter2['default'])(_GeneralId2['default']);
module.exports = exports['default'];

redpajama_set_name: RedPajamaGithub


text:
package org.openmuc.framework.core.authentication;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.openmuc.framework.authentication.AuthenticationService;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ServiceScope;
import org.osgi.service.useradmin.Authorization;
import org.osgi.service.useradmin.Group;
import org.osgi.service.useradmin.Role;
import org.osgi.service.useradmin.User;
import org.osgi.service.useradmin.UserAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(service = AuthenticationService.class, scope = ServiceScope.SINGLETON)
public class Authentication implements AuthenticationService {
    private static final String DEFAULT_SHADOW_FILE_LOCATION = "conf/shadow";

    private static final Logger logger = LoggerFactory.getLogger(Authentication.class);
    private final Map<String, String> shadow = new HashMap<>();
    private String path;
    private UserAdmin userAdmin;
    private boolean userAdminInitiated;

    private static String initPath() {
        String path = System.getProperty("bundles.configuration.location");
        if (path == null) {
            return DEFAULT_SHADOW_FILE_LOCATION;
        }

        if (path.endsWith("/")) {
            path = path.substring(0, path.length() - 1);
        }

        return path + "/shadow";
    }

    private static String generateHash(String pw) {
        try {
            MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
            byte[] hashedBytes = sha256.digest(pw.getBytes());
            return bytesToHexString(hashedBytes);
        } catch (NoSuchAlgorithmException e) {
            // should not occur.
            logger.error("Failed to generate hash.", e);
            return "";
        }

    }

    private static String bytesToHexString(byte[] hashedBytes) {
        StringBuilder hash = new StringBuilder();
        for (byte hashedByte : hashedBytes) {
            hash.append(String.format("%02x", hashedByte));
        }
        return hash.toString();
    }

    @Activate
    public void activate() {
        this.path = initPath();
        userAdminInitiated = false;
    }

    @Override
    public void register(String user, String pw, String group) {
        logger.info("register");
        pw += generateHash(user); // use the hash of the username as salt

        String hash = generateHash(pw);

        setUserHashPair(user, hash, group);
    }

    @Override
    public void registerNewUser(String user, String pw) {
        pw += generateHash(user); // use the hash of the username as salt

        String hash = generateHash(pw);

        setUserHashPair(user, hash, "normal");
        writeShadowToFile();
    }

    @Override
    public boolean login(String userName, String pw) {
        initUserAdminIfNotDone();
        // use the hash of the username as salt
        String pwToCheck = pw + generateHash(userName);

        String hash = generateHash(pwToCheck);

        User user = userAdmin.getUser("name", userName);

        return user.getProperties().get("password").equals(hash);
    }

    @Override
    public void delete(String user) {
        userAdmin.removeRole(user);

        writeShadowToFile();
    }

    @Override
    public boolean contains(String user) {
        return getAllUsers().contains(user);
    }

    @Override
    public Set<String> getAllUsers() {
        Set<String> registeredUsers = new HashSet<>();
        Role[] allRoles = getAllRoleObjects();

        for (Role role : Arrays.asList(allRoles)) {
            User user = (User) role;
            String userName = (String) user.getProperties().get("name");
            if (userName != null) {
                registeredUsers.add(userName);
            }
        }

        return registeredUsers;
    }

    private void setUserHashPair(String user, String hash, String group) {
        User newUser = (User) userAdmin.createRole(user, Role.USER);
        Group grp = (Group) userAdmin.createRole(group, Role.GROUP);

        if (grp == null) {
            grp = (Group) userAdmin.getRole(group);
        }

        if (newUser == null) {
            newUser = (User) userAdmin.getRole(user);
        }

        @SuppressWarnings("unchecked")
        Dictionary<String, String> properties = newUser.getProperties();
        properties.put("name", user);
        properties.put("password", hash);
        properties.put("group", group);

        grp.addMember(newUser);
    }

    @Override
    public void writeShadowToFile() {
        Role[] allRoles = getAllRoleObjects();
        StringBuilder textSb = prepareStringBuilder(allRoles);

        try (Writer output = new BufferedWriter(new FileWriter(new File(path)));) {
            output.write(textSb.toString());
            output.flush();
        } catch (IOException e) {
            logger.warn("Failed to write shadow.", e);
        }

    }

    private Role[] getAllRoleObjects() {
        Role[] allUser = null;
        try {
            allUser = userAdmin.getRoles(null);
        } catch (InvalidSyntaxException e) {
            logger.error(e.getMessage());
        }

        return allUser;
    }

    private StringBuilder prepareStringBuilder(Role[] allUser) {
        StringBuilder textSb = new StringBuilder();

        for (Role role : Arrays.asList(allUser)) {
            User user = (User) role;
            if (user.getProperties().get("name") != null) {
                textSb.append(user.getProperties().get("name") + ";");
                textSb.append(user.getProperties().get("password") + ";");
                textSb.append(user.getProperties().get("group") + ";\n");
            }
        }

        return textSb;
    }

    private void loadShadowFromFile() {
        try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] temp = line.split(";");
                setUserHashPair(temp[0], temp[1], temp[2]);
            }
        } catch (IOException e) {
            logger.warn("Failed to load shadow.", e);
        }
    }

    @Override
    public boolean isUserAdmin(String userName) {
        User user = userAdmin.getUser("name", userName);
        Authorization loggedUser = userAdmin.getAuthorization(user);

        return loggedUser.hasRole("admin");

    }

    @Reference
    protected void setUserAdmin(UserAdmin userAdmin) {
        this.userAdmin = userAdmin;
    }

    protected void unsetUserAdmin(UserAdmin userAdmin) {

    }

    private void initUserAdminIfNotDone() {
        if (userAdminInitiated) {
            return;
        }

        File file = new File(this.path);
        if (!file.exists()) {
            register("admin", "admin", "adminGrp");
            writeShadowToFile();
        }
        else {
            loadShadowFromFile();
        }
        userAdminInitiated = true;
    }
}


text:
import csv
import copy
import math
import json

import webbrowser
import os

from bokeh.plotting import figure, output_file, show, reset_output, ColumnDataSource
from bokeh.models import HoverTool, Range1d, LinearAxis, LinearColorMapper, ColorBar, BasicTicker, PrintfTickFormatter, CustomJS, TapTool, Slider, widgets
from bokeh.layouts import row, widgetbox
from bokeh import events
import bokeh

import numpy.polynomial.polynomial as poly
import numpy

from . import parseV3
from . import parseV4
from . import util
from . import filters
from . import chartBuilder

dynoStartTime = 9.25
dynoEndTime = 12.8
dynoEndTime = 12.85
dynoPreLoad = 0

MIN_SAMPLE_TIME = 100 #minimum time between sample readings in micros

class smoother():
	medTaps = 6
	avgTaps = 6

	def __init__(self, medTaps=6, avgTaps=6, preAvgTaps=1):
		self.medAcc = []
		self.avgAcc = []
		self.preAvgAcc = []
		self.medTaps = medTaps
		self.avgTaps = avgTaps
		self.preAvgTaps = preAvgTaps

	def add(self, value):
			self.preAvgAcc.append(value)
			self.preAvgAcc = self.preAvgAcc[-self.preAvgTaps:]
			preAvgVal = numpy.mean(self.preAvgAcc)

			self.medAcc.append(preAvgVal)
			self.medAcc = self.medAcc[-self.medTaps:]

			medVal = numpy.median(self.medAcc)
			self.avgAcc.append( medVal  )
			self.avgAcc = self.avgAcc[-self.avgTaps:]

	def get(self):
		#if len(self.avgAcc) < self.avgTaps:
		#	print self.avgAcc

		return(numpy.mean(self.avgAcc))

class KalmanFilter(object):

    def __init__(self, process_variance, estimated_measurement_variance):
        self.process_variance = process_variance
        self.estimated_measurement_variance = estimated_measurement_variance
        self.posteri_estimate = 0.0
        self.posteri_error_estimate = 1.0

    def add(self, measurement):
        priori_estimate = self.posteri_estimate
        priori_error_estimate = self.posteri_error_estimate + self.process_variance

        blending_factor = priori_error_estimate / (priori_error_estimate + self.estimated_measurement_variance)
        self.posteri_estimate = priori_estimate + blending_factor * (measurement - priori_estimate)
        self.posteri_error_estimate = (1 - blending_factor) * priori_error_estimate

    def get(self):
        return self.posteri_estimate

class bladeBenchLog():
	filePath = None
	headerValues = {}

	def __init__(self, filePath ):
		self.filePath = filePath
		self.readHeader()

	def readHeader(self):
		with open(self.filePath, 'rb') as f:

			for line in iter(f.readline, ''):
				if 'adcMaxValue:' in line:
					self.headerValues['adcMax'] = float(line.split(':')[-1])
				if 'vref:' in line:
					self.headerValues['vref'] = float(line.split(':')[-1])
				if 'thermBValue:' in line:
					self.headerValues['thermBValue'] = float(line.split(':')[-1])
				if 'pulse per rev:' in line:
					self.headerValues['pulse per rev'] = int(line.split(':')[-1])
				if 'loadcell calibration value:' in line:
					self.headerValues['loadcell calibration value'] = float(line.split(':')[-1])

				if 'vrange:' in line:
					if '6s' in line.split(':')[-1]:
						self.headerValues['vrange']='6s'
					else:
						self.headerValues['vrange']='3s'

				if 'vCalibrate:' in line:
					self.headerValues['vCalibrate'] = float(line.split(':')[-1])
				if 'vOffset:' in line:
					self.headerValues['vOffset'] = float(line.split(':')[-1])
				if 'aCalibrate:' in line:
					self.headerValues['aCalibrate'] = float(line.split(':')[-1])
				if 'aOffset:' in line:
					self.headerValues['aOffset'] = float(line.split(':')[-1])

				if 'motorPully:' in line:
					self.headerValues['motorPully'] = float(line.split(':')[-1])
				if 'drivePully:' in line:
					self.headerValues['drivePully'] = float(line.split(':')[-1])

				if 'loaded program:' in line:
					self.headerValues['loaded program'] = line.split(':')[-1].strip()

				if line == 'Data Start:\n':
					self.headerValues['data start'] = f.tell()
					break

	def getProgramName(self):
		if 'loaded program' in self.headerValues.keys():
			return self.headerValues['loaded program']

def readLog(file):
	print 'parsing log', file
	with open(file, 'rb') as csvfile:
		thisLine = ''
		while 'Time,' not in thisLine:
			lastRead = csvfile.tell()
			thisLine = csvfile.readline()
		csvfile.seek(lastRead)

		floatKeys = ['RPM', 'Volt', 'Amp', 'Thrust']
		intKeys = ['Motor Command', 'Time']
		csv = csv.DictReader(csvfile, delimiter=',', quotechar='|')

		allSamples = []
		index = {}
		try:
			for row in csv:
				thisSample = {}

				if not index.keys():
					for key in row.keys():
						index[key]=[]

				for key in row.keys():
					thisSample[key]=None

				for key in floatKeys:
					if row[key] != '':
						thisSample[key]=float(row[key])
						index[key].append(len(allSamples))
				for key in intKeys:
					if row[key] != '':
						thisSample[key]=int(row[key])
						index[key].append(len(allSamples))
				allSamples.append(thisSample)
		except:
			pass

	#interpolate
	for key in index:
		seq = index[key]
		for a, b in zip(seq, seq[1:]):
			length = b-a
			if length<2: continue
			start = allSamples[a][key]
			end = allSamples[b][key]
			delta = end-start
			for i in range(1,length):
				allSamples[a+i][key] =start + delta*(float(i)/length)

	return allSamples, index

def readBinaryLog(file, shortLoad=None):

	fileVersion = None
	allSamples = None
	index = None
	with open(file, 'rb') as f:
		for line in iter(f.readline, ''):
			if 'log version:' in line:
				fileVersion = int(line.split(':')[-1])

	if fileVersion == 3:
		allSamples, index = parseV3.readBinaryLog(file, shortLoad)
	elif fileVersion == 4:
		allSamples, index = parseV4.readBinaryLog(file, shortLoad)
	else:
		print 'unknown file version'

	return allSamples, index

def getInterpolated(indexList, valueList):
	for a, b in zip(indexList, indexList[1:]):
		length = b-a
		if length<2: continue
		start = valueList[a]
		end = valueList[b]
		delta = end-start
		for i in range(1,length):
			valueList[a+i] =start + delta*(float(i)/length)
	return valueList

def getStats(allSample, index):
	x = []
	y = []
	startRange = 5.25 * 1000000
	endRange = 6.75 *1000000

	foundStart = 0
	foundEnd = 0

	smoothV = smoother(avgTaps=6, medTaps=1)
	smoothA = smoother(avgTaps=6, medTaps=1)
	smoothT = smoother(avgTaps=1, medTaps=3)

	for sampleIndex in index['Time']:
		time = allSample[sampleIndex]['Time']
		if not foundStart and time>startRange:
			foundStart = sampleIndex
		if not foundEnd and time>endRange:
			foundEnd = sampleIndex
		if foundStart and foundEnd:
			break

	v=[]
	a=[]
	t=[]
	w=[]
	e=[]
	r=[]

	for sample in allSample[foundStart:foundEnd]:
		v.append(round(sample['Volt'],2))
		a.append(round(sample['Amp'],2))
		watts = sample['Volt']*sample['Amp']
		w.append( round(watts, 2) )
		if sample['Thrust']:
			smoothT.add ( sample['Thrust'] )

			t.append(round(smoothT.get(),2))
			e.append(round(smoothT.get()/watts,2))
		if sample['RPM']:
			r.append(int(sample['RPM']))

	v = getMiddleResults(v)
	a = getMiddleResults(a)
	t = getMiddleResults(t)
	w = getMiddleResults(w)
	e = getMiddleResults(e)
	r = getMiddleResults(r)

	print 'stats min max med mean'
	if r: print 'RPM', min(r), max(r), int(numpy.median(numpy.array( r ))), int(numpy.mean(numpy.array( r )))
	if t: print 'thrust', min(t), max(t), numpy.median(numpy.array( t )), round(numpy.mean(numpy.array( t )), 2)
	print 'volts', min(v), max(v), numpy.median(numpy.array( v )), round( numpy.mean(numpy.array( v )), 2 )
	print 'Amps', min(a), max(a), numpy.median(numpy.array( a )),round(numpy.mean(numpy.array( a )), 2)
	print 'watts', min(w), max(w), numpy.median(numpy.array( w )),round(numpy.mean(numpy.array( w )), 2)
	if e: print 'efficiency', min(e), max(e), numpy.median(numpy.array( e )), round(numpy.mean(numpy.array( e )), 2)

	return

def getCalibrationStats(allSample, index):

	smoothV = smoother(avgTaps=6, medTaps=1)
	smoothA = smoother(avgTaps=6, medTaps=1)
	smoothT = smoother(avgTaps=1, medTaps=3)

	v=[]
	a=[]
	t=[]

	for sample in allSample:

		v.append( sample['VoltADC'] )
		a.append( sample['AmpADC'] )

		if 'ThrustADC' in sample.keys():
			t.append( sample['ThrustADC'] )

	print 'stats samples min max med mean'
	print 'volts', len(v), min(v), max(v), numpy.median(numpy.array( v )), round( numpy.mean(numpy.array( v )), 8 )
	print 'Amps', len(a), min(a), max(a), numpy.median(numpy.array( a )),round(numpy.mean(numpy.array( a )), 8)
	print 'Thrust', len(t), min(t), max(t), numpy.median(numpy.array( t )),round(numpy.mean(numpy.array( t )), 8)

	return

def getMiddleResults(samples, factor=0.1):
	return sorted(samples)[int(len(samples)*factor):-int(len(samples)*factor)] #remove the top and bottom 10% of results

def getWatts(sample, index):
	x = []
	y = []

	smoothV = smoother(avgTaps=24, medTaps=1)
	smoothA = smoother(avgTaps=24, medTaps=1)
	smoothT = smoother(avgTaps=6, medTaps=3)
	for sampleIndex in index['Volt']:

		volt = sample[sampleIndex]['Volt']
		amp = sample[sampleIndex]['Amp']
		smoothV.add( volt )
		smoothA.add( amp )

		if sampleIndex not in index['Thrust']: continue

		thrust = sample[sampleIndex]['Thrust']
		smoothT.add ( thrust )
		watts = round(smoothV.get()*smoothA.get()  , 1 )

		y.append(round(smoothT.get(), 2) )
		x.append(watts)

	return x, y

def getEfficiencyOverRPM(sample, index):
	x = []
	y = []

	smoothV = smoother(avgTaps=24, medTaps=1)
	smoothA = smoother(avgTaps=24, medTaps=1)
	smoothT = smoother(avgTaps=5, medTaps=29)
	for sampleIndex in index['Volt']:

		volt = sample[sampleIndex]['Volt']
		amp = sample[sampleIndex]['Amp']
		smoothV.add( volt )
		smoothA.add( amp )

		if sampleIndex not in index['Thrust']: continue

		thrust = sample[sampleIndex]['Thrust']
		smoothT.add ( thrust )
		rpm = sample[sampleIndex]['RPM']

		watts = round(smoothV.get()*smoothA.get()  , 1 )
		if not watts: continue
		y.append(round(smoothT.get(), 2)/watts )
		x.append(rpm)

	return x, y

def getMechanicalPower(sample, index):
	x = []
	y = []

	smoothT = smoother(avgTaps=5, medTaps=29)
	for sampleIndex in index['Thrust']:
		time = sample[sampleIndex]['Time']

		if sampleIndex not in index['Thrust']: continue

		thrust = sample[sampleIndex]['ThrustF']
		rpm = sample[sampleIndex]['RPM']

		if not rpm: continue

		mechWatts = thrust * (rpm * ((2*math.pi)/60) )
		y.append( round(mechWatts, 2) )
		x.append( util.getFloatTime(time) )

	return x, y

def getTestWatts(sample, index):
	x = []
	y = []

	for sampleIndex in index['Volt']:
		time = sample[sampleIndex]['Time']

		volt = sample[sampleIndex]['VoltF']
		amp = sample[sampleIndex]['AmpF']

		watts = volt*amp
		if not watts: continue
		y.append(round(watts, 2) )
		x.append( util.getFloatTime(time) )

	return x, y

def getMechanicalEff(sample, index):
	x = []
	y = []

	for sampleIndex in index['Volt']:
		time = sample[sampleIndex]['Time']
		roundedTime = util.getFloatTime(time)

		#if roundedTime<11: continue
		#if roundedTime>15: continue

		volt = sample[sampleIndex]['VoltF']
		amp = sample[sampleIndex]['AmpF']

		if sampleIndex not in index['Thrust']: continue

		thrust = sample[sampleIndex]['ThrustF']
		rpm = sample[sampleIndex]['RPM']

		if not rpm: continue

		mechWatts = thrust * (rpm * ((2*math.pi)/60) )
		watts = volt*amp
		if not watts: continue
		y.append(round(mechWatts/watts, 2) )
		x.append(roundedTime)

	return x, y

def getTorqueOverRPM(sample, index, idleOffset=0):
	x = []
	y = []
	z = []
	command = []
	inWatts = []
	inVolts = []

	global dynoStartTime, dynoEndTime
	dynoStartTime = 3
	dynoEndTime = 99
	thisProgramName = sample[0]['programName']

	if 'Marker' in index.keys():
		for sampleIndex in index['Marker']:
			if sample[sampleIndex]['Marker'] == 1:
				dynoStartTime = util.getFloatTime(sample[sampleIndex]['Time'])
			if sample[sampleIndex]['Marker'] == 2:
				dynoEndTime = util.getFloatTime(sample[sampleIndex]['Time'])

	minThrust = None
	minThrustIndex = None
	minRpm = None
	minRpmIndex =None

	for sampleIndex in index['Time']:
		time = sample[sampleIndex]['Time']
		roundedTime = util.getFloatTime(time)

		if roundedTime<dynoStartTime-dynoPreLoad: continue
		if roundedTime>dynoEndTime: break

		if not minThrust:
			minThrust = sample[sampleIndex]['ThrustF']
			minThrustIndex = sampleIndex

		if not minRpm:
			minRpm = sample[sampleIndex]['RPM']
			minRpmIndex = sampleIndex

		if sample[sampleIndex]['ThrustF'] < minThrust:
			minThrust = sample[sampleIndex]['ThrustF']
			minThrustIndex = sampleIndex

		if sample[sampleIndex]['RPMF'] < minRpm:
			minRpm = sample[sampleIndex]['RPMF']
			minRpmIndex = sampleIndex

	print 'range indexes', minThrustIndex, minRpmIndex
	for sampleIndex in index['RPM']:
		time = sample[sampleIndex]['Time']
		roundedTime = util.getFloatTime(time)

		if sampleIndex>minRpmIndex: break
		if sampleIndex<minThrustIndex: continue

		volt = sample[sampleIndex]['VoltF']
		amp = sample[sampleIndex]['AmpF']

		#if sampleIndex not in index['Thrust']: continue

		thrust = sample[sampleIndex]['ThrustF']+idleOffset

		rpm = sample[sampleIndex]['RPMF']

		if not rpm: continue

		mechWatts = thrust * (rpm * ((2*math.pi)/60) )
		watts = volt*amp
		if not watts: continue

		y.append(round(thrust, 4) )
		x.append(rpm)
		z.append(round(mechWatts/watts, 2) )
		inWatts.append(round(watts, 1) )
		inVolts.append(round(volt, 2) )
		command.append(sample[sampleIndex]['Motor Command'] )

	accX = []
	accY = []
	accZ = []
	accInWatts = []
	accInVolts = []

	'''
	extraData = {}
	extraData['z'] = z
	extraData['inWatts'] = inWatts
	extraData['command'] = command

	return x, y, extraData, thisProgramName
	'''

	mergedX = []
	mergedY = []
	mergedZ = []
	mergedCommand = []
	mergedInWatts = []
	mergedInVolts = []
	lastValue = y[0]
	lastIndex = 0
	maxDist = 1000
	#maxDist = 250

	#preload the merged result with the actual highest RPM sample
	mergedCommand.append(command[0])
	mergedX.append(x[0])
	mergedY.append(y[0])
	mergedZ.append(z[0])
	mergedInWatts.append(inWatts[0])
	mergedInVolts.append(inVolts[0])

	#reduce point count based on segment distance
	for index in range(0,len(x)):
		xDist = x[index] - x[lastIndex]
		yDist = ( y[index] - y[lastIndex] )*1000000
		thisDist = abs( math.sqrt( pow(xDist,2) + pow(yDist,2) ) )

		if thisDist > maxDist:
			mergedCommand.append(command[index])
			mergedX.append(numpy.mean(accX))
			mergedY.append(numpy.mean(accY))
			mergedZ.append(numpy.mean(accZ))
			mergedInWatts.append(numpy.mean(accInWatts))
			mergedInVolts.append(numpy.mean(accInVolts))
			accX = []
			accY = []
			accZ = []
			accInWatts = []
			accInVolts = []
			lastIndex = index

		accX.append(x[index])
		accY.append(y[index])
		accZ.append(z[index])
		accInWatts.append(inWatts[index])
		accInVolts.append(inVolts[index])

	mergedCommand.append(command[index])
	mergedX.append(numpy.mean(accX))
	mergedY.append(numpy.mean(accY))
	mergedZ.append(numpy.mean(accZ))
	mergedInWatts.append(numpy.mean(accInWatts))
	mergedInVolts.append(numpy.mean(accInVolts))

	extraData = {}
	extraData['z'] = mergedZ
	extraData['inWatts'] = mergedInWatts
	extraData['inVolts'] = mergedInVolts
	extraData['command'] = mergedCommand

	return mergedX, mergedY, extraData, thisProgramName

def getEfficiencyOverThrottle(sample, index):
	x = []
	y = []

	for sampleIndex in index['Thrust']:

		volt = sample[sampleIndex]['VoltF']
		amp = sample[sampleIndex]['AmpF']
		thrust = sample[sampleIndex]['ThrustF']

		throttle = sample[sampleIndex]['Motor Command']

		watts = round(volt*amp  , 1 )
		if not watts: continue
		y.append(round(thrust, 2)/watts )
		x.append(throttle)

	return x, y

def getThrust(sample, index):
	# thrust / RPM
	x = []
	y = []
	smooth = smoother(avgTaps=1, medTaps=1)
	tSmooth = smoother(avgTaps=5, medTaps=29)

	testStartTime = 3
	testEndTime = 99

	if 'Marker' in index.keys():
		for sampleIndex in index['Marker']:
			if sample[sampleIndex]['Marker'] == 1:
				testStartTime = util.getFloatTime(sample[sampleIndex]['Time'])
			if sample[sampleIndex]['Marker'] == 2:
				testEndTime = util.getFloatTime(sample[sampleIndex]['Time'])

	for sampleIndex in index['Thrust']:
		rpm = sample[sampleIndex]['RPMF']
		time = sample[sampleIndex]['Time']
		thrust = sample[sampleIndex]['ThrustF']
		if not rpm: continue

		roundedTime = util.getFloatTime(time)

		if roundedTime<testStartTime: continue
		if roundedTime>testEndTime: break

		smooth.add( rpm )
		smoothedValue = round(smooth.get(), 3 )
		tSmooth.add( thrust )
		tSmoothedValue = round(tSmooth.get(), 3 )
		x.append(smoothedValue)
		y.append(tSmoothedValue)

	return x, y

def getThrustFit(sample, index):
	# thrust / RPM
	x = []
	y = []
	smooth = smoother()
	#sample, index = readLog('C:\\Users\\markm\\Documents\\Drones\\PropBenchmarks\\bladeShapes\\rxTri.txt')
	for sampleIndex in index['RPM']:
		rpm = sample[sampleIndex]['RPM']
		time = sample[sampleIndex]['Time']
		thrust = sample[sampleIndex]['Thrust']
		if rpm > 45000: continue

		smooth.add( rpm )
		smoothedValue = round(smooth.get(), 3 )
		x.append(smoothedValue)
		y.append(thrust)

	xTrim = x[:int(len(x)*0.5)]
	yTrim = y[:int(len(y)*0.5)]
	#Calculate trendline
	x = numpy.linspace(0, 40000, num=len(xTrim))
	order = 2
	coeffs = poly.polyfit(xTrim,yTrim, order)
	y = poly.polyval(x, coeffs)

	return x, y

def getTestThrust(sample, index):
	# thrust / RPM
	x = []
	y = []

	for sampleIndex in index['Thrust']:
		time = sample[sampleIndex]['Time']
		thrust = sample[sampleIndex]['ThrustF']
		y.append( thrust )
		x.append( util.getFloatTime(time) )

	return x, y

def getIdleThrust(sample, index):

	samples = []
	for sampleIndex in index['Thrust']:
		time = sample[sampleIndex]['Time']
		thrust = sample[sampleIndex]['ThrustF']
		if  util.getFloatTime(time) > 1:
			break
		samples.append(thrust)

	if samples:
		return numpy.median(samples)

	return None

def getTestThrustResidual(sample, index):
	# thrust / RPM
	x = []
	y = []

	for sampleIndex in index['Thrust']:
		time = sample[sampleIndex]['Time']
		thrust = sample[sampleIndex]['ThrustResidual']
		y.append( thrust )
		x.append( util.getFloatTime(time) )

	return x, y

def getThrottleThrust(sample, index):
	# thrust / RPM
	x = []
	y = []
	smooth = smoother(avgTaps=1, medTaps=3)
	for sampleIndex in index['Thrust']:
		throttle = sample[sampleIndex]['Motor Command']
		thrust = sample[sampleIndex]['Thrust']
		smooth.add( thrust )
		smoothedValue =  round(smooth.get(), 3 )
		x.append(throttle )
		y.append(smoothedValue)
	return x, y

def getRpmOverThrottle(sample, index):
	# thrust / RPM
	x = []
	y = []
	smooth = smoother(avgTaps=2, medTaps=1)

	for sampleIndex in index['RPM']:
		throttle = sample[sampleIndex]['Motor Command']
		rpm = sample[sampleIndex]['RPM']
		if rpm > 65000:
			continue
		x.append( throttle )
		smooth.add( rpm )
		thisValue = smooth.get()
		y.append(rpm)
	return x, y

def getTestRpm(sample, index, deltaMode=False):
	# thrust / RPM
	x = []
	y = []
	smooth = smoother(avgTaps=2, medTaps=1)
	dsmooth = smoother(avgTaps=2, medTaps=1)

	lastGoodTime = 0
	lastValue = 0
	for sampleIndex in index['RPM']:
		time = sample[sampleIndex]['Time']
		rpm = sample[sampleIndex]['RPMF']
		x.append( util.getFloatTime(time) )
		smooth.add( rpm )
		thisValue = smooth.get()
		if deltaMode:
			dsmooth.add( float(thisValue-lastValue)/(float(time-lastGoodTime)/1000)  )
			y.append( dsmooth.get() )
			lastGoodTime = time
			lastValue = thisValue
		else:
			y.append(rpm)
	return x, y

def getInertia(sample, index, torqueLoad, propLoad):
	x = []
	y = []

	thisStaticTorque = 0

	inertiaStart = 0
	inertiaEnd = 99

	if 'Marker' in index.keys():
		for sampleIndex in index['Marker']:
			if sample[sampleIndex]['Marker'] == 1:
				inertiaStart = util.getFloatTime(sample[sampleIndex]['Time']) + 0.005
				inertiaEnd = inertiaStart + 0.020
				inertiaEnd = inertiaStart + 0.045
				inertiaEnd = inertiaStart + 1

	for i in xrange( 1,len(index['RPM']) ):
		sampleIndex = index['RPM'][i]
		thisTime = sample[sampleIndex]['Time']

		roundedTime = util.getFloatTime(thisTime)
		if roundedTime<inertiaStart: continue
		if roundedTime>inertiaEnd: break

		lastTime = sample[sampleIndex-1]['Time']
		thisRPM = sample[sampleIndex]['RPMF']
		lastRPM = sample[sampleIndex-1]['RPMF']
		thisCommand = sample[sampleIndex]['Motor Command']
		throttle = int(round( (thisCommand/2000.0) * 100))

		if throttle not in torqueLoad.keys():
			continue
		found = False
		for j in xrange( len( torqueLoad[throttle] ) ):
			if torqueLoad[throttle][j]['rpm']> thisRPM:
				found=True
				break

		if not found:
			print 'no torque found', thisRPM, 'on', throttle
			continue

		if propLoad:
			found = False
			for k in xrange( len( propLoad ) ):
				if propLoad[k]['rpm']> thisRPM:
					found=True
					break

			if not found:
				print 'no prop torque found', thisRPM
				continue

			propRPMA = propLoad[k]['rpm']
			propRPMB = propLoad[k-1]['rpm']
			propTorqueA = propLoad[k]['torque']
			propTorqueB = propLoad[k-1]['torque']
			interpDist = (thisRPM-propRPMA)/(propRPMB-propRPMA)
			thisStaticTorque = propTorqueA + (propTorqueB - propTorqueA)*interpDist

		RPMA = torqueLoad[throttle][j]['rpm']
		RPMB = torqueLoad[throttle][j-1]['rpm']
		torqueA = torqueLoad[throttle][j]['torque']
		torqueB = torqueLoad[throttle][j-1]['torque']

		interpDist = (thisRPM-RPMB)/(RPMA-RPMB)
		thisTotalTorque = torqueB + (torqueA - torqueB)*interpDist

		accelTorque = thisTotalTorque - thisStaticTorque

		timeDelta = util.getFloatTime( thisTime - lastTime )
		RPMDelta = thisRPM - lastRPM

		accel = RPMDelta/timeDelta

		accelRadian = (math.pi/30) * accel
		torqueNm = accelTorque/100
		inertia = torqueNm/accelRadian # in kg m^2
		inertiaG = inertia*pow(10, 7) # in g cm^2
		#T=I*A
		#T/A = I
		if inertiaG > 200: continue
		if inertiaG < 0: continue

		x.append( util.getFloatTime(thisTime) )
		y.append(inertiaG)

	if len(y)>6:
		print 'Y length', len(y)
		y = filters.butterFilter(y, order = 1, cutoff = 0.5 )

	return x, y

def getInertiaSingle(sample, index):
	x = []
	y = []

	thisStaticTorque = 0

	inertiaStart = 0
	inertiaEnd = 99

	if 'Marker' in index.keys():
		for sampleIndex in index['Marker']:
			if sample[sampleIndex]['Marker'] == 1:
				inertiaStart = util.getFloatTime(sample[sampleIndex]['Time']) + 0.005
				inertiaEnd = inertiaStart + 0.020
				inertiaEnd = inertiaStart + 0.045
				inertiaEnd = inertiaStart + 1

	for i in xrange( 1,len(index['RPM']) ):
		sampleIndex = index['RPM'][i]
		thisTime = sample[sampleIndex]['Time']

		roundedTime = util.getFloatTime(thisTime)
		if roundedTime<inertiaStart: continue
		if roundedTime>inertiaEnd: break

		lastTime = sample[sampleIndex-1]['Time']
		thisRPM = sample[sampleIndex]['RPMF']
		lastRPM = sample[sampleIndex-1]['RPMF']
		thisCommand = sample[sampleIndex]['Motor Command']
		throttle = int(round( (thisCommand/2000.0) * 100))

		accelTorque = sample[sampleIndex]['ThrustF']

		timeDelta = util.getFloatTime( thisTime - lastTime )
		RPMDelta = thisRPM - lastRPM

		accel = RPMDelta/timeDelta

		accelRadian = (math.pi/30) * accel
		torqueNm = accelTorque
		inertia = torqueNm/accelRadian # in kg m^2
		inertiaG = inertia*pow(10, 7) # in g cm^2
		#T=I*A
		#T/A = I
		if inertiaG > 200: continue
		if inertiaG < 0: continue

		x.append( util.getFloatTime(thisTime) )
		y.append(inertiaG)

	if len(y)>6:
		print 'Y length', len(y)
		y = filters.butterFilter(y, order = 1, cutoff = 0.5 )

	return x, y

def getTestRpmError(sample, index, deltaMode=False):
	x = []
	y = []

	for sampleIndex in index['autoCalibrate']:
		time = sample[sampleIndex]['Time']
		volt = sample[sampleIndex]['autoCalibrate']
		x.append( util.getFloatTime(time) )
		y.append(volt)
	return x, y

def getTestVoltsRaw(sample, index):
	x = []
	y = []

	for sampleIndex in index['Volt']:
		time = sample[sampleIndex]['Time']
		volt = sample[sampleIndex]['Volt']
		x.append( util.getFloatTime(time) )
		y.append(volt)
	return x, y

def getTestTRaw(sample, index, deltaMode=False, sensor='T1'):
	x = []
	y = []
	lastGoodTime = 0
	lastValue = 0
	dsmooth = smoother(avgTaps=70, medTaps=5)
	smooth = smoother(avgTaps=1, medTaps=5)

	for sampleIndex in index[sensor]:
		time = sample[sampleIndex]['Time']
		T = sample[sampleIndex][sensor]
		x.append( util.getFloatTime(time) )

		if deltaMode:
			dsmooth.add( 1000*(float(T-lastValue)/(float(time-lastGoodTime)/1000))  )
			y.append( dsmooth.get() )
			lastGoodTime = time
			lastValue = T
		else:
			#smooth.add(T)
			y.append(T)

	return x, y

def getThrustOverT1(sample, index):
	x = []
	y = []
	for sampleIndex in index['Thrust']:
		T1 = sample[sampleIndex]['T1']
		thrust = sample[sampleIndex]['Thrust']
		x.append(T1 )
		y.append(thrust)
	return x, y

def getThrustOverV(sample, index):
	x = []
	y = []
	for sampleIndex in index['Thrust']:
		volt = sample[sampleIndex]['Volt']
		thrust = sample[sampleIndex]['Thrust']
		x.append(volt )
		y.append(thrust)
	return x, y

def getCommandRaw(sample, index, trace='Motor'):
	x = []
	y = []
	for sampleIndex in index[trace+' Command']:
		time = sample[sampleIndex]['Time']
		T1 = sample[sampleIndex][trace+' Command']
		x.append( util.getFloatTime(time) )
		y.append(T1)
	return x, y

def getTestAmpsRaw(sample, index):
	x = []
	y = []
	for sampleIndex in index['Amp']:
		time = sample[sampleIndex]['Time']
		amp = sample[sampleIndex]['Amp']
		x.append( util.getFloatTime(time) )
		y.append(amp)
	return x, y

def getTestVolts(sample, index):
	x = []
	y = []

	smooth = smoother(avgTaps=24, medTaps=6)
	lastTime = 0
	for sampleIndex in index['Volt']:
		time = sample[sampleIndex]['Time']
		volt = sample[sampleIndex]['Volt']
		smooth.add( volt )
		if time-lastTime > MIN_SAMPLE_TIME:
			x.append( util.getFloatTime(time) )
			y.append(sample[sampleIndex]['VoltF'])
			lastTime = time
	return x, y

def getTestAmps(sample, index):
	x = []
	y = []

	smooth = smoother(avgTaps=24, medTaps=6)
	lastTime = 0
	for sampleIndex in index['Amp']:
		time = sample[sampleIndex]['Time']
		amp = sample[sampleIndex]['Amp']
		smooth.add( amp )

		if time-lastTime > MIN_SAMPLE_TIME:
			x.append( util.getFloatTime(time) )
			y.append(sample[sampleIndex]['AmpF'])
			lastTime = time
	return x, y

def getTestRpmRAW(sample, index, deltaMode=False):
	# thrust / RPM
	x = []
	y = []
	lastGoodTime=0
	lastValue=0
	for sampleIndex in index['RPMRAW']:
		time = sample[sampleIndex]['Time']
		rpm = sample[sampleIndex]['RPMRAW']
		x.append( util.getFloatTime(time) )

		thisValue = rpm
		if deltaMode:
			y.append( float(thisValue-lastValue)/(float(time-lastGoodTime)/1000) )
			lastGoodTime = time
			lastValue = thisValue
		else:
			y.append(thisValue)

	return x, y

def getLoad(sample, index, unloadedRPM):
	# Motor Load
	x = []
	y = []
	smooth = smoother()
	#sample, index = readLog('C:\\Users\\markm\\Documents\\Drones\\PropBenchmarks\\bladeShapes\\rxTri.txt')
	for sampleIndex in index['RPM']:
		value = sample[sampleIndex]['RPM']
		time = sample[sampleIndex]['Time']

		if value > 60000: continue
		x.append( util.getFloatTime(time) )
		smooth.add( value )
		smootedValue = round(smooth.get(), 3 )
		if sampleIndex >= len(unloadedRPM): continue
		if unloadedRPM[sampleIndex]==None: continue
		y.append(100- (smootedValue/unloadedRPM[sampleIndex])*100 )
	return x, y

def getUnloadedBaseline(logPath):
	sample, index = readBinaryLog(logPath)

	unloadedRPM = [None]*len(sample)
	unloadedIndex = []
	smooth = smoother(avgTaps=4, medTaps=1)
	for sampleIndex in index['RPM']:
		value = sample[sampleIndex]['RPM']

		if value > 60000: continue
		smooth.add( value )
		unloadedRPM[sampleIndex] = round(smooth.get(), 3 )
		unloadedIndex.append(sampleIndex)

	getInterpolated(unloadedIndex, unloadedRPM)
	return unloadedRPM

def createPropDump(sample, index):
	maxCommand = 2000
	targetCommands = [ maxCommand*(i/100.0) for i in range(5,105,5) ]
	lastCommandIndex = 0
	dump = []
	for i in range(len(index['Motor Command'])):
		sampleIndex = index['Motor Command'][i]
		command = sample[sampleIndex]['Motor Command']

		if command >= targetCommands[lastCommandIndex]:
			rpm = sample[sampleIndex]['RPMF']
			thrust = sample[sampleIndex]['ThrustF']
			print 'threshold', command, rpm

			thisDump = {}
			thisDump['rpm']=rpm
			thisDump['thrust']=thrust
			thisDump['torque']=-1
			thisDump['command']=command

			dump.append(thisDump)

			lastCommandIndex = lastCommandIndex+1
			if lastCommandIndex >= len(targetCommands):
				break

	dumpFile = open('last.prop', 'w')
	json.dump(dump, dumpFile, sort_keys=True, indent=4, separators=(',', ': '))
	dumpFile.close()

	return dump

def integratePropDump(sample, index, dump,  idleOffset=0):
	x = []
	y = []
	z = []
	command = []
	inWatts = []

	thisProgramName = sample[0]['programName']
	nameSplit = thisProgramName.split('_')
	throttleValue = float(nameSplit[0])
	thisDumpEntry = None

	print 'starting with dump, searching for',(throttleValue/100)*2000
	for item in dump:
		if item['command']==(throttleValue/100)*2000:
			print 'found dump entry', item
			thisDumpEntry = item
			break

	if not thisDumpEntry: return dump

	targetRPM = thisDumpEntry['rpm']
	tolerance = 200

	torqueAcc = []
	minThrust = None
	minThrustIndex = None
	minRpm = None
	minRpmIndex =None

	global dynoStartTime, dynoEndTime

	if 'Marker' in index.keys():
		for sampleIndex in index['Marker']:
			if sample[sampleIndex]['Marker'] == 1:
				dynoStartTime = util.getFloatTime(sample[sampleIndex]['Time'])+.5
			if sample[sampleIndex]['Marker'] == 2:
				dynoEndTime = util.getFloatTime(sample[sampleIndex]['Time'])-.05

	print 'start/end', dynoStartTime, dynoEndTime

	for sampleIndex in index['RPM']:
		time = sample[sampleIndex]['Time']
		roundedTime = util.getFloatTime(time)

		if roundedTime<dynoStartTime-dynoPreLoad: continue
		if roundedTime>dynoEndTime: break

		if not minThrust:
			minThrust = sample[sampleIndex]['ThrustF']
			minThrustIndex = sampleIndex

		if not minRpm:
			minRpm = sample[sampleIndex]['RPM']
			minRpmIndex = sampleIndex

		if sample[sampleIndex]['ThrustF'] < minThrust:
			minThrust = sample[sampleIndex]['ThrustF']
			minThrustIndex = sampleIndex

		if sample[sampleIndex]['RPMF'] < minRpm:
			minRpm = sample[sampleIndex]['RPMF']
			minRpmIndex = sampleIndex

	print minThrust, minThrustIndex, util.getFloatTime(sample[minThrustIndex]['Time']), minRpm, minRpmIndex,  util.getFloatTime(sample[minRpmIndex]['Time'])

	foundExact = None

	for sampleIndex in index['RPM']:
		time = sample[sampleIndex]['Time']
		roundedTime = util.getFloatTime(time)

		if sampleIndex>minRpmIndex: break
		if sampleIndex<minThrustIndex: continue

		thisTorque = (sample[sampleIndex]['ThrustF']+idleOffset)*100 # convert Nm to Ncm
		rpm = sample[sampleIndex]['RPMF']

		if not rpm: continue

		if (not foundExact) and (rpm < targetRPM):
			foundExact = thisTorque
			print 'found point', thisTorque, sample[sampleIndex]['Thrust']*100, sample[sampleIndex]['RPMF'], sample[sampleIndex]['RPM']
		tolerance = targetRPM * 0.005
		if ((rpm > targetRPM-tolerance) and (rpm < targetRPM+tolerance)):
			print 'found range', thisTorque,sample[sampleIndex]['RPM']
			torqueAcc.append( thisTorque)

	print 'averaging', len(torqueAcc)

	if not torqueAcc: return dump

	averageTorque = sum(torqueAcc)/len(torqueAcc)
	thisDumpEntry['torque']=foundExact
	thisDumpEntry['torqueCnt']=len(torqueAcc)

	dumpFile = open('lastIntegrate.prop', 'w')
	json.dump(dump, dumpFile, sort_keys=True, indent=4, separators=(',', ': '))
	dumpFile.close()

	return dump

def MQTBDump(sample, index):
	x = []
	y = []

	erpmPoleCount = 7
	sampleIncrement = 0.004
	lastTime = 0.0

	testStartTime = 0.0
	testStartUsec = 0
	if 'Marker' in index.keys():
		for sampleIndex in index['Marker']:
			if sample[sampleIndex]['Marker'] == 1:
				testStartTime = util.getFloatTime(sample[sampleIndex]['Time'])
				testStartUsec = sample[sampleIndex]['Time']

	import csv
	with open('mqtbDump.csv', 'wb') as csvFile:
		dumpWriter = csv.writer(csvFile)
		dumpWriter.writerow(['Time(uS)', 'Throttle(uS)', 'Thrust(g)', 'eSteps', 'eRPMs', 'Volts', 'Amps'])

		for sampleIndex in index['Volt']:

			time = sample[sampleIndex]['Time']
			floatTime = util.getFloatTime(time)
			if floatTime < testStartTime:
				lastTime = floatTime
				continue

			throttle = (sample[sampleIndex]['Motor Command']/2)+1000
			thrust = round(sample[sampleIndex]['ThrustF'], 4)
			eSteps = 0
			rpm = round(sample[sampleIndex]['RPMSingle'])
			volt = round(sample[sampleIndex]['VoltF'], 4)
			amp = round(sample[sampleIndex]['AmpF'], 4)

			floatTime = util.getFloatTime(time)
			erpm = rpm * erpmPoleCount

			if floatTime > (lastTime+sampleIncrement):
				lastTime = lastTime+sampleIncrement
				dumpWriter.writerow([time-testStartUsec, throttle, thrust, eSteps, erpm, volt, amp])

	return x, y

def buildFigure(dataList, labelList, deltaMode, chartTitle=None, mode=None, patchLoad=None):
	colorsSource = ['steelblue', 'teal', 'indigo', 'greenyellow', 'gray', 'fuchsia', 'yellow', 'black', 'purple', 'orange', 'green', 'blue','red']
	colors = copy.copy(colorsSource)
	xLabel = labelList['x']
	yLabel = labelList['y']
	yScale = labelList['yScale']

	if deltaMode:
		yScale = labelList['yScaleDelta']

	figureArgs ={}
	figureArgs['y_range']=[0, yScale]
	#figureArgs['x_range']=[0, 40000]

	deltaString = ''
	if deltaMode:
		deltaString = ' - Delta'

	outputFile = './output/'+mode+deltaString+'.html'
	outputTitle = mode+deltaString
	if chartTitle:
		outputTitle = chartTitle

	output_file( outputFile, title=outputTitle, mode='inline' )

	foundZ = False

	for item in dataList[::-1]:
		if item['extraData']:
			foundZ = True
	tooltipList = [
			#("index", "$index"),
			(xLabel, "@x{1.11}"),
			(yLabel, "@y{1.11}"),
		]

	if foundZ:
		tooltipList.append(('eff', "@z{1.11}") )
		tooltipList.append(('power', "@inWatts{1.11}") )
		tooltipList.append(('command', "@command{1.11}") )

	hover = HoverTool(
		tooltips = tooltipList,
		names=['propLine', 'scatterPlot']
		#mode='vline',
	)

	mapperColors = ["#d7191c", "#CF353D", "#C7505E", "#CF7E8C", "#CDA0B1", "#cac2d6", "#9EB5DA", "#72A8DE", "#459AE2", "#198de6"]
	mapper = LinearColorMapper(palette=mapperColors, low=.0, high=1)
	mapperLegend = LinearColorMapper(palette=mapperColors, low=.0, high=100)

	# load up the patch data, building the polygons for each efficiency range
	patches = {}
	patches['data'] = {}
	outsidePoints = []

	if not patchLoad:
		print 'creating default patch'
		patchLoad = {1: [[0, 0], [0, 0.001]], 2: [], 3: [], 4: [], 5: [], 6: [], 7: [], 8: [], 9: [], 10: []}

		patches, outsidePoints = chartBuilder.loadPatchDump(patchLoad)
	else:
		print 'using passed patch'
		patches, outsidePoints = chartBuilder.loadPatchDump(patchLoad)

		#if loading a patch file over ride the display range of the chart to fit
		figureArgs['y_range']=[0, patches['ymax']*1.1]
		figureArgs['x_range']=[0, patches['xmax']*1.15]

	allScatter = []

	print 'args', figureArgs

	p = figure(
		width=1520, plot_height=880,
		tools=[hover,'pan','box_zoom','wheel_zoom', 'reset','crosshair', 'tap'],#"resize,pan,wheel_zoom,box_zoom,reset,box_select,lasso_select,hover",
		active_scroll='wheel_zoom',
		#y_range=None,
		x_axis_label=xLabel,# y_axis_label=yLabel,
		output_backend="webgl",
		title=outputTitle,
		**figureArgs

	)

	if (outputTitle == 'Torque Over RPM') or (patchLoad):
		color_bar = ColorBar(color_mapper=mapperLegend, major_label_text_font_size="8pt",
                     ticker=BasicTicker(desired_num_ticks=len(colors)),
                     formatter=PrintfTickFormatter(format="%d%%"),
                     label_standoff=6, border_line_color=None,
                     height=500, location=(-80, 0))
		p.add_layout(color_bar, 'right')

		if patches:
			chartBuilder.addPatchToChart(patches, outsidePoints, mapperColors, p)

			chartBuilder.findIntersections(dataList, outsidePoints, p)

	for item in dataList[::-1]:
		if not colors:
			colors = copy.copy(colorsSource)

		print 'creating plot for', item['label'], item['mode']
		#thisRange = defaultRange
		rangeArgs = {}
		if item['extraRange']:
			rangeName = item['label'] + '_range'
			p.extra_y_ranges.update( {rangeName: Range1d(start=0, end=item['extraRange'])} )
			p.add_layout(LinearAxis(y_range_name=rangeName, axis_label=item['extraLabel']), 'left')
			#thisRange = rangeName
			rangeArgs['y_range_name']=rangeName

		data = {
			'x':item['x'],
			'y':item['y']
			}

		if item['extraData']:
			data['z']= item['extraData']['z']
			if 'inWatts' in  item['extraData'].keys():
				data['inWatts']= item['extraData']['inWatts']
				data['command']= item['extraData']['command']
				data['scatterSize']=[i * 8 for i in item['extraData']['z']]
				data['color']=[i  for i in item['extraData']['z']]

		source = ColumnDataSource( data=data)
		if item['mode']=='line':
			p.line('x', 'y', source=source, name='propLine', legend=item['label'], color=colors.pop(), line_width=3, *rangeArgs)

		else:
			scatterSize = 8
			if item['extraData']:
				#scatterSize = 'scatterSize'
				thisColor = {'field': 'z', 'transform': mapper}
			else:
				thisColor = colors.pop()
			thisScatter = p.scatter('x', 'y', source=source, name='scatterPlot', legend=item['label'], color=thisColor, size=scatterSize, *rangeArgs)
			allScatter.append(thisScatter)

	p.legend.location = "top_left"
	p.legend.click_policy="hide"

	callback = CustomJS(code="""
	// the event that triggered the callback is cb_obj:
	// The event type determines the relevant attributes
	if (typeof coords == 'undefined') {
		coords = [];
	}
	coords.push( [ Math.round(cb_obj.x), +cb_obj.y.toFixed(2) ] );
	console.log('Tap event occured at x-position: ' + cb_obj.x + ', '+ cb_obj.y);
	""")

	tapCallback = CustomJS(code="""
	if (typeof coords == 'undefined') {
		coords = [];
	}
	var srcIndex = cb_data.source.selected['1d'].indices[0];
	var d1 = cb_data.source.data;
	var x = d1['x'][srcIndex];
	var y = d1['y'][srcIndex];
	console.log('TapTool event occured at x-position: ' + x + ', '+ y);
	console.log(parseInt(patchIndexInput.value));
	var hitCoord = [ Math.round(x), y.toFixed(2) ]
	coords.push( hitCoord );
	checkHit(hitCoord, parseInt(patchIndexInput.value) )
	""")

	#p.js_on_event(events.Tap, callback)

	taptool = p.select(type=TapTool)
	taptool.callback = tapCallback

	sliderCallback = CustomJS(args=dict(source=source, xRange=p.x_range, yRange=p.y_range), code="""
	var xMin = parseFloat(xMinInput.value);
	var xMax = parseFloat(xMaxInput.value);
	var yMin = parseFloat(yMinInput.value);
	var yMax = parseFloat(yMaxInput.value);

	xRange.start = xMin;
	xRange.end = xMax;

	yRange.start = yMin;
	yRange.end = yMax;
	""")

	bookmarkCallback = CustomJS(args=dict(source=source, xRange=p.x_range, yRange=p.y_range), code="""
	var bookmarkString = bookmarkInput.value;
	var stringSplit = bookmarkString.split(":");
	var xMin = parseFloat(stringSplit[0]);
	var xMax = parseFloat(stringSplit[1]);
	var yMin = parseFloat(stringSplit[2]);
	var yMax = parseFloat(stringSplit[3]);

	xRange.start = xMin;
	xRange.end = xMax;

	yRange.start = yMin;
	yRange.end = yMax;
	""")

	sizeCallback = CustomJS(args=dict( plot=p ), code="""
	var size = parseFloat(sizeInput.value);
	allRenderers = plot.renderers;

	for (var index in allRenderers) {
		item = allRenderers[index];
		if ('y_range_name' in item){
			if (item.y_range_name == "default"){
				if ('glyph' in item){
					item.glyph.size=size;
				}
			}
		}
	}
	""")

	yMaxInput = widgets.TextInput(value="8", title="Ymax", callback=sliderCallback)
	sliderCallback.args['yMaxInput']=yMaxInput
	yMinInput = widgets.TextInput(value="0", title="Ymin", callback=sliderCallback)
	sliderCallback.args['yMinInput']=yMinInput
	xMaxInput = widgets.TextInput(value="40000", title="xmax", callback=sliderCallback)
	sliderCallback.args['xMaxInput']=xMaxInput
	xMinInput = widgets.TextInput(value="0", title="xmin", callback=sliderCallback)
	sliderCallback.args['xMinInput']=xMinInput
	bookmarkInput = widgets.TextInput(value="", title="bookmark", callback=bookmarkCallback)
	sliderCallback.args['bookmarkInput']=bookmarkInput
	bookmarkCallback.args['bookmarkInput']=bookmarkInput
	sizeInput = widgets.TextInput(value="", title="size", callback=sizeCallback)
	sizeCallback.args['sizeInput']=sizeInput

	patchIndexInput = widgets.TextInput(value="", title="patch index")
	tapCallback.args['patchIndexInput']=patchIndexInput

	xMinChangeCB = CustomJS(args=dict(source=source, xRange=p.x_range, yRange=p.y_range,
		xMinInput=xMinInput, xMaxInput=xMaxInput, yMinInput=yMinInput, yMaxInput=yMaxInput, bookmarkInput=bookmarkInput), code="""
	xMinInput.value = xRange.start.toString();
	xMaxInput.value = xRange.end.toString();
	yMinInput.value = yRange.start.toString();
	yMaxInput.value = yRange.end.toString();
	bookmarkInput.value = xRange.start.toString()+":"+ xRange.end.toString()+":"+ yRange.start.toString() + ":" + yRange.end.toString();
	""")

	p.x_range.js_on_change('start', xMinChangeCB)
	p.x_range.js_on_change('end', xMinChangeCB)
	p.y_range.js_on_change('start', xMinChangeCB)
	p.y_range.js_on_change('end', xMinChangeCB)

	layout = row(
		p,
		widgetbox(xMinInput, xMaxInput, yMinInput, yMaxInput, bookmarkInput, sizeInput, patchIndexInput),

	)
	from jinja2 import Template

	template = Template('''<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>{{ title|e if title else "Bokeh Plot" }}</title>
        {{ bokeh_css }}
        {{ bokeh_js }}
        <script type="text/javascript" src="patchLoader.js"></script>
    </head>
    <body>
        {{ plot_div|indent(8) }}
        {{ plot_script|indent(8) }}
        <input type=button value="loadPatch" onclick="loadPatchFile()">
		<input type='button' value='download patch' onclick='dumpPatch();'>
		<input type='button' value='reset band' onclick='resetBand();'>
		<input type='button' value='reset all' onclick='resetAll();'>

        <form id="jsonFile" name="jsonFile" enctype="multipart/form-data" method="post">

		  <fieldset>
		    <h2>Json File</h2>
		     <input type='file' id='fileinput'>
		     <input type='button' id='btnLoad' value='Load' onclick='loadFile();'>
		  </fieldset>
		</form>
    </body>
</html>''')

	bokeh.io.save(layout)
	with open(outputFile, "w") as f:
		f.write(bokeh.embed.file_html(layout, bokeh.resources.INLINE, template=template) )
	reset_output()

	webbrowser.open('file://' + os.path.realpath(outputFile))


text:
package com.chetbox.twitter.android;

import com.twitter.sdk.android.core.TwitterSession;

import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.conf.Configuration;
import twitter4j.conf.ConfigurationBuilder;

public class Twitter4JWrapper {

    private static Twitter sTwitter;

    public static Twitter twitter4j() {
        if (sTwitter == null) {
            TwitterSession session = com.twitter.sdk.android.Twitter.getSessionManager().getActiveSession();

            Configuration twitterConfig = new ConfigurationBuilder()
                    .setDebugEnabled(true)
                    .setJSONStoreEnabled(true)
                    .setOAuthConsumerKey(TwitterApplication.TWITTER_KEY)
                    .setOAuthConsumerSecret(TwitterApplication.TWITTER_SECRET)
                    .setOAuthAccessToken(session.getAuthToken().token)
                    .setOAuthAccessTokenSecret(session.getAuthToken().secret)
                    .build();

            sTwitter = new TwitterFactory(twitterConfig).getInstance();
        }
        return sTwitter;
    }

}


text:
// Copyright 2011 WebDriver committers
// Copyright 2011 Google Inc.
//
// Licensed 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.

/**
 * @fileoverview Ready to inject atoms for handling web SQL database.
 */

goog.provide('webdriver.atoms.inject.storage.database');

goog.require('bot.Error');
goog.require('bot.ErrorCode');
goog.require('bot.storage.database');
goog.require('webdriver.atoms.inject');

/**
 * Executes the given query in the Web SQL database specified.
 *
 * @param {string} databaseName The name of the database.
 * @param {string} query The SQL statement.
 * @param {Array.<*>} args Arguments to pass to the query.
 * @param {function(string)} onDone The callback to invoke when done. The
 *     result, according to the wire protocol, will be passed to this callback.
 */
webdriver.atoms.inject.storage.database.executeSql =
    function(databaseName, query, args, onDone) {
  var onSuccessCallback = function(tx, result) {
    onDone(webdriver.atoms.inject.executeScript(function(res) {
      return result;
    }, [result]));
  };

  var onErrorCallback = function(error) {
    onDone(webdriver.atoms.inject.executeScript(function() {
      throw new bot.Error(bot.ErrorCode.SQL_DATABASE_ERROR,
          'SQL Error Code: ' + error.code + '. SQL Error Message: ' +
          error.message);
    }, []));
  };

  bot.storage.database.executeSql(
      databaseName, query, args, onSuccessCallback, onErrorCallback);
};


text:
.blog-container{padding-top:30px;padding-bottom:60px}
.user-avatar{margin-top:20px}
img.user-logo-img{width:100px;height:100px;border-radius:100px;border:1px solid #ddd;-webkit-box-shadow:2px 2px 2px #888;box-shadow:2px 2px 2px #888}
.blog-post-container{margin-top:60px}.blog-post-container .nav-pills{margin-bottom:20px}
.blog-post-item .panel-heading{background-color:#fff}
.username{margin-top:5px;margin-left:5px}
.datetime{color:#999;font-size:.9em}
.article-post-all .nav-pills{margin-bottom:20px}
.blog-sidebar-container .user-avatar .username{margin-top:15px}.blog-sidebar-container .user-avatar .username a{color:#333;font-weight:bold;font-size:16px}
.aritile-side-info img{width:60px;height:60px;border-radius:100px;-webkit-box-shadow:2px 2px 3px #888;box-shadow:2px 2px 3px #888}
.aritile-side-info .username{margin:5px auto;font-color:#999}
.index-article-nav .nav>li>a{padding:5px 10px;font-size:14px;border-radius:3px;margin-right:5px}
.index-article-list{margin-bottom:30px}.index-article-list a{color:#444}
.index-article-list .a-header{font-weight:bold;margin-bottom:5px}
.index-article-list .a-body{margin-top:10px;color:#666}
.index-article-list .a-info{margin-top:6px;font-size:.9em}.index-article-list .a-info a{color:#666}
.article-view .t1{font-size:22px;font-weight:bold;margin:0 0 0 -1px;padding:0}
.article-view .a-info{font-size:14px;color:#444;margin:5px 0 25px}
.article-view .abstract{margin-bottom:30px;color:#666;font-size:18px}.article-view .abstract .fa-quote-left{margin-right:10px}
.article-view .abstract .fa-quote-right{margin-left:10px}
.article-view .a-body h1,.article-view .a-body h2,.article-view .a-body h3,.article-view .a-body h4,.article-view .a-body h5,.article-view .a-body h6{font-size:18px;color:#333;font-weight:bold}
.article-view-baseinfo{margin-top:25px}.article-view-baseinfo table{font-size:.9em}.article-view-baseinfo table th{text-align:right}
.article-view-baseinfo table td{padding-left:5px}
.tag{border-radius:3px;background-color:#ff0;color:#999;padding:2px 5px;margin-bottom:5px;display:inline-block}
.post-new textarea#body{height:360px}


text:
class Manufacturer < ActiveRecord::Base
  include Islay::MetaData
  include Islay::Publishable

  extend FriendlyId
  friendly_id :name, :use => [:slugged, :finders]

  include PgSearch
  multisearchable :against => [:name, :description, :metadata]

  track_user_edits
  validations_from_schema

  has_many   :products
  has_many   :manufacturer_assets
  has_many   :assets,    -> {order('position ASC')}, :through => :manufacturer_assets
  has_many   :images,    -> {order('position ASC')}, :through => :manufacturer_assets, :source => :asset, :class_name => 'ImageAsset'
  has_many   :audio,     -> {order('position ASC')}, :through => :manufacturer_assets, :source => :asset, :class_name => 'AudioAsset'
  has_many   :videos,    -> {order('position ASC')}, :through => :manufacturer_assets, :source => :asset, :class_name => 'VideoAsset'
  has_many   :documents, -> {order('position ASC')}, :through => :manufacturer_assets, :source => :asset, :class_name => 'DocumentAsset'

  # Generates a relation with additional fields for summarising manufacturers.
  #
  # @return ActiveRecord::Relation
  def self.summary
    select(%{
      published,
      slug,
      name,
      updated_at,
      (SELECT name FROM users WHERE id = updater_id) AS updater_name
    })
  end

  check_for_extensions
end


text:
since: 2.4.0
category: Poll Management
signatures:
    - []
returns:
    dataType: bool
    description: ~
---

This function needs a description. Please feel free to contribute a description to this function.


text:
layout: post
lang: fr
title:  "Puzzle-ball ours polaire"
date:   2017-08-10 19:25:00
categories: crochet
comments: true
meta_description: "Un doudou ours polaire Amamani Puzzle Ball fait au crochet, modèle Annie's Craft store"
asset_path: 'puzzle-ball-ours-polaire'
tags:
  - amamanipuzzleball
  - crochet
  - doudou
support:
  - jquery
  - gallery
---

Bonsoir à vous!

J'ai terminé aujourd'hui le deuxième cadeau de naissance que je compte offrir à une petite demoiselle.
Il s'agit d'un "Amamani Puzzle Ball" de Annie's Crochet, un peu modifié comme à mon habitude pour en faire un ours polaire (le modèle n'est pas présenté dans le livre).

C'est une balle de préhension démontable en 3 parties, en forme d'animal.

Crochet numéro 3, fil Sunny de Cheval Blanc 100% coton mercerisé coloris écru, perle et noir.
Les explications sont payantes et je ne suis pas en mesure de vous les fournir gratuitement ici.
Vous pouvez néanmoins les retrouver (en anglais) sur le site [Annie's Craft Store](https://www.anniescatalog.com/detail.html?prod_id=113005&source=rvlry), ou vous procurer le livre par vos propres moyens sur internet.

De nouvelles créations sont en cours, alors je vous dis à très bientôt sur Le Crochet d'Argent!

{% include gallery-layout.html gallery=site.data.galleries.puzzle-ball-ours-polaire %}

Je vous souhaite une très belle journée!

LN


text:
declare module "tv4" {
    export interface TV4ErrorCodes {
        [key:string]:number;
    }
    export interface TV4Error {
        code:number;
        message:string;
        dataPath:string;
        schemaPath:string;
    }
    export interface TV4SchemaMap {
        [uri:string]:any;
    }
    export interface TV4BaseResult {
        missing:string[];
        valid:boolean;
        dataPath: string;
        schemaPath: string;
    }
    export interface TV4SingleResult extends TV4BaseResult {
        error:TV4Error;
    }
    export interface TV4MultiResult extends TV4BaseResult {
        errors:TV4Error[];
    }

    export function validate(data:any, schema:any, checkRecursive:boolean, additionalProperties:boolean):boolean;
    export var error:TV4SingleResult;

    export function validateResult(data:any, schema:any):TV4SingleResult;
    export function validateMultiple(data:any, schema:any):TV4MultiResult;

    export function addSchema(uri:string, schema:any):boolean;
    export function getSchema(uri:string):any;
    export function normSchema(schema:any, baseUri:string):any;
    export function resolveUrl(base:string, href:string):string;
    export function freshApi():void;
    export function dropSchemas():void;
    export function reset():void;

    export function getMissingUris(exp?:RegExp):string[];
    export function getSchemaUris(exp?:RegExp):string[];
    export function getSchemaMap():TV4SchemaMap;
    export var errorCodes:TV4ErrorCodes;
}


text:
import re
import tensorflow as tf

from ..compat import tfv1
from ..tfutils.common import get_tf_version_tuple
from ..tfutils.tower import get_current_tower_context
from ..utils import logger
from ..utils.argtools import graph_memoized
from .common import layer_register

__all__ = ['regularize_cost', 'regularize_cost_from_collection',
           'l2_regularizer', 'l1_regularizer', 'Dropout']

@graph_memoized
def _log_once(msg):
    logger.info(msg)

if get_tf_version_tuple() <= (1, 12):
    l2_regularizer = tf.contrib.layers.l2_regularizer  # deprecated
    l1_regularizer = tf.contrib.layers.l1_regularizer  # deprecated
else:
    # oh these little dirty details
    l2_regularizer = lambda x: tf.keras.regularizers.l2(x * 0.5)  # noqa
    l1_regularizer = tf.keras.regularizers.l1

def regularize_cost(regex, func, name='regularize_cost'):
    """
    Apply a regularizer on trainable variables matching the regex, and print
    the matched variables (only print once in multi-tower training).
    In replicated mode, it will only regularize variables within the current tower.

    If called under a TowerContext with `is_training==False`, this function returns a zero constant tensor.

    Args:
        regex (str): a regex to match variable names, e.g. "conv.*/W"
        func: the regularization function, which takes a tensor and returns a scalar tensor.
            E.g., ``tf.nn.l2_loss, tf.contrib.layers.l1_regularizer(0.001)``.

    Returns:
        tf.Tensor: a scalar, the total regularization cost.

    Example:
        .. code-block:: python

            cost = cost + regularize_cost("fc.*/W", l2_regularizer(1e-5))
    """
    assert len(regex)
    ctx = get_current_tower_context()
    if not ctx.is_training:
        # Currently cannot build the wd_cost correctly at inference,
        # because ths vs_name used in inference can be '', therefore the
        # variable filter will fail
        return tf.constant(0, dtype=tf.float32, name='empty_' + name)

    # If vars are shared, regularize all of them
    # If vars are replicated, only regularize those in the current tower
    if ctx.has_own_variables:
        params = ctx.get_collection_in_tower(tfv1.GraphKeys.TRAINABLE_VARIABLES)
    else:
        params = tfv1.trainable_variables()

    names = []

    with tfv1.name_scope(name + '_internals'):
        costs = []
        for p in params:
            para_name = p.op.name
            if re.search(regex, para_name):
                regloss = func(p)
                assert regloss.dtype.is_floating, regloss
                # Some variables may not be fp32, but it should
                # be fine to assume regularization in fp32
                if regloss.dtype != tf.float32:
                    regloss = tf.cast(regloss, tf.float32)
                costs.append(regloss)
                names.append(p.name)
        if not costs:
            return tf.constant(0, dtype=tf.float32, name='empty_' + name)

    # remove tower prefix from names, and print
    if len(ctx.vs_name):
        prefix = ctx.vs_name + '/'
        prefixlen = len(prefix)

        def f(name):
            if name.startswith(prefix):
                return name[prefixlen:]
            return name
        names = list(map(f, names))
    logger.info("regularize_cost() found {} variables to regularize.".format(len(names)))
    _log_once("The following tensors will be regularized: {}".format(', '.join(names)))

    return tf.add_n(costs, name=name)

def regularize_cost_from_collection(name='regularize_cost'):
    """
    Get the cost from the regularizers in ``tf.GraphKeys.REGULARIZATION_LOSSES``.
    If in replicated mode, will only regularize variables created within the current tower.

    Args:
        name (str): the name of the returned tensor

    Returns:
        tf.Tensor: a scalar, the total regularization cost.
    """
    ctx = get_current_tower_context()
    if not ctx.is_training:
        # TODO Currently cannot build the wd_cost correctly at inference,
        # because ths vs_name used in inference can be '', therefore the
        # variable filter will fail
        return tf.constant(0, dtype=tf.float32, name='empty_' + name)

    # NOTE: this collection doesn't always grow with towers.
    # It only grows with actual variable creation, but not get_variable call.
    if ctx.has_own_variables:   # be careful of the first tower (name='')
        losses = ctx.get_collection_in_tower(tfv1.GraphKeys.REGULARIZATION_LOSSES)
    else:
        losses = tfv1.get_collection(tfv1.GraphKeys.REGULARIZATION_LOSSES)
    if len(losses) > 0:
        logger.info("regularize_cost_from_collection() found {} regularizers "
                    "in REGULARIZATION_LOSSES collection.".format(len(losses)))

        def maploss(l):
            assert l.dtype.is_floating, l
            if l.dtype != tf.float32:
                l = tf.cast(l, tf.float32)
            return l

        losses = [maploss(l) for l in losses]
        reg_loss = tf.add_n(losses, name=name)
        return reg_loss
    else:
        return tf.constant(0, dtype=tf.float32, name='empty_' + name)

@layer_register(use_scope=None)
def Dropout(x, *args, **kwargs):
    """
    Same as `tf.layers.dropout`.
    However, for historical reasons, the first positional argument is
    interpreted as keep_prob rather than drop_prob.
    Explicitly use `rate=` keyword arguments to ensure things are consistent.
    """
    if 'is_training' in kwargs:
        kwargs['training'] = kwargs.pop('is_training')
    if len(args) > 0:
        if args[0] != 0.5:
            logger.warn(
                "The first positional argument to tensorpack.Dropout is the probability to keep, rather than to drop. "
                "This is different from the rate argument in tf.layers.Dropout due to historical reasons. "
                "To mimic tf.layers.Dropout, explicitly use keyword argument 'rate' instead")
        rate = 1 - args[0]
    elif 'keep_prob' in kwargs:
        assert 'rate' not in kwargs, "Cannot set both keep_prob and rate!"
        rate = 1 - kwargs.pop('keep_prob')
    elif 'rate' in kwargs:
        rate = kwargs.pop('rate')
    else:
        rate = 0.5

    if kwargs.get('training', None) is None:
        kwargs['training'] = get_current_tower_context().is_training

    if get_tf_version_tuple() <= (1, 12):
        return tf.layers.dropout(x, rate=rate, **kwargs)
    else:
        return tf.nn.dropout(x, rate=rate if kwargs['training'] else 0.)


text:
<?php

require_once(realpath(dirname(__FILE__).'/../../../..').'/functional/helper/dmFunctionalTestHelper.php');
$helper = new dmFunctionalTestHelper();
$helper->boot('admin');

$b = $helper->getBrowser();

$helper->login();

$b->get('/tools/configuration/configuration-panel/index')
->checks(array(
  'code' => 200,
  'moduleAction' => 'dmConfigPanel/index',
  'h1' => 'Configuration panel')
);


text:
layout: default
title: Tutorials
i18n: en
---

Tutorials

Each tutorial is like a self-contained lesson, explaining a
specific aspect of Mu so you have the skills needed to achieve your
learning and coding goals. Most of all, they're written to be both
educational and entertaining.

Start Here!

All the basics you need to know to get started and help with first
        steps in using Mu. If you only read one thing, make it
        this!

Read Level: SUPER EASY

Using Modes

What are modes? How are they used in Mu? We show how
        modes help you make all sorts of fun and awesome projects.

Read Level: SUPER EASY

Where are my Files?

Mu stores all your code in a special folder so it's always in
        the right place. This tutorial explains where and how to find it.

Read Level: SUPER EASY

Using Standard Python3

Python is one of the world's most
        popular, powerful and easy to learn programming languages. This
        tutorial explains how to use Mu to write Python.

Read Level: EASY

Adafruit Boards and Mu

Adafruit make amazing
        gizmos, circuit boards and mini-computers that run
        CircuitPython.
        This tutorial explains how it all works with Mu.

Read Level: EASY

Mu and micro:bit

The BBC micro:bit is a small
        thingamajig with buttons, lights and sensors. This tutorial shows how
        to use
        MicroPython to program it with
        Mu.

Read Level: EASY

Games with Pygame Zero

Writing computer games is super easy and lots of fun with the amazing
        Pygame Zero
        and Mu. This tutorial gets you started.

Read Level: EASY

What is a REPL?

A REPL (Read, Evaluate, Print, Loop) is a super
        powerful way to talk directly with your computer in Python code. This
        tutorial shows you how.

Read Level: INTERMEDIATE

The Visual Debugger

The debugger lets you run Python3 code, stop it while
        it's running, look at the state of your program and step through the
        code one line at a time.

Read Level: INTERMEDIATE

Plotting Data with Mu

Programs generate data. Data can be plotted in ways that make it
        easy to understand. This tutorial explains how Mu's simple built-in
        plotter works.

Read Level: INTERMEDIATE

Keyboard Shortcuts

All the features of Mu can be activated with a keyboard shortcut
        so you don't need to move your hands from the keyboard to move a
        mouse.

Read Level: ADVANCED(ish)

Log Files and Configuration

Log files are a way to discover what Mu is doing in case
        anything goes wrong. It's also possible to configure some of Mu's
        behaviour.

Read Level: ADVANCED(ish)

I've Found a Problem

As you'll see, computers mostly don't work. This tutorial shows you
        what to do with Mu when your code fails or, shock/horror, if Mu
        breaks.

Read Level: ADVANCED(ish)

Advanced Configuration

If you need greater control of the way Mu behaves or you'd like to
        change some of the default settings, this tutorial explains the easy
        steps involved.

Read Level: ADVANCED(ish)

Moving on from Mu

Mu helps you get started, but there will come a time when you will
        outgrow it. This tutorial explains your potential next steps.

Read Level: ADVANCED(ish)


text:
function $() {
	return document.querySelector.apply(document, arguments);
}

if (navigator.userAgent.indexOf("Xcode") != -1) {
	document.documentElement.classList.add("xcode");
}

var jumpTo = $("#jump-to");

if (jumpTo) {
	jumpTo.addEventListener("change", function(e) {
		location.hash = this.options[this.selectedIndex].value;
	});
}

function hashChanged() {
	if (/^#\/\/api\//.test(location.hash)) {
		var element = document.querySelector("a[name='" + location.hash.substring(1) + "']");

		if (!element) {
			return;
		}

		element = element.parentNode;

		element.classList.remove("hide");
		fixScrollPosition(element);
	}
}

function fixScrollPosition(element) {
	var scrollTop = element.offsetTop - 150;
	document.documentElement.scrollTop = scrollTop;
	document.body.scrollTop = scrollTop;
}

[].forEach.call(document.querySelectorAll(".section-method"), function(element) {
	element.classList.add("hide");

	element.querySelector(".method-title a").addEventListener("click", function(e) {
		var info = element.querySelector(".method-info"),
			infoContainer = element.querySelector(".method-info-container");

		element.classList.add("animating");
		info.style.height = (infoContainer.clientHeight + 40) + "px";
		fixScrollPosition(element);
		element.classList.toggle("hide");
		if (element.classList.contains("hide")) {
			e.preventDefault();
		}
		setTimeout(function() {
			element.classList.remove("animating");
		}, 300);
	});
});

window.addEventListener("hashchange", hashChanged);
hashChanged();


text:
package me.rojo8399.placeholderapi.impl.placeholder.gen;

import me.rojo8399.placeholderapi.impl.placeholder.Expansion;

/**
 * @author Wundero
 *
 */
public abstract class InternalExpansion<S, O, V> extends Expansion<S, O, V> {

	protected Object handle;

	public InternalExpansion(String id, Object handle) {
		super(id);
		this.handle = handle;
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getConfiguration() {
		try {
			return (T) handle;
		} catch (Exception e) {
			return null;
		}
	}

	public Object getHandle() {
		return handle;
	}

}


text:
/* Generated by Font Squirrel (http://www.fontsquirrel.com) on June 20, 2011 05:51:29 AM America/New_York */

@font-face {
    font-family: 'OstrichSansCondensedLight';
    src: url('ostrich-light-webfont.eot');
    src: url('ostrich-light-webfont.eot?#iefix') format('embedded-opentype'),
         url('ostrich-light-webfont.woff') format('woff'),
         url('ostrich-light-webfont.ttf') format('truetype'),
         url('ostrich-light-webfont.svg#OstrichSansCondensedLight') format('svg');
    font-weight: normal;
    font-style: normal;

}

@font-face {
    font-family: 'OstrichSansMedium';
    src: url('ostrich-regular-webfont.eot');
    src: url('ostrich-regular-webfont.eot?#iefix') format('embedded-opentype'),
         url('ostrich-regular-webfont.woff') format('woff'),
         url('ostrich-regular-webfont.ttf') format('truetype'),
         url('ostrich-regular-webfont.svg#OstrichSansMedium') format('svg');
    font-weight: normal;
    font-style: normal;

}

@font-face {
    font-family: 'OstrichSansBold';
    src: url('ostrich-bold-webfont.eot');
    src: url('ostrich-bold-webfont.eot?#iefix') format('embedded-opentype'),
         url('ostrich-bold-webfont.woff') format('woff'),
         url('ostrich-bold-webfont.ttf') format('truetype'),
         url('ostrich-bold-webfont.svg#OstrichSansBold') format('svg');
    font-weight: normal;
    font-style: normal;

}

@font-face {
    font-family: 'OstrichSansBlack';
    src: url('ostrich-black-webfont.eot');
    src: url('ostrich-black-webfont.eot?#iefix') format('embedded-opentype'),
         url('ostrich-black-webfont.woff') format('woff'),
         url('ostrich-black-webfont.ttf') format('truetype'),
         url('ostrich-black-webfont.svg#OstrichSansBlack') format('svg');
    font-weight: normal;
    font-style: normal;

}

@font-face {
    font-family: 'OstrichSansRoundedMedium';
    src: url('ostrich-rounded-webfont.eot');
    src: url('ostrich-rounded-webfont.eot?#iefix') format('embedded-opentype'),
         url('ostrich-rounded-webfont.woff') format('woff'),
         url('ostrich-rounded-webfont.ttf') format('truetype'),
         url('ostrich-rounded-webfont.svg#OstrichSansRoundedMedium') format('svg');
    font-weight: normal;
    font-style: normal;

}

@font-face {
    font-family: 'OstrichSansDashedMedium';
    src: url('ostrich-dashed-webfont.eot');
    src: url('ostrich-dashed-webfont.eot?#iefix') format('embedded-opentype'),
         url('ostrich-dashed-webfont.woff') format('woff'),
         url('ostrich-dashed-webfont.ttf') format('truetype'),
         url('ostrich-dashed-webfont.svg#OstrichSansDashedMedium') format('svg');
    font-weight: normal;
    font-style: normal;

}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
null

#### Original name
Mycena arata Berk.

### Remarks
null


text:
package com.github.bernd.samsa.utils;

import com.github.bernd.samsa.OffsetMapException;
import com.github.bernd.samsa.SamsaStorageException;
import com.google.common.util.concurrent.Uninterruptibles;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

public abstract class ShutdownableThread extends Thread {
    private static final Logger LOG = LoggerFactory.getLogger(ShutdownableThread.class);

    private final AtomicBoolean isRunning = new AtomicBoolean(true);
    private final CountDownLatch shutdownLatch = new CountDownLatch(1);
    private final boolean isInterruptible;

    public ShutdownableThread(final String name) {
        this(name, true);
    }

    public ShutdownableThread(final String name, final boolean isInterruptible) {
        super(name);
        this.isInterruptible = isInterruptible;

        setDaemon(false);
    }

    public void shutdown() throws InterruptedException {
        initiateShutdown();
        awaitShutdown();
    }

    public boolean initiateShutdown() {
        if (isRunning.compareAndSet(true, false)) {
            LOG.info("Shutting down");
            isRunning.set(false);
            if (isInterruptible) {
                interrupt();
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * After calling initiateShutdown(), use this API to wait until the shutdown is complete
     */
    public void awaitShutdown() {
        Uninterruptibles.awaitUninterruptibly(shutdownLatch);
        LOG.info("Shutdown completed");
    }

    public abstract void doWork() throws SamsaStorageException, IOException, OffsetMapException;

    @Override
    public void run() {
        LOG.info("Starting ");
        try {
            while (isRunning.get()) {
                doWork();
            }
        } catch (Throwable e) {
            if (isRunning.get()) {
                LOG.error("Error due to ", e);
            }
        }
        shutdownLatch.countDown();
        LOG.info("Stopped ");
    }

    public AtomicBoolean getIsRunning() {
        return isRunning;
    }
}


text:
using System.ServiceModel;

namespace CommunicationLibrary
{
    /// <summary>
    /// ServiceContract implemented by the clients.
    /// It's a secondary channel used for testing purpose
    /// </summary>
    /// TODO: used only for DS4ToolService, delete it
    [ServiceContract(CallbackContract = typeof(IPushService))]
    public interface ISendService
    {
        /// <summary>
        /// Send message to the service
        /// </summary>
        [OperationContract]
        void SendCommand(ControllerContract param);
    }

    /// <summary>
    /// ServiceContract implemented by the service.
    /// It's a secondary channel used only for testing purpose
    /// </summary>
    /// TODO: used only for DS4ToolService, delete it
    [ServiceContract]
    public interface IPushService
    {
        /// <summary>
        /// Send message to the clients
        /// </summary>
        [OperationContract(IsOneWay = true)]
        void PushCommand(ControllerContract param);
    }
}


text:
FizzBuzz
========

FizzBuzz question