function percentEncode( str ) {
	var byte;
	var out;
	var len;
	var buf;
	var i;

	// Convert to an array of octets using UTF-8 encoding (see https://tools.ietf.org/html/rfc3986#section-2.5):
	buf = utf16ToUTF8Array( str );

	// Encode the string...
	len = buf.length;
	out = '';
	for ( i = 0; i < len; i++ ) {
		byte = buf[ i ];
		if (
			// ASCII Digits:
			( byte >= ZERO && byte <= NINE ) ||

			// ASCII uppercase letters:
			( byte >= A && byte <= Z ) ||

			// ASCII lowercase letters:
			( byte >= a && byte <= z ) ||

			// ASCII unreserved characters (see https://tools.ietf.org/html/rfc3986#section-2.3):
			byte === HYPHEN ||
			byte === PERIOD ||
			byte === UNDERSCORE ||
			byte === TILDE
		) {
			out += str.charAt( i );
		} else {
			// Convert an octet to hexadecimal and uppercase according to the RFC (see https://tools.ietf.org/html/rfc3986#section-2.1):
			out += '%' + byte.toString( 16 ).toUpperCase();
		}
	}
	return out;
}
Percent-encodes a UTF-16 encoded string according to [RFC 3986][1].

[1]: https://tools.ietf.org/html/rfc3986#section-2.1

@param {string} str - string to percent-encode
@returns {string} percent-encoded string

@example
var str1 = 'Ladies + Gentlemen';

var str2 = percentEncode( str1 );
// returns 'Ladies%20%2B%20Gentlemen'