{address: "BASE32", definition: [...], signers: {...}}
164056
function handleNewSharedAddress(body, callbacks){
	if (!ValidationUtils.isArrayOfLength(body.definition, 2))
		return callbacks.ifError("invalid definition");
	if (typeof body.signers !== "object" || Object.keys(body.signers).length === 0)
		return callbacks.ifError("invalid signers");
	if (body.address !== objectHash.getChash160(body.definition))
		return callbacks.ifError("definition doesn't match its c-hash");
	for (var signing_path in body.signers){
		var signerInfo = body.signers[signing_path];
		if (signerInfo.address && !ValidationUtils.isValidAddress(signerInfo.address))
			return callbacks.ifError("invalid member address: "+signerInfo.address);
	}
	determineIfIncludesMe(body.signers, function(err){
		if (err)
			return callbacks.ifError(err);
		validateAddressDefinition(body.definition, function(err){
			if (err)
				return callbacks.ifError(err);
			addNewSharedAddress(body.address, body.definition, body.signers, body.forwarded, callbacks.ifOk);
		});
	});
}
917378
function determineIfIncludesMe(assocSignersByPath, handleResult){
	var assocMemberAddresses = {};
	for (var signing_path in assocSignersByPath){
		var signerInfo = assocSignersByPath[signing_path];
	//	if (signerInfo.device_address === device.getMyDeviceAddress())
		if (signerInfo.address)
			assocMemberAddresses[signerInfo.address] = true;
	}
	var arrMemberAddresses = Object.keys(assocMemberAddresses);
	if (arrMemberAddresses.length === 0)
		return handleResult("no member addresses?");
	db.query(
		"SELECT address FROM my_addresses WHERE address IN(?) UNION SELECT shared_address AS address FROM shared_addresses WHERE shared_address IN(?)", 
		[arrMemberAddresses, arrMemberAddresses],
		function(rows){
		//	handleResult(rows.length === arrMyMemberAddresses.length ? null : "Some of my member addresses not found");
			handleResult(rows.length > 0 ? null : "I am not a member of this shared address");
		}
	);
}
777193
def signing_base(self, request, consumer, token):
        """"""
        sig = '%s&' % escape(consumer.secret)
        if token:
            sig = sig + escape(token.secret)
        return sig, sig
393182
function (input, signature, b64safeKey, alg) {
  var key = new Buffer( b64url.b64( b64safeKey ), 'base64' )
  var hmac = crypto.createHmac( alg, key ).update( input )
  var inputSignature = b64url.safe( hmac.digest( 'base64' ) )
  return (inputSignature === signature)
}
544442
function signSubscription () {
    var to_sign = args.sid + ':' + args.channel + '.' + args.resource +
                  ':ttl=' + args.ttl + ':read=' + args.read +
                  ':write=' + args.write

    if (self.bbt.userinfo.userid) {
      to_sign = to_sign + ':userid=' + self.bbt.userinfo.userid
    }

    var signature = crypto.createHmac('sha1', self.bbt.transport.secretKey)
    .update(to_sign)
    .digest('base64')

    var auth = {
      auth: self.bbt.transport.key + ':' + signature
    }

    if (self.bbt.userinfo.userid) {
      auth.userid = self.bbt.userinfo.userid
    }

    return auth
  }
352309
function(t) {
    return {
      id: t.identifier,
      y: t.clientY,
      x: t.clientX,
    };
  }
719179
def onelineaddress(self, address, **kwargs):
        '''
        '''
        fields = {
            'address': address,
        }

        return self._fetch('onelineaddress', fields, **kwargs)
787787
function validateAddressDefinition(arrDefinition, handleResult){
	var objFakeUnit = {authors: []};
	var objFakeValidationState = {last_ball_mci: MAX_INT32, bAllowUnresolvedInnerDefinitions: true};
	Definition.validateDefinition(db, arrDefinition, objFakeUnit, objFakeValidationState, false, function(err){
		if (err)
			return handleResult(err);
		handleResult();
	});
}
809522
def _sign(self, data):
        

        # Python2/3 urlencode aren't good enough for this task.
        params = "&".join(
            "=".join((key, cs_encode(value)))
            for key, value in sorted(data.items())
        )

        digest = hmac.new(
            self.secret.encode('utf-8'),
            msg=params.lower().encode('utf-8'),
            digestmod=hashlib.sha1).digest()

        return base64.b64encode(digest).decode('utf-8').strip()
163706
def derivesha256address(self):
        
        pkbin = unhexlify(repr(self._pubkey))
        addressbin = ripemd160(hexlify(hashlib.sha256(pkbin).digest()))
        return Base58(hexlify(addressbin).decode('ascii'))
703533
private int matchAddress(Matcher matcher) {
        int addr = 0;
        for (int i = 1; i <= 4; ++i) {
            int n = (rangeCheck(Integer.parseInt(matcher.group(i)), 0, 255));
            addr |= ((n & 0xff) << 8 * (4 - i));
        }
        return addr;
    }
252052
def address(self):
        '''
        
        '''
        return self.API.replace(
            'http://{}:{}'.format(
                self._bridge.hostname,
                self._bridge.port
            ), ''
        )
1222358
function Address(domMap, formObj, addressID, match) {
		// PRIVATE MEMBERS //

		var self = this; // Pointer to self so that internal functions can reference its parent
		var fields; // Data values and references to DOM elements
		var id; // An ID by which to classify this address on the DOM

		var state = "accepted"; // Can be: "accepted" or "changed"
		// Example of a field:  street: { value: "123 main", dom: DOMElement, undo: "123 mai"}
		// Some of the above fields will only be mapped manually, not automatically.

		// Private method that actually changes the address. The keepState parameter is
		// used by the results of verification after an address is chosen; (or an "undo"
		// on a freeform address), otherwise an infinite loop of requests is executed
		// because the address keeps changing! (Set "suppressAutoVerify" to true when coming from the "Undo" link)
		var doSet = function (key, value, updateDomElement, keepState, sourceEvent, suppressAutoVerify) {
			if (!arrayContains(acceptableFields, key) || !domMap[key]) { // Skip "id" and other unacceptable fields, also skip fields that weren't included in mapping
				return false;
			}

			if (!fields[key])
				fields[key] = {};

			if (typeof fields[key].dom !== "undefined" && fields[key].dom.tagName === "SELECT" && key !== "administrative_area" && fields[key].dom.selectedIndex >= 0) {
				value = fields[key].dom[fields[key].dom.selectedIndex].text.replace(/<|>/g, "");
			} else {
				value = value.replace(/<|>/g, ""); // prevents script injection attacks (< and > aren't in addresses, anyway)
			}

			var differentVal = fields[key].value != value;

			fields[key].undo = fields[key].value || "";
			fields[key].value = value;

			if (fields[key].dom && updateDomElement) {
				if (fields[key].dom.tagName === "INPUT") {
					$(fields[key].dom).val(value);
				} else if (fields[key].dom.tagName === "SELECT" && key === "administrative_area" && self.isDomestic()) {
					var selectedVal = "";
					$(fields[key].dom).find("option").each(function () {
						if ($(this).text().toUpperCase() === value) {
							selectedVal = $(this).val();
							return false;
						} else {
							for (var stateName in allStatesByName) {
								if (allStatesByName[stateName] === value && stateName === $(this).text().toUpperCase()) {
									selectedVal = $(this).val();
									return false;
								}
							}
						}
					});
					$(fields[key].dom).val(selectedVal);
				}
			}

			var eventMeta = {
				sourceEvent: sourceEvent, // may be undefined
				field: key,
				address: self,
				value: value,
				suppressAutoVerification: suppressAutoVerify || false
			};

			if (differentVal && !keepState) {
				ui.unmarkAsValid(self);
				var uiTag = config.ui && config.smartyTag ? $(".smarty-ui .smarty-tag.smarty-addr-" + id) : undefined;
				if (config.target.indexOf("US") >= 0 && config.target.indexOf("INTERNATIONAL") < 0) {
					if (self.isDomestic()) {
						if (uiTag && !uiTag.is(":visible"))
							uiTag.show(); // Show checkmark tag if address is in US
						self.unaccept();
						trigger("AddressChanged", eventMeta);
					} else {
						if (uiTag && uiTag.is(":visible"))
							uiTag.hide(); // Hide checkmark tag if address is non-US
						self.accept({
							address: self
						}, false);
					}
				} else if (config.target.indexOf("INTERNATIONAL") >= 0 && config.target.indexOf("US") < 0) {
					if (uiTag && !uiTag.is(":visible"))
						uiTag.show(); // Show checkmark tag if address is in US
					self.unaccept();
					trigger("AddressChanged", eventMeta);
				} else if (config.target.indexOf("US") >= 0 && config.target.indexOf("INTERNATIONAL") >= 0) {
					if (uiTag && !uiTag.is(":visible"))
						uiTag.show(); // Show checkmark tag if address is in US
					self.unaccept();
					trigger("AddressChanged", eventMeta);
				}
			}

			return true;
		};

		// PUBLIC MEMBERS //

		this.form = formObj; // Reference to the parent form object (NOT THE DOM ELEMENT)
		this.match = match; // Determines how matches are made and what kind of results are returned.
		this.verifyCount = 0; // Number of times this address was submitted for verification
		this.lastField; // The last field found (last to appear in the DOM) during mapping, or the order given
		this.active = true; // If true, verify the address. If false, pass-thru entirely.
		this.lastStreetInput = ""; // Used by autocomplete to detect changes

		// Constructor-esque functionality (save the fields in this address object)
		this.load = function (domMap, addressID) {
			fields = {};
			id = addressID ? addressID.replace(/[^a-z0-9_\-]/ig, "") : randomInt(1, 99999); // Strips non-selector-friendly characters

			if (typeof domMap === "object") { // can be an actual map to DOM elements or just field/value data
				// Find the last field likely to appear on the DOM (used for UI attachments)
				this.lastField = domMap[Object.keys(domMap)[Object.keys(domMap).length - 1]];

				var isEmpty = true; // Whether the address has data in it (pre-populated) -- first assume it is empty.

				for (var prop in domMap) {
					if (domMap.hasOwnProperty(prop)) {
						if (!arrayContains(acceptableFields, prop)) // Skip "id" and any other unacceptable field
							continue;

						if (typeof domMap[prop] == "object" && domMap[prop].getBoundingClientRect().top > this.lastField.getBoundingClientRect().top) {
							this.lastField = domMap[prop];
						}

						var elem, val, elemArray, isData;
						try {
							elem = $(domMap[prop]);
							elemArray = elem.toArray();
							isData = elemArray ? elemArray.length == 0 : false;
						} catch (e) {
							isData = true;
						}

						if (isData) // Didn't match an HTML element, so treat it as an address string ("street1" data) instead
							val = domMap[prop] || "";
						else
							val = elem.val() || "";

						fields[prop] = {};
						fields[prop].value = val;
						fields[prop].undo = val;

						if (!isData) {
							if (config.debug) {
								$(elem).addClass("smarty-debug-input");
								elem.attr("placeholder", prop + ":" + id);
							}
							fields[prop].dom = domMap[prop];
						}

						// This has to be passed in at bind-time; they cannot be obtained at run-time
						var data = {
							address: this,
							field: prop,
							value: val
						};

						// Capture the element that is clicked on so we know whether or not to close the autocomplete UI
						// (http://stackoverflow.com/a/11544766/4462191)
						$(document).mousedown(function (e) {
							// The latest element clicked
							clicky = $(e.target);
						});

						// when "clicky == null" on blur, we know it was not caused by a click
						// but maybe by pressing the tab key
						$(document).mouseup(function (e) {
							clicky = null;
						});

						$(document).keydown(function (e) {
							typey = $(e.target);
						});

						$(document).keyup(function (e) {
							typey = null;
						});

						// Bind the DOM element to needed events, passing in the data above
						// NOTE: When the user types a street, city, and state, then hits Enter without leaving
						// the state field, this change() event fires before the form is submitted, and if autoVerify is
						// on, the verification will not invoke form submit, because it didn't come from a form submit.
						// This is known behavior and is actually proper functioning in this uncommon edge case.
						!isData && $(domMap[prop]).change(data, actionsOnChange);
					}
				}

				var address = this;
				$(domMap.address1, domMap.freeform).blur(function () {
					ui.hideAutocomplete(address.id());
				});

				state = "changed";
			}
		};

		// Run the "constructor" to load up the address
		this.load(domMap, addressID);

		this.set = function (key, value, updateDomElement, keepState, sourceEvent, suppressAutoVerify) {
			if (typeof value !== "undefined") {
				if (typeof key === "string" && arguments.length >= 2)
					return doSet(key, value, updateDomElement, keepState, sourceEvent, suppressAutoVerify);
				else if (typeof key === "object") {
					var successful = true;
					for (var prop in key) {
						if (key.hasOwnProperty(prop)) {
							successful = doSet(prop, key[prop], updateDomElement, keepState, sourceEvent, suppressAutoVerify) ? successful : false;
						}
					}
					return successful;
				}
			}
		};

		this.replaceWith = function (resp, updateDomElement, e) {
			// Given the response from an API request associated with this address,
			// replace the values in the address... and if updateDomElement is true,
			// then change the values in the fields on the page accordingly.

			if (typeof resp === "array" && resp.length > 0)
				resp = resp[0];

			// Sent via US api
			if (typeof resp.candidate_index != "undefined") {
				if (self.isFreeform()) {
					var singleLineAddr = (resp.addressee ? resp.addressee + ", " : "") +
						(resp.delivery_line_1 ? resp.delivery_line_1 + ", " : "") +
						(resp.delivery_line_2 ? resp.delivery_line_2 + ", " : "") +
						(resp.components.urbanization ? resp.components.urbanization + ", " : "") +
						(resp.last_line ? resp.last_line : "");
					var fieldKey = "freeform";
					if (fields.address1) {
						fieldKey = "address1";
					}
					self.set(fieldKey, singleLineAddr, updateDomElement, true, e, false);
				} else {
					self.set("organization", resp.addressee, updateDomElement, true, e, false);
					self.set("address1", resp.delivery_line_1, updateDomElement, true, e, false);
					if (resp.delivery_line_2)
						self.set("address2", resp.delivery_line_2, updateDomElement, true, e, false); // Rarely used; must otherwise be blank.
					else
						self.set("address2", "", updateDomElement, true, e, false);
					self.set("locality", resp.components.city_name, updateDomElement, true, e, false);
					self.set("administrative_area", resp.components.state_abbreviation, updateDomElement, true, e, false);
					self.set("postal_code", resp.components.zipcode + "-" + resp.components.plus4_code, updateDomElement, true, e, false);
				}
				self.set("address3", "", updateDomElement, true, e, false);
				self.set("address4", "", updateDomElement, true, e, false);
				self.set("country", "USA", updateDomElement, true, e, false);
			} else { // Sent via international API
				if (self.isFreeform()) {
					var singleLineAddr = (resp.organization ? resp.organization + ", " : "") +
						(resp.address1 ? resp.address1 : "") +
						(resp.address2 ? ", " + resp.address2 : "") +
						(resp.address3 ? ", " + resp.address3 : "") +
						(resp.address4 ? ", " + resp.address4 : "") +
						(resp.address5 ? ", " + resp.address5 : "") +
						(resp.address6 ? ", " + resp.address6 : "") +
						(resp.address7 ? ", " + resp.address7 : "") +
						(resp.address8 ? ", " + resp.address8 : "") +
						(resp.address9 ? ", " + resp.address9 : "") +
						(resp.address10 ? ", " + resp.address10 : "") +
						(resp.address11 ? ", " + resp.address11 : "") +
						(resp.address12 ? ", " + resp.address12 : "");
					var countryLine = resp.components.country_iso_3 ? resp.components.country_iso_3 : "";
					self.set("freeform", singleLineAddr, updateDomElement, true, e, false);
					self.set("country", countryLine, updateDomElement, true, e, false);
				} else {
					self.set("organization", resp.organization, updateDomElement, true, e, false);
					self.set("locality", resp.components.locality, updateDomElement, true, e, false);
					self.set("administrative_area", resp.components.administrative_area, updateDomElement, true, e, false);
					if (resp.components.postal_code_short) {
						var fullPostalCode = resp.components.postal_code_short;
						if (resp.components.postal_code_extra)
							fullPostalCode = fullPostalCode + "-" + resp.components.postal_code_extra;
						self.set("postal_code", fullPostalCode, updateDomElement, true, e, false);
					}
					removeComponentsFromAddressLines(resp);
					if (this.getDomFields().address4) {
						self.set("address1", resp.address1, updateDomElement, true, e, false);
						self.set("address2", resp.address2, updateDomElement, true, e, false);
						self.set("address3", resp.address3, updateDomElement, true, e, false);

						var addressLine4 = resp.address4;
						addressLine4 = addAddressLine(addressLine4, resp.address5, resp.address6);
						addressLine4 = addAddressLine(addressLine4, resp.address6, resp.address7);
						addressLine4 = addAddressLine(addressLine4, resp.address7, resp.address8);
						addressLine4 = addAddressLine(addressLine4, resp.address8, resp.address9);
						addressLine4 = addAddressLine(addressLine4, resp.address9, resp.address10);
						addressLine4 = addAddressLine(addressLine4, resp.address10, resp.address11);
						addressLine4 = addAddressLine(addressLine4, resp.address11, resp.address12);
						self.set("address4", addressLine4, updateDomElement, true, e, false);
					} else if (this.getDomFields().address3) {
						self.set("address1", resp.address1, updateDomElement, true, e, false);
						self.set("address2", resp.address2, updateDomElement, true, e, false);

						var addressLine3 = resp.address3;
						addressLine3 = addAddressLine(addressLine3, resp.address4, resp.address5);
						addressLine3 = addAddressLine(addressLine3, resp.address5, resp.address6);
						addressLine3 = addAddressLine(addressLine3, resp.address6, resp.address7);
						addressLine3 = addAddressLine(addressLine3, resp.address7, resp.address8);
						addressLine3 = addAddressLine(addressLine3, resp.address8, resp.address9);
						addressLine3 = addAddressLine(addressLine3, resp.address9, resp.address10);
						addressLine3 = addAddressLine(addressLine3, resp.address10, resp.address11);
						addressLine3 = addAddressLine(addressLine3, resp.address11, resp.address12);
						self.set("address3", addressLine3, updateDomElement, true, e, false);
					} else if (this.getDomFields().address2) {
						self.set("address1", resp.address1, updateDomElement, true, e, false);

						var addressLine2 = resp.address2;
						addressLine2 = addAddressLine(addressLine2, resp.address3, resp.address4);
						addressLine2 = addAddressLine(addressLine2, resp.address4, resp.address5);
						addressLine2 = addAddressLine(addressLine2, resp.address5, resp.address6);
						addressLine2 = addAddressLine(addressLine2, resp.address6, resp.address7);
						addressLine2 = addAddressLine(addressLine2, resp.address7, resp.address8);
						addressLine2 = addAddressLine(addressLine2, resp.address8, resp.address9);
						addressLine2 = addAddressLine(addressLine2, resp.address9, resp.address10);
						addressLine2 = addAddressLine(addressLine2, resp.address10, resp.address11);
						addressLine2 = addAddressLine(addressLine2, resp.address11, resp.address12);
						self.set("address2", addressLine2, updateDomElement, true, e, false);
					} else if (this.getDomFields().address1) {
						var addressLine1 = resp.address1;
						addressLine1 = addAddressLine(addressLine1, resp.address2, resp.address3);
						addressLine1 = addAddressLine(addressLine1, resp.address3, resp.address4);
						addressLine1 = addAddressLine(addressLine1, resp.address4, resp.address5);
						addressLine1 = addAddressLine(addressLine1, resp.address5, resp.address6);
						addressLine1 = addAddressLine(addressLine1, resp.address6, resp.address7);
						addressLine1 = addAddressLine(addressLine1, resp.address7, resp.address8);
						addressLine1 = addAddressLine(addressLine1, resp.address8, resp.address9);
						addressLine1 = addAddressLine(addressLine1, resp.address9, resp.address10);
						addressLine1 = addAddressLine(addressLine1, resp.address10, resp.address11);
						addressLine1 = addAddressLine(addressLine1, resp.address11, resp.address12);
						self.set("address1", addressLine1, updateDomElement, true, e, false);
					}
					self.set("country", resp.components.country_iso_3, updateDomElement, true, e, false);
				}
			}
		};

		var removeComponentFromAddressLine = function (addressComponent, componentName, addressLineComponent, resp) {
			if (addressComponent.indexOf(componentName) !== -1) {
				var regex = new RegExp(resp.components[componentName], "g");
				var newAddressLine = resp[addressLineComponent].replace(regex, "");
				resp[addressLineComponent] = newAddressLine;
			}
		};

		var removeExtraWhitespace = function (addressLineComponent, resp) {
			var addressLine = resp[addressLineComponent];

			removeLeadingWhitespace();
			removeTrailingWhitespace();
			replaceMultipleWhitespaceWithSingle();
			resp[addressLineComponent] = addressLine;

			function removeLeadingWhitespace() {
				addressLine = addressLine.replace(/^\s+/g, "");
			}

			function removeTrailingWhitespace() {
				addressLine = addressLine.replace(/\s+$/g, "");
			}

			function replaceMultipleWhitespaceWithSingle() {
				addressLine = addressLine.replace(/\s+/g, " ");
			}
		};

		var emptyLastNonEmptyAddressLine = function (resp) {
			for (var lineNumber = 12; lineNumber >= 1; lineNumber--) {
				var addressLineComponent = "address" + lineNumber;

				if (resp.hasOwnProperty(addressLineComponent) && resp[addressLineComponent] !== "") {
					resp[addressLineComponent] = "";
					return;
				}
			}
		};

		var removeComponentsFromAddressLines = function (resp) {
			if (resp.metadata.hasOwnProperty("address_format")) {
				var addressFormatLines = resp.metadata.address_format.split("|");

				for (var addressLineNumber in addressFormatLines) {
					var componentsToRemove = [
						"locality",
						"administrative_area",
						"postal_code",
						"country"
					];
					var addressComponent = addressFormatLines[addressLineNumber];
					var lineNumberAsInt = parseInt(addressLineNumber) + 1;
					var addressLineComponent = "address" + lineNumberAsInt;

					componentsToRemove.map(function (componentName) {
						removeComponentFromAddressLine(addressComponent, componentName, addressLineComponent, resp);
					});
					removeExtraWhitespace(addressLineComponent, resp);
				}
			} else {
				emptyLastNonEmptyAddressLine(resp);
			}
		};

		var addAddressLine = function (fullLine, addressLine, nextAddressLine) {
			if (typeof addressLine !== "undefined" && typeof nextAddressLine !== "undefined") {
				if (fullLine !== "") {
					fullLine += ", ";
				}
				fullLine += addressLine;
			}
			return fullLine;
		};

		this.corners = function (lastField) {
			var corners = {};

			if (!lastField) {
				for (var prop in fields) {
					if (fields.hasOwnProperty(prop)) {
						if (!fields[prop].dom || !$(fields[prop].dom).is(":visible"))
							continue;

						var dom = fields[prop].dom;
						var offset = $(dom).offset();
						offset.right = offset.left + $(dom).outerWidth(false);
						offset.bottom = offset.top + $(dom).outerHeight(false);

						corners.top = !corners.top ? offset.top : Math.min(corners.top, offset.top);
						corners.left = !corners.left ? offset.left : Math.min(corners.left, offset.left);
						corners.right = !corners.right ? offset.right : Math.max(corners.right, offset.right);
						corners.bottom = !corners.bottom ? offset.bottom : Math.max(corners.bottom, offset.bottom);
					}
				}
			} else {
				var jqDom = $(self.lastField);
				corners = jqDom.offset();
				corners.right = corners.left + jqDom.outerWidth(false);
				corners.bottom = corners.top + jqDom.outerHeight(false);
			}

			corners.width = corners.right - corners.left;
			corners.height = corners.bottom - corners.top;

			return corners;
		};

		this.verify = function (invoke, invokeFn) {
			// Invoke contains the element to "click" on once we're all done, or is a user-defined callback function (may also be undefined)
			if (!self.enoughInput()) {
				return trigger("AddressWasMissingInput", {
					address: self,
					invoke: invoke,
					invokeFn: invokeFn,
					response: new Response([])
				});
			}

			ui.disableFields(self);
			self.verifyCount++;
			var addrData = self.toRequestIntl();
			var credentials = config.token ? "auth-id=" + encodeURIComponent(config.key) + "&auth-token=" +
				encodeURIComponent(config.token) : "auth-id=" + encodeURIComponent(config.key);
			var requestUrl = config.requestUrlInternational;
			var headers = {};
			if (self.isDomestic() && config.target.indexOf("US") >= 0) {
				requestUrl = config.requestUrlUS;
				addrData = self.toRequestUS();
			}

			var agent = "&agent=" + encodeURIComponent("smartystreets (plugin:website@" + instance.version + ")");
			if (config.agent)
				agent += "&agent=" + encodeURIComponent(config.agent);

			var ajaxSettings = {
				url: requestUrl + "?" + credentials + agent,
				contentType: "jsonp",
				data: addrData,
				timeout: config.timeout
			};

			$.ajax($.extend({}, config.ajaxSettings, ajaxSettings))
				.done(function (response, statusText, xhr) {
					trigger("ResponseReceived", {
						address: self,
						response: new Response(response),
						invoke: invoke,
						invokeFn: invokeFn
					});
				})
				.fail(function (xhr, statusText) {
					var indexOfCountry = -1;
					if (xhr.responseText) {
						indexOfCountry = xhr.responseText.split("\n")[0].indexOf("country");
					}
					if (xhr.status === 422 && indexOfCountry > -1) {
						return trigger("CountryWasInvalid", {
							address: self,
							response: new Response([]),
							invoke: invoke,
							invokeFn: invokeFn
						});
					} else {
						trigger("RequestTimedOut", {
							address: self,
							status: statusText,
							invoke: invoke,
							invokeFn: invokeFn
						});
					}
					self.verifyCount--; // Address verification didn't actually work, so don't count it
				});

			// Remember, the above callbacks happen later and this function is
			// executed immediately afterward, probably before a response is received.
			trigger("RequestSubmitted", {
				address: self
			});
		};

		this.enoughInput = function () {
			// Checks for state dropdown
			var stateText;
			if (fields.administrative_area) {
				stateText = fields.administrative_area.value;
				if (fields.administrative_area.dom !== undefined && fields.administrative_area.dom.length !== undefined) {
					if (fields.administrative_area.dom.selectedIndex < 1)
						stateText = "";
					else
						stateText = fields.administrative_area.dom.options[fields.administrative_area.dom.selectedIndex].text;
				}
			}

			if (fields.country && !fields.country.value) {
				return false;
			}
			if (fields.freeform) {
				return fields.freeform.value;
			}
			if (fields.address1 && !fields.address1.value) {
				return false;
			}

			var postalCodeIsPresentAndHasValue = !!(fields.postal_code && fields.postal_code.value);
			var administrativeAreaIsPresentAndHasValue = !!(fields.administrative_area && stateText.length > 0);
			var localityIsPresentAndHasValue = !!(fields.locality && fields.locality.value);

			return postalCodeIsPresentAndHasValue || (localityIsPresentAndHasValue && administrativeAreaIsPresentAndHasValue);
		};

		this.toRequestIntl = function () {
			var obj = {};
			if (fields.hasOwnProperty("freeform") &&
				fields.hasOwnProperty("address1") &&
				fields.hasOwnProperty("locality") &&
				fields.hasOwnProperty("administrative_area") &&
				fields.hasOwnProperty("postal_code")) {
				delete fields.address1;
				delete fields.locality;
				delete fields.administrative_area;
				delete fields.postal_code;
			}
			for (var key in fields) {
				if (fields.hasOwnProperty(key)) {
					var keyval = {};
					if (fields[key].dom && fields[key].dom.tagName === "SELECT" && fields[key].dom.selectedIndex >= 0) {
						keyval[key] = fields[key].dom[fields[key].dom.selectedIndex].text;
					} else {
						keyval[key] = fields[key].value.replace(/\r|\n/g, " "); // Line breaks to spaces
					}
					$.extend(obj, keyval);
				}
			}
			obj.geocode = config.geocode;
			return obj;
		};

		this.toRequestUS = function () {
			var obj = {};
			if (fields.address1 && fields.address1.dom && fields.address1.dom.value) {
				obj.street = fields.address1.dom.value;
			} else if (fields.address1 && fields.address1.value) { // Covers a special case where the user calls .verify on the instance
				obj.street = fields.address1.value;
			}
			if (fields.address2 && fields.address2.dom && fields.address2.dom.value) {
				obj.street2 = fields.address2.dom.value;
			}
			if (fields.address3 && fields.address3.dom && fields.address3.dom.value) {
				if (typeof obj.street2 === "undefined") {
					obj.street2 = fields.address3.dom.value;
				} else {
					obj.street2 = obj.street2 += ", " + fields.address3.dom.value;
				}
			}
			if (fields.address4 && fields.address4.dom && fields.address4.dom.value) {
				if (typeof obj.street2 === "undefined") {
					obj.street2 = fields.address4.dom.value;
				} else {
					obj.street2 = obj.street2 += ", " + fields.address4.dom.value;
				}
			}
			if (fields.locality && fields.locality.dom) {
				if (fields.locality.dom.tagName === "SELECT" && fields.locality.dom.selectedIndex >= 0) {
					obj.city = fields.locality.dom[fields.locality.dom.selectedIndex].text;
				} else {
					obj.city = fields.locality.dom.value;
				}
			}
			if (fields.administrative_area && fields.administrative_area.dom.value) {
				if (fields.administrative_area.dom.tagName === "SELECT" && fields.administrative_area.dom.selectedIndex >= 0) {
					obj.state = fields.administrative_area.dom[fields.administrative_area.dom.selectedIndex].text;
				} else {
					obj.state = fields.administrative_area.dom.value;
				}
			}
			if (fields.postal_code && fields.postal_code.dom.value) {
				obj.zipcode = fields.postal_code.dom.value;
			}
			if (fields.freeform && fields.freeform.dom.value) {
				obj.street = fields.freeform.dom.value;
			}
			if (typeof this.secondary !== "undefined") {
				obj.secondary = this.secondary;
				delete this.secondary;
			}
			if (typeof this.address1 !== "undefined") {
				obj.street = this.address1;
				delete this.address1;
				if (typeof this.zipcode !== "undefined") {
					obj.zipcode = this.zipcode;
					delete this.zipcode;
				}
				delete obj.freeform;
			}

			obj.match = this.match;
			obj.candidates = config.candidates;
			return obj;
		};

		function getStringOfPossibleDropdown(field) {
			if (field.dom) {
				if (field.dom.tagName !== "SELECT") {
					return field.dom.value + " ";
				} else if (field.dom.selectedIndex > 0) {
					return field.dom[field.dom.selectedIndex].text + " ";
				}
			}
			return "";
		}

		this.toString = function () {
			if (fields.freeform) {
				return (fields.freeform ? fields.freeform.value + " " : "") + (fields.country ? fields.country.value : "");
			} else {
				var addrString = (fields.address1 ? fields.address1.value + " " : "") + (fields.address2 ? fields.address2.value + " " : "") +
					(fields.address3 ? fields.address3.value + " " : "") + (fields.address4 ? fields.address4.value + " " : "") +
					(fields.locality ? fields.locality.value + " " : "");
				if (fields.administrative_area) {
					addrString += getStringOfPossibleDropdown(fields.administrative_area);
				}
				addrString += (fields.postal_code ? fields.postal_code.value + " " : "");
				if (fields.country) {
					addrString += getStringOfPossibleDropdown(fields.country);
				}
				return addrString;
			}
		};

		this.abort = function (event, keepAccept) {
			keepAccept = typeof keepAccept === "undefined" ? false : keepAccept;
			if (!keepAccept)
				self.unaccept();
			delete self.form.processing;
			return suppress(event);
		};

		// Based on the properties in "fields," determines if this is a single-line address
		this.isFreeform = function () {
			return fields.freeform;
		};

		this.get = function (key) {
			return fields[key] ? fields[key].value : null
		};

		this.undo = function (updateDomElement) {
			updateDomElement = typeof updateDomElement === "undefined" ? true : updateDomElement;
			for (var key in fields) {
				if (fields.hasOwnProperty(key)) {
					this.set(key, fields[key].undo, updateDomElement, false, undefined, true);
				}
			}
		};

		this.accept = function (data, showValid) {
			showValid = typeof showValid === "undefined" ? true : showValid;
			state = "accepted";
			ui.enableFields(self);
			if (showValid) // If user chooses original input or the request timed out, the address wasn't "verified"
				ui.markAsValid(self);
			trigger("AddressAccepted", data);
		};

		this.unaccept = function () {
			state = "changed";
			ui.unmarkAsValid(self);
			return self;
		};

		this.getUndoValue = function (key) {
			return fields[key].undo;
		};

		this.status = function () {
			return state;
		};

		this.getDomFields = function () {
			// Gets just the DOM elements for each field
			var obj = {};
			for (var prop in fields) {
				if (fields.hasOwnProperty(prop)) {
					var ext = {};
					ext[prop] = fields[prop].dom;
					$.extend(obj, ext);
				}
			}
			return obj;
		};

		this.hasDomFields = function () {
			for (var prop in fields) {
				if (fields.hasOwnProperty(prop) && fields[prop].dom) {
					return true;
				}
			}
		};

		this.isDomestic = function () {
			var countryValue = "";
			if (fields.country && fields.country.dom) {
				countryValue = $(fields.country.dom).val();
				var selectedOption = $(fields.country.dom).children(":selected");
				if (selectedOption.length > 0 && selectedOption.index() > 0)
					countryValue = selectedOption.text();
			}
			countryValue = countryValue.toUpperCase().replace(/\.|\s|\(|\)|\\|\/|-/g, "");
			var usa = ["", "0", "1", "US", "USA", "USOFA", "USOFAMERICA", "AMERICAN", // 1 is AmeriCommerce
				"UNITEDSTATES", "UNITEDSTATESAMERICA", "UNITEDSTATESOFAMERICA", "AMERICA",
				"840", "223", "AMERICAUNITEDSTATES", "AMERICAUS", "AMERICAUSA", "UNITEDSTATESUS",
				"AMERICANSAMOA", "AMERIKASĀMOA", "AMERIKASAMOA", "ASM",
				"MICRONESIA", "FEDERALSTATESOFMICRONESIA", "FEDERATEDSTATESOFMICRONESIA", "FSM",
				"GUAM", "GM",
				"MARSHALLISLANDS", "MHL",
				"NORTHERNMARIANAISLANDS", "NMP",
				"PALAU", "REPUBLICOFPALAU", "BELAU", "PLW",
				"PUERTORICO", "COMMONWEALTHOFPUERTORICO", "PRI",
				"UNITEDSTATESVIRGINISLANDS", "VIR"
			]; // 840 is ISO: 3166; and 223 is some shopping carts
			return arrayContains(usa, countryValue) || fields.country.value == "-1";
		};

		this.autocompleteVisible = function () {
			return config.ui && config.autocomplete && $(".smarty-autocomplete.smarty-addr-" + self.id()).is(":visible");
		};

		this.id = function () {
			return id;
		};
	}
1226435
function deriveWalletAddress(publicKey, type) {
  let keyBuffer = new Buffer(publicKey, 'hex');
  let firstHash = crypto.createHash('sha256').update(keyBuffer).digest();
  let secondHash = ripemd160(firstHash);
  let extendedHash = (type === 'issuer' ? '57' : '87') + secondHash.toString('hex');
  let base58Public = bs58check.encode(new Buffer(extendedHash, 'hex'));

  return base58Public;
}
1140259
function ObiCallerID() {
    this.fromRegex = /^INVITE[\S\s]*From:\s*"?([\w\s\.\+\?\$]*?)"?<sip:((.*)@)?(.*)>;.*/;
    this.cidRegex = /<7> \[SLIC\] CID to deliver: '([\w\s\.\+\?\$]*?)' (\d*).*/;
    this.cnams = {};
    this.lastSentTime = new Date();
    this.outlookImported = false;
    this.addressbookImported = false;
    this.lastGrowlName = "";
    this.lastGrowlNumber = "";
}
134499
function (params) {
  const oThis = this;

  params = params || {};
  oThis.erc20Address = params.erc20_address;
  oThis.address = params.address;
}
675523
function validateAuthentifiers(conn, address, this_asset, arrDefinition, objUnit, objValidationState, assocAuthentifiers, cb){
	
	function evaluate(arr, path, cb2){
		var op = arr[0];
		var args = arr[1];
		switch(op){
			case 'or':
				// ['or', [list of options]]
				var res = false;
				var index = -1;
				async.eachSeries(
					args,
					function(arg, cb3){
						index++;
						evaluate(arg, path+'.'+index, function(arg_res){
							res = res || arg_res;
							cb3(); // check all members, even if required minimum already found
							//res ? cb3("found") : cb3();
						});
					},
					function(){
						cb2(res);
					}
				);
				break;
				
			case 'and':
				// ['and', [list of requirements]]
				var res = true;
				var index = -1;
				async.eachSeries(
					args,
					function(arg, cb3){
						index++;
						evaluate(arg, path+'.'+index, function(arg_res){
							res = res && arg_res;
							cb3(); // check all members, even if required minimum already found
							//res ? cb3() : cb3("found");
						});
					},
					function(){
						cb2(res);
					}
				);
				break;
				
			case 'r of set':
				// ['r of set', {required: 2, set: [list of options]}]
				var count = 0;
				var index = -1;
				async.eachSeries(
					args.set,
					function(arg, cb3){
						index++;
						evaluate(arg, path+'.'+index, function(arg_res){
							if (arg_res)
								count++;
							cb3(); // check all members, even if required minimum already found, so that we don't allow invalid sig on unchecked path
							//(count < args.required) ? cb3() : cb3("found");
						});
					},
					function(){
						cb2(count >= args.required);
					}
				);
				break;
				
			case 'weighted and':
				// ['weighted and', {required: 15, set: [{value: boolean_expr, weight: 10}, {value: boolean_expr, weight: 20}]}]
				var weight = 0;
				var index = -1;
				async.eachSeries(
					args.set,
					function(arg, cb3){
						index++;
						evaluate(arg.value, path+'.'+index, function(arg_res){
							if (arg_res)
								weight += arg.weight;
							cb3(); // check all members, even if required minimum already found
							//(weight < args.required) ? cb3() : cb3("found");
						});
					},
					function(){
						cb2(weight >= args.required);
					}
				);
				break;
				
			case 'sig':
				// ['sig', {algo: 'secp256k1', pubkey: 'base64'}]
				//console.log(op, path);
				var signature = assocAuthentifiers[path];
				if (!signature)
					return cb2(false);
				arrUsedPaths.push(path);
				var algo = args.algo || 'secp256k1';
				if (algo === 'secp256k1'){
					if (objValidationState.bUnsigned && signature[0] === "-") // placeholder signature
						return cb2(true);
					var res = ecdsaSig.verify(objValidationState.unit_hash_to_sign, signature, args.pubkey);
					if (!res)
						fatal_error = "bad signature at path "+path;
					cb2(res);
				}
				break;
				
			case 'hash':
				// ['hash', {algo: 'sha256', hash: 'base64'}]
				if (!assocAuthentifiers[path])
					return cb2(false);
				arrUsedPaths.push(path);
				var algo = args.algo || 'sha256';
				if (algo === 'sha256'){
					var res = (args.hash === crypto.createHash("sha256").update(assocAuthentifiers[path], "utf8").digest("base64"));
					if (!res)
						fatal_error = "bad hash at path "+path;
					cb2(res);
				}
				break;
				
			case 'address':
				// ['address', 'BASE32']
				var other_address = args;
				storage.readDefinitionByAddress(conn, other_address, objValidationState.last_ball_mci, {
					ifFound: function(arrInnerAddressDefinition){
						evaluate(arrInnerAddressDefinition, path, cb2);
					},
					ifDefinitionNotFound: function(definition_chash){
						var arrDefiningAuthors = objUnit.authors.filter(function(author){
							return (author.address === other_address && author.definition && objectHash.getChash160(author.definition) === definition_chash);
						});
						if (arrDefiningAuthors.length === 0) // no definition in the current unit
							return cb2(false);
						if (arrDefiningAuthors.length > 1)
							throw Error("more than 1 address definition");
						var arrInnerAddressDefinition = arrDefiningAuthors[0].definition;
						evaluate(arrInnerAddressDefinition, path, cb2);
					}
				});
				break;
				
			case 'definition template':
				// ['definition template', ['unit', {param1: 'value1'}]]
				var unit = args[0];
				var params = args[1];
				conn.query(
					"SELECT payload FROM messages JOIN units USING(unit) \n\
					WHERE unit=? AND app='definition_template' AND main_chain_index<=? AND +sequence='good' AND is_stable=1",
					[unit, objValidationState.last_ball_mci],
					function(rows){
						if (rows.length !== 1)
							throw Error("not 1 template");
						var template = rows[0].payload;
						var arrTemplate = JSON.parse(template);
						var arrFilledTemplate = replaceInTemplate(arrTemplate, params);
						evaluate(arrFilledTemplate, path, cb2);
					}
				);
				break;
				
			case 'seen address':
				// ['seen address', 'BASE32']
				var seen_address = args;
				conn.query(
					"SELECT 1 FROM unit_authors CROSS JOIN units USING(unit) \n\
					WHERE address=? AND main_chain_index<=? AND sequence='good' AND is_stable=1 \n\
					LIMIT 1",
					[seen_address, objValidationState.last_ball_mci],
					function(rows){
						cb2(rows.length > 0);
					}
				);
				break;
				
			case 'seen definition change':
				// ['seen definition change', ['BASE32', 'BASE32']]
				var changed_address = args[0];
				var new_definition_chash = args[1];
				if (changed_address === 'this address')
					changed_address = address;
				if (new_definition_chash === 'this address')
					new_definition_chash = address;
				var and_definition_chash = (new_definition_chash === 'any') ? '' : 'AND definition_chash='+db.escape(new_definition_chash);
				conn.query(
					"SELECT 1 FROM address_definition_changes CROSS JOIN units USING(unit) \n\
					WHERE address=? "+and_definition_chash+" AND main_chain_index<=? AND sequence='good' AND is_stable=1 \n\
					LIMIT 1",
					[changed_address, objValidationState.last_ball_mci],
					function(rows){
						cb2(rows.length > 0);
					}
				);
				break;
				
			case 'seen':
				// ['seen', {what: 'input', asset: 'asset or base', type: 'transfer'|'issue', amount_at_least: 123, amount_at_most: 123, amount: 123, address: 'BASE32'}]
				var filter = args;
				var sql = "SELECT 1 FROM "+filter.what+"s CROSS JOIN units USING(unit) \n\
					LEFT JOIN assets ON asset=assets.unit \n\
					WHERE main_chain_index<=? AND sequence='good' AND is_stable=1 AND (asset IS NULL OR is_private=0) ";
				var params = [objValidationState.last_ball_mci];
				if (filter.asset){
					if (filter.asset === 'base')
						sql += " AND asset IS NULL ";
					else{
						sql += " AND asset=? ";
						params.push(filter.asset);
					}
				}
				if (filter.type){
					sql += " AND type=? ";
					params.push(filter.type);
				}
				if (filter.address){
					sql += " AND address=? ";
					params.push((filter.address === 'this address') ? address : filter.address);
				}
				if (filter.what === 'output'){
					if (filter.amount_at_least){
						sql += " AND amount>=? ";
						params.push(filter.amount_at_least);
					}
					if (filter.amount_at_most){
						sql += " AND amount<=? ";
						params.push(filter.amount_at_most);
					}
					if (filter.amount){
						sql += " AND amount=? ";
						params.push(filter.amount);
					}
				}
				sql += " LIMIT 1";
				conn.query(sql, params, function(rows){
					cb2(rows.length > 0);
				});
				break;
				
			case 'attested':
				// ['attested', ['BASE32', ['BASE32']]]
				var attested_address = args[0];
				var arrAttestors = args[1];
				if (attested_address === 'this address')
					attested_address = address;
				storage.filterAttestedAddresses(
					conn, {arrAttestorAddresses: arrAttestors}, objValidationState.last_ball_mci, [attested_address], function(arrFilteredAddresses){
						cb2(arrFilteredAddresses.length > 0);
					}
				);
				break;
				
			case 'cosigned by':
				// ['cosigned by', 'BASE32']
				var cosigner_address = args;
				var arrAuthorAddresses = objUnit.authors.map(function(author){ return author.address; });
				console.log(op+" "+arrAuthorAddresses.indexOf(cosigner_address));
				cb2(arrAuthorAddresses.indexOf(cosigner_address) >= 0);
				break;
				
			case 'not':
				// useful for conditions such as: after timestamp but there's still no searched value in datafeed
				// sig, hash, and address cannot be negated
				evaluate(args, path, function(not_res){
					cb2(!not_res);
				});
				break;
				
			case 'in data feed':
				// ['in data feed', [['BASE32'], 'data feed name', '=', 'expected value']]
				var arrAddresses = args[0];
				var feed_name = args[1];
				var relation = args[2];
				var value = args[3];
				var min_mci = args[4] || 0;
				var value_condition;
				var index;
				var params = [arrAddresses, feed_name];
				if (typeof value === "string"){
					index = 'byNameStringValue';
					var isNumber = /^-?\d+\.?\d*$/.test(value);
					if (isNumber){
						var bForceNumericComparison = (['>','>=','<','<='].indexOf(relation) >= 0);
						var plus_0 = bForceNumericComparison ? '+0' : '';
						value_condition = '(value'+plus_0+relation+value+' OR int_value'+relation+value+')';
					//	params.push(value, value);
					}
					else{
						value_condition = 'value'+relation+'?';
						params.push(value);
					}
				}
				else{
					index = 'byNameIntValue';
					value_condition = 'int_value'+relation+'?';
					params.push(value);
				}
				params.push(objValidationState.last_ball_mci, min_mci);
				conn.query(
					"SELECT 1 FROM data_feeds "+db.forceIndex(index)+" CROSS JOIN units USING(unit) CROSS JOIN unit_authors USING(unit) \n\
					WHERE address IN(?) AND feed_name=? AND "+value_condition+" \n\
						AND main_chain_index<=? AND main_chain_index>=? AND sequence='good' AND is_stable=1 LIMIT 1",
					params,
					function(rows){
						console.log(op+" "+feed_name+" "+rows.length);
						cb2(rows.length > 0);
					}
				);
				break;
				
			case 'in merkle':
				// ['in merkle', [['BASE32'], 'data feed name', 'expected value']]
				if (!assocAuthentifiers[path])
					return cb2(false);
				arrUsedPaths.push(path);
				var arrAddresses = args[0];
				var feed_name = args[1];
				var element = args[2];
				var min_mci = args[3] || 0;
				var serialized_proof = assocAuthentifiers[path];
				var proof = merkle.deserializeMerkleProof(serialized_proof);
				if (!merkle.verifyMerkleProof(element, proof)){
					fatal_error = "bad merkle proof at path "+path;
					return cb2(false);
				}
				conn.query(
					"SELECT 1 FROM data_feeds CROSS JOIN units USING(unit) JOIN unit_authors USING(unit) \n\
					WHERE address IN(?) AND feed_name=? AND value=? AND main_chain_index<=? AND main_chain_index>=? AND sequence='good' AND is_stable=1 \n\
					LIMIT 1",
					[arrAddresses, feed_name, proof.root, objValidationState.last_ball_mci, min_mci],
					function(rows){
						if (rows.length === 0)
							fatal_error = "merkle proof at path "+path+" not found";
						cb2(rows.length > 0);
					}
				);
				break;
				
			case 'timestamp':
				var relation = args[0];
				var timestamp = args[1];
				switch(relation){
					case '>': return cb2(objValidationState.last_ball_timestamp > timestamp);
					case '>=': return cb2(objValidationState.last_ball_timestamp >= timestamp);
					case '<': return cb2(objValidationState.last_ball_timestamp < timestamp);
					case '<=': return cb2(objValidationState.last_ball_timestamp <= timestamp);
					case '=': return cb2(objValidationState.last_ball_timestamp === timestamp);
					case '!=': return cb2(objValidationState.last_ball_timestamp !== timestamp);
					default: throw Error('unknown relation in mci: '+relation);
				}
				break;
				
			case 'mci':
				var relation = args[0];
				var mci = args[1];
				switch(relation){
					case '>': return cb2(objValidationState.last_ball_mci > mci);
					case '>=': return cb2(objValidationState.last_ball_mci >= mci);
					case '<': return cb2(objValidationState.last_ball_mci < mci);
					case '<=': return cb2(objValidationState.last_ball_mci <= mci);
					case '=': return cb2(objValidationState.last_ball_mci === mci);
					case '!=': return cb2(objValidationState.last_ball_mci !== mci);
					default: throw Error('unknown relation in mci: '+relation);
				}
				break;
				
			case 'age':
				var relation = args[0];
				var age = args[1];
				augmentMessagesAndContinue(function(){
					var arrSrcUnits = [];
					for (var i=0; i<objValidationState.arrAugmentedMessages.length; i++){
						var message = objValidationState.arrAugmentedMessages[i];
						if (message.app !== 'payment' || !message.payload)
							continue;
						var inputs = message.payload.inputs;
						for (var j=0; j<inputs.length; j++){
							var input = inputs[j];
							if (input.type !== 'transfer') // assume age is satisfied for issue, headers commission, and witnessing commission
								continue;
							if (!input.address) // augment should add it
								throw Error('no input address');
							if (input.address === address && arrSrcUnits.indexOf(input.unit) === -1)
								arrSrcUnits.push(input.unit);
						}
					}
					if (arrSrcUnits.length === 0) // not spending anything from our address
						return cb2(false);
					conn.query(
						"SELECT 1 FROM units \n\
						WHERE unit IN(?) AND ?"+relation+"main_chain_index AND main_chain_index<=? AND +sequence='good' AND is_stable=1",
						[arrSrcUnits, objValidationState.last_ball_mci - age, objValidationState.last_ball_mci],
						function(rows){
							var bSatisfies = (rows.length === arrSrcUnits.length);
							console.log(op+" "+bSatisfies);
							cb2(bSatisfies);
						}
					);
				});
				break;
				
			case 'has':
			case 'has one':
				// ['has', {what: 'input', asset: 'asset or base', type: 'transfer'|'issue', amount_at_least: 123, amount_at_most: 123, amount: 123, address: 'BASE32'}]
				// when an address is included (referenced from another address), "this address" refers to the outer address
				augmentMessagesAndEvaluateFilter(op, args, function(res){
					console.log(op+" "+res, args);
					cb2(res);
				});
				break;
				
			case 'has equal':
			case 'has one equal':
				// ['has equal', {equal_fields: ['address', 'amount'], search_criteria: [{what: 'output', asset: 'asset1', address: 'BASE32'}, {what: 'input', asset: 'asset2', type: 'issue', address: 'ANOTHERBASE32'}]}]
				augmentMessagesAndEvaluateFilter("has", args.search_criteria[0], function(res1, arrFirstObjects){
					if (!res1)
						return cb2(false);
					augmentMessagesAndEvaluateFilter("has", args.search_criteria[1], function(res2, arrSecondObjects){
						if (!res2)
							return cb2(false);
						var count_equal_pairs = 0;
						for (var i=0; i<arrFirstObjects.length; i++)
							for (var j=0; j<arrSecondObjects.length; j++)
								if (!args.equal_fields.some(function(field){ return (arrFirstObjects[i][field] !== arrSecondObjects[j][field]); }))
									count_equal_pairs++;
						if (count_equal_pairs === 0)
							return cb2(false);
						if (op === "has one equal" && count_equal_pairs === 1)
							return cb2(true);
						if (op === "has equal" && count_equal_pairs > 0)
							return cb2(true);
						cb2(false);
					});
				});
				break;
				
			case 'sum':
				// ['sum', {filter: {what: 'input', asset: 'asset or base', type: 'transfer'|'issue', address: 'BASE32'}, at_least: 123, at_most: 123, equals: 123}]
				augmentMessagesAndEvaluateFilter("has", args.filter, function(res, arrFoundObjects){
					var sum = 0;
					if (res)
						for (var i=0; i<arrFoundObjects.length; i++)
							sum += arrFoundObjects[i].amount;
					console.log("sum="+sum);
					if (typeof args.equals === "number" && sum === args.equals)
						return cb2(true);
					if (typeof args.at_least === "number" && sum < args.at_least)
						return cb2(false);
					if (typeof args.at_most === "number" && sum > args.at_most)
						return cb2(false);
					cb2(true);
				});
				break;
				
			case 'has definition change':
				// ['has definition change', ['BASE32', 'BASE32']]
				var changed_address = args[0];
				var new_definition_chash = args[1];
				if (changed_address === 'this address')
					changed_address = address;
				if (new_definition_chash === 'this address')
					new_definition_chash = address;
				cb2(objUnit.messages.some(function(message){
					if (message.app !== 'address_definition_change')
						return false;
					if (!message.payload)
						return false;
					if (new_definition_chash !== 'any' && message.payload.definition_chash !== new_definition_chash)
						return false;
					var payload_address = message.payload.address || objUnit.authors[0].address;
					return (payload_address === changed_address);
				}));
				break;
			
			case 'formula':
				var formula = args;
				augmentMessagesOrIgnore(formula, function (messages) {
					evalFormulaBB.evaluate(conn, formula, messages, objValidationState, address, function (result) {
						if (typeof result === 'boolean') {
							cb2(result);
						} else if (typeof result === 'string') {
							cb2(!!result);
						} else if (BigNumber.isBigNumber(result)) {
							cb2(!result.eq(0))
						} else {
							cb(false);
						}
					});
				});
				break;
		}
	}
	
	function augmentMessagesOrIgnore(formula, cb){
		if (objValidationState.arrAugmentedMessages || /input/.test(formula)){
			augmentMessagesAndContinue(function () {
				cb(objValidationState.arrAugmentedMessages);
			});
		}else{
			cb(objUnit.messages);
		}
	}
	
	function augmentMessagesAndContinue(next){
		if (!objValidationState.arrAugmentedMessages)
			augmentMessages(next);
		else
			next();
	}
	
	function augmentMessagesAndEvaluateFilter(op, filter, handleResult){
		function doEvaluateFilter(){
			//console.log("augmented: ", objValidationState.arrAugmentedMessages[0].payload);
			evaluateFilter(op, filter, handleResult);
		}
		if (!objValidationState.arrAugmentedMessages && filter.what === "input" && (filter.address || typeof filter.amount === "number" || typeof filter.amount_at_least === "number" || typeof filter.amount_at_most === "number"))
			augmentMessages(doEvaluateFilter);
		else
			doEvaluateFilter();
	}
	
	
	function evaluateFilter(op, filter, handleResult){
		var arrFoundObjects = [];
		for (var i=0; i<objUnit.messages.length; i++){
			var message = objUnit.messages[i];
			if (message.app !== "payment" || !message.payload) // we consider only public payments
				continue;
			var payload = message.payload;
			if (filter.asset){
				if (filter.asset === "base"){
					if (payload.asset)
						continue;
				}
				else if (filter.asset === "this asset"){
					if (payload.asset !== this_asset)
						continue;
				}
				else{
					if (payload.asset !== filter.asset)
						continue;
				}
			}
			if (filter.what === "input"){
				for (var j=0; j<payload.inputs.length; j++){
					var input = payload.inputs[j];
					if (input.type === "headers_commission" || input.type === "witnessing")
						continue;
					if (filter.type){
						var type = input.type || "transfer";
						if (type !== filter.type)
							continue;
					}
					var augmented_input = objValidationState.arrAugmentedMessages ? objValidationState.arrAugmentedMessages[i].payload.inputs[j] : null;
					if (filter.address){
						if (filter.address === 'this address'){
							if (augmented_input.address !== address)
								continue;
						}
						else if (filter.address === 'other address'){
							if (augmented_input.address === address)
								continue;
						}
						else { // normal address
							if (augmented_input.address !== filter.address)
								continue;
						}
					}
					if (filter.amount && augmented_input.amount !== filter.amount)
						continue;
					if (filter.amount_at_least && augmented_input.amount < filter.amount_at_least)
						continue;
					if (filter.amount_at_most && augmented_input.amount > filter.amount_at_most)
						continue;
					arrFoundObjects.push(augmented_input || input);
				}
			} // input
			else if (filter.what === "output"){
				for (var j=0; j<payload.outputs.length; j++){
					var output = payload.outputs[j];
					if (filter.address){
						if (filter.address === 'this address'){
							if (output.address !== address)
								continue;
						}
						else if (filter.address === 'other address'){
							if (output.address === address)
								continue;
						}
						else { // normal address
							if (output.address !== filter.address)
								continue;
						}
					}
					if (filter.amount && output.amount !== filter.amount)
						continue;
					if (filter.amount_at_least && output.amount < filter.amount_at_least)
						continue;
					if (filter.amount_at_most && output.amount > filter.amount_at_most)
						continue;
					arrFoundObjects.push(output);
				}
			} // output
		}
		if (arrFoundObjects.length === 0)
			return handleResult(false);
		if (op === "has one" && arrFoundObjects.length === 1)
			return handleResult(true);
		if (op === "has" && arrFoundObjects.length > 0)
			return handleResult(true, arrFoundObjects);
		handleResult(false);
	}

	
	function augmentMessages(onDone){
		console.log("augmenting");
		var arrAuthorAddresses = objUnit.authors.map(function(author){ return author.address; });
		objValidationState.arrAugmentedMessages = _.cloneDeep(objUnit.messages);
		async.eachSeries(
			objValidationState.arrAugmentedMessages,
			function(message, cb3){
				if (message.app !== 'payment' || !message.payload) // we are looking only for public payments
					return cb3();
				var payload = message.payload;
				if (!payload.inputs) // skip now, will choke when checking the message
					return cb3();
				console.log("augmenting inputs");
				async.eachSeries(
					payload.inputs,
					function(input, cb4){
						console.log("input", input);
						if (input.type === "issue"){
							if (!input.address)
								input.address = arrAuthorAddresses[0];
							cb4();
						}
						else if (!input.type){
							input.type = "transfer";
							conn.query(
								"SELECT amount, address FROM outputs WHERE unit=? AND message_index=? AND output_index=?",
								[input.unit, input.message_index, input.output_index],
								function(rows){
									if (rows.length === 1){
										console.log("src", rows[0]);
										input.amount = rows[0].amount;
										input.address = rows[0].address;
									} // else will choke when checking the message
									else
										console.log(rows.length+" src outputs found");
									cb4();
								}
							);
						}
						else // ignore headers commissions and witnessing
							cb4();
					},
					cb3
				);
			},
			onDone
		);
	}
	
	var bAssetCondition = (assocAuthentifiers === null);
	if (bAssetCondition && address || !bAssetCondition && this_asset)
		throw Error("incompatible params");
	var arrAuthentifierPaths = bAssetCondition ? null : Object.keys(assocAuthentifiers);
	var fatal_error = null;
	var arrUsedPaths = [];
	
	// we need to re-validate the definition every time, not just the first time we see it, because:
	// 1. in case a referenced address was redefined, complexity might change and exceed the limit
	// 2. redefinition of a referenced address might introduce loops that will drive complexity to infinity
	// 3. if an inner address was redefined by keychange but the definition for the new keyset not supplied before last ball, the address
	// becomes temporarily unusable
	validateDefinition(conn, arrDefinition, objUnit, objValidationState, arrAuthentifierPaths, bAssetCondition, function(err){
		if (err)
			return cb(err);
		//console.log("eval def");
		evaluate(arrDefinition, 'r', function(res){
			if (fatal_error)
				return cb(fatal_error);
			if (!bAssetCondition && arrUsedPaths.length !== Object.keys(assocAuthentifiers).length)
				return cb("some authentifiers are not used, res="+res+", used="+arrUsedPaths+", passed="+JSON.stringify(assocAuthentifiers));
			cb(null, res);
		});
	});
}