text: import * as tslib_1 from "tslib";
  import { isNode, URLBuilder } from "@azure/ms-rest-js";
  /**
   * Reserved URL characters must be properly escaped for Storage services like Blob or File.
   *
   * ## URL encode and escape strategy for JSv10 SDKs
   *
   * When customers pass a URL string into XXXURL classes constrcutor, the URL string may already be URL encoded or not.
   * But before sending to Azure Storage server, the URL must be encoded. However, it's hard for a SDK to guess whether the URL
   * string has been encoded or not. We have 2 potential strategies, and chose strategy two for the XXXURL constructors.
   *
   * ### Strategy One: Assume the customer URL string is not encoded, and always encode URL string in SDK.
   *
   * This is what legacy V2 SDK does, simple and works for most of the cases.
   * - When customer URL string is "http://account.blob.core.windows.net/con/b:",
   *   SDK will encode it to "http://account.blob.core.windows.net/con/b%3A" and send to server. A blob named "b:" will be created.
   * - When customer URL string is "http://account.blob.core.windows.net/con/b%3A",
   *   SDK will encode it to "http://account.blob.core.windows.net/con/b%253A" and send to server. A blob named "b%3A" will be created.
   *
   * But this strategy will make it not possible to create a blob with "?" in it's name. Because when customer URL string is
   * "http://account.blob.core.windows.net/con/blob?name", the "?name" will be treated as URL paramter instead of blob name.
   * If customer URL string is "http://account.blob.core.windows.net/con/blob%3Fname", a blob named "blob%3Fname" will be created.
   * V2 SDK doesn't have this issue because it doesn't allow customer pass in a full URL, it accepts a separate blob name and encodeURIComponent for it.
   * We cannot accept a SDK cannot create a blob name with "?". So we implement strategy two:
   *
   * ### Strategy Two: SDK doesn't assume the URL has been encoded or not. It will just escape the special characters.
   *
   * This is what V10 Blob Go SDK does. It accepts a URL type in Go, and call url.EscapedPath() to escape the special chars unescaped.
   * - When customer URL string is "http://account.blob.core.windows.net/con/b:",
   *   SDK will escape ":" like "http://account.blob.core.windows.net/con/b%3A" and send to server. A blob named "b:" will be created.
   * - When customer URL string is "http://account.blob.core.windows.net/con/b%3A",
   *   There is no special characters, so send "http://account.blob.core.windows.net/con/b%3A" to server. A blob named "b:" will be created.
   * - When customer URL string is "http://account.blob.core.windows.net/con/b%253A",
   *   There is no special characters, so send "http://account.blob.core.windows.net/con/b%253A" to server. A blob named "b%3A" will be created.
   *
   * This strategy gives us flexibility to create with any special characters. But "%" will be treated as a special characters, if the URL string
   * is not encoded, there shouldn't a "%" in the URL string, otherwise the URL is not a valid URL.
   * If customer needs to create a blob with "%" in it's blob name, use "%25" insead of "%". Just like above 3rd sample.
   * And following URL strings are invalid:
   * - "http://account.blob.core.windows.net/con/b%"
   * - "http://account.blob.core.windows.net/con/b%2"
   * - "http://account.blob.core.windows.net/con/b%G"
   *
   * Another special character is "?", use "%2F" to represent a blob name with "?" in a URL string.
   *
   * ### Strategy for containerName, blobName or other specific XXXName parameters in methods such as `BlobURL.fromContainerURL(containerURL, blobName)`
   *
   * We will apply strategy one, and call encodeURIComponent for these parameters like blobName. Because what customers passes in is a plain name instead of a URL.
   *
   * @see https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata
   * @see https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-shares--directories--files--and-metadata
   *
   * @export
   * @param {string} url
   * @returns {string}
   */
  export function escapeURLPath(url) {
      var urlParsed = URLBuilder.parse(url);
      var path = urlParsed.getPath();
      path = path || "/";
      path = escape(path);
      urlParsed.setPath(path);
      return urlParsed.toString();
  }
  /**
   * Internal escape method implmented Strategy Two mentioned in escapeURL() description.
   *
   * @param {string} text
   * @returns {string}
   */
  function escape(text) {
      return encodeURIComponent(text)
          .replace(/%2F/g, "/") // Don't escape for "/"
          .replace(/'/g, "%27") // Escape for "'"
          .replace(/\+/g, "%20")
          .replace(/%25/g, "%"); // Revert encoded "%"
  }
  /**
   * Append a string to URL path. Will remove duplicated "/" in front of the string
   * when URL path ends with a "/".
   *
   * @export
   * @param {string} url Source URL string
   * @param {string} name String to be appended to URL
   * @returns {string} An updated URL string
   */
  export function appendToURLPath(url, name) {
      var urlParsed = URLBuilder.parse(url);
      var path = urlParsed.getPath();
      path = path ? (path.endsWith("/") ? "" + path + name : path + "/" + name) : name;
      urlParsed.setPath(path);
      return urlParsed.toString();
  }
  /**
   * Set URL parameter name and value. If name exists in URL parameters, old value
   * will be replaced by name key. If not provide value, the parameter will be deleted.
   *
   * @export
   * @param {string} url Source URL string
   * @param {string} name Parameter name
   * @param {string} [value] Parameter value
   * @returns {string} An updated URL string
   */
  export function setURLParameter(url, name, value) {
      var urlParsed = URLBuilder.parse(url);
      urlParsed.setQueryParameter(name, value);
      return urlParsed.toString();
  }
  /**
   * Get URL parameter by name.
   *
   * @export
   * @param {string} url
   * @param {string} name
   * @returns {(string | string[] | undefined)}
   */
  export function getURLParameter(url, name) {
      var urlParsed = URLBuilder.parse(url);
      return urlParsed.getQueryParameterValue(name);
  }
  /**
   * Set URL host.
   *
   * @export
   * @param {string} url Source URL string
   * @param {string} host New host string
   * @returns An updated URL string
   */
  export function setURLHost(url, host) {
      var urlParsed = URLBuilder.parse(url);
      urlParsed.setHost(host);
      return urlParsed.toString();
  }
  /**
   * Get URL path from an URL string.
   *
   * @export
   * @param {string} url Source URL string
   * @returns {(string | undefined)}
   */
  export function getURLPath(url) {
      var urlParsed = URLBuilder.parse(url);
      return urlParsed.getPath();
  }
  /**
   * Get URL query key value pairs from an URL string.
   *
   * @export
   * @param {string} url
   * @returns {{[key: string]: string}}
   */
  export function getURLQueries(url) {
      var queryString = URLBuilder.parse(url).getQuery();
      if (!queryString) {
          return {};
      }
      queryString = queryString.trim();
      queryString = queryString.startsWith("?") ? queryString.substr(1) : queryString;
      var querySubStrings = queryString.split("&");
      querySubStrings = querySubStrings.filter(function (value) {
          var indexOfEqual = value.indexOf("=");
          var lastIndexOfEqual = value.lastIndexOf("=");
          return (indexOfEqual > 0 && indexOfEqual === lastIndexOfEqual && lastIndexOfEqual < value.length - 1);
      });
      var queries = {};
      for (var _i = 0, querySubStrings_1 = querySubStrings; _i < querySubStrings_1.length; _i++) {
          var querySubString = querySubStrings_1[_i];
          var splitResults = querySubString.split("=");
          var key = splitResults[0];
          var value = splitResults[1];
          queries[key] = value;
      }
      return queries;
  }
  /**
   * Rounds a date off to seconds.
   *
   * @export
   * @param {Date} date
   * @param {boolean} [withMilliseconds=true] If true, YYYY-MM-DDThh:mm:ss.fffffffZ will be returned;
   *                                          If false, YYYY-MM-DDThh:mm:ssZ will be returned.
   * @returns {string} Date string in ISO8061 format, with or without 7 milliseconds component
   */
  export function truncatedISO8061Date(date, withMilliseconds) {
      if (withMilliseconds === void 0) { withMilliseconds = true; }
      // Date.toISOString() will return like "2018-10-29T06:34:36.139Z"
      var dateString = date.toISOString();
      return withMilliseconds
          ? dateString.substring(0, dateString.length - 1) + "0000" + "Z"
          : dateString.substring(0, dateString.length - 5) + "Z";
  }
  /**
   * Base64 encode.
   *
   * @export
   * @param {string} content
   * @returns {string}
   */
  export function base64encode(content) {
      return !isNode ? btoa(content) : Buffer.from(content).toString("base64");
  }
  /**
   * Base64 decode.
   *
   * @export
   * @param {string} encodedString
   * @returns {string}
   */
  export function base64decode(encodedString) {
      return !isNode ? atob(encodedString) : Buffer.from(encodedString, "base64").toString();
  }
  /**
   * Generate a 64 bytes base64 block ID string.
   *
   * @export
   * @param {number} blockIndex
   * @returns {string}
   */
  export function generateBlockID(blockIDPrefix, blockIndex) {
      // To generate a 64 bytes base64 string, source string should be 48
      var maxSourceStringLength = 48;
      // A blob can have a maximum of 100,000 uncommitted blocks at any given time
      var maxBlockIndexLength = 6;
      var maxAllowedBlockIDPrefixLength = maxSourceStringLength - maxBlockIndexLength;
      if (blockIDPrefix.length > maxAllowedBlockIDPrefixLength) {
          blockIDPrefix = blockIDPrefix.slice(0, maxAllowedBlockIDPrefixLength);
      }
      var res = blockIDPrefix +
          padStart(blockIndex.toString(), maxSourceStringLength - blockIDPrefix.length, "0");
      return base64encode(res);
  }
  /**
   * Delay specified time interval.
   *
   * @export
   * @param {number} timeInMs
   * @param {AbortSignalLike} [aborter]
   * @param {Error} [abortError]
   */
  export function delay(timeInMs, aborter, abortError) {
      return tslib_1.__awaiter(this, void 0, void 0, function () {
          return tslib_1.__generator(this, function (_a) {
              return [2 /*return*/, new Promise(function (resolve, reject) {
                      var timeout;
                      var abortHandler = function () {
                          if (timeout !== undefined) {
                              clearTimeout(timeout);
                          }
                          reject(abortError);
                      };
                      var resolveHandler = function () {
                          if (aborter !== undefined) {
                              aborter.removeEventListener("abort", abortHandler);
                          }
                          resolve();
                      };
                      timeout = setTimeout(resolveHandler, timeInMs);
                      if (aborter !== undefined) {
                          aborter.addEventListener("abort", abortHandler);
                      }
                  })];
          });
      });
  }
  /**
   * String.prototype.padStart()
   *
   * @export
   * @param {string} currentString
   * @param {number} targetLength
   * @param {string} [padString=" "]
   * @returns {string}
   */
  export function padStart(currentString, targetLength, padString) {
      if (padString === void 0) { padString = " "; }
      if (String.prototype.padStart) {
          return currentString.padStart(targetLength, padString);
      }
      padString = padString || " ";
      if (currentString.length > targetLength) {
          return currentString;
      }
      else {
          targetLength = targetLength - currentString.length;
          if (targetLength > padString.length) {
              padString += padString.repeat(targetLength / padString.length);
          }
          return padString.slice(0, targetLength) + currentString;
      }
  }
  //# sourceMappingURL=utils.common.js.map