async function get(url) {
   const response = await fetch(url);
   return response.json();
}

async function post(url, formData) {
   const response = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded', },
      body: $.param(formData),
   });
   return response.json();
}

async function put(url, content, opts) {
   return new Promise((resolve, reject) => {
      let xhr = new XMLHttpRequest();
      xhr.upload.addEventListener("progress", opts?.onuploadprogress);
      xhr.addEventListener("load", evt => resolve(evt.target));
      xhr.open("PUT", url);
      for(const [key, value] of Object.entries(opts?.headers || {})) {
         xhr.setRequestHeader(key, value);
      }
      xhr.send(content);
   });
}
