diff --git a/lib/client/storage/dropbox/lib/dropbox.js b/lib/client/storage/dropbox/lib/dropbox.js new file mode 100644 index 00000000..baa1119c --- /dev/null +++ b/lib/client/storage/dropbox/lib/dropbox.js @@ -0,0 +1,2392 @@ +// Generated by CoffeeScript 1.4.0 +(function() { + var Dropbox, DropboxClient, DropboxXhrArrayBufferView, DropboxXhrCanSendForms, DropboxXhrDoesPreflight, DropboxXhrIeMode, DropboxXhrRequest, add32, arrayToBase64, atob, atobNibble, base64Digits, base64HmacSha1, base64Sha1, btoa, btoaNibble, crypto, dropboxEncodeKey, hmacSha1, rotateLeft32, sha1, stringToArray, _base64Digits, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + + Dropbox = (function() { + + function Dropbox(options) { + this.client = new DropboxClient(options); + } + + return Dropbox; + + })(); + + Dropbox.ApiError = (function() { + + ApiError.prototype.status = void 0; + + ApiError.prototype.method = void 0; + + ApiError.prototype.url = void 0; + + ApiError.prototype.responseText = void 0; + + ApiError.prototype.response = void 0; + + function ApiError(xhr, method, url) { + var text; + this.method = method; + this.url = url; + this.status = xhr.status; + if (xhr.responseType) { + text = xhr.response || xhr.responseText; + } else { + text = xhr.responseText; + } + if (text) { + try { + this.responseText = text.toString(); + this.response = JSON.parse(text); + } catch (e) { + this.response = null; + } + } else { + this.responseText = '(no response)'; + this.response = null; + } + } + + ApiError.prototype.toString = function() { + return "Dropbox API error " + this.status + " from " + this.method + " " + this.url + " :: " + this.responseText; + }; + + ApiError.prototype.inspect = function() { + return this.toString(); + }; + + return ApiError; + + })(); + + if (typeof window !== "undefined" && window !== null) { + if (window.atob && window.btoa) { + atob = function(string) { + return window.atob(string); + }; + btoa = function(base64) { + return window.btoa(base64); + }; + } else { + base64Digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + btoaNibble = function(accumulator, bytes, result) { + var i, limit; + limit = 3 - bytes; + accumulator <<= limit * 8; + i = 3; + while (i >= limit) { + result.push(base64Digits.charAt((accumulator >> (i * 6)) & 0x3F)); + i -= 1; + } + i = bytes; + while (i < 3) { + result.push('='); + i += 1; + } + return null; + }; + atobNibble = function(accumulator, digits, result) { + var i, limit; + limit = 4 - digits; + accumulator <<= limit * 6; + i = 2; + while (i >= limit) { + result.push(String.fromCharCode((accumulator >> (8 * i)) & 0xFF)); + i -= 1; + } + return null; + }; + btoa = function(string) { + var accumulator, bytes, i, result, _i, _ref; + result = []; + accumulator = 0; + bytes = 0; + for (i = _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + accumulator = (accumulator << 8) | string.charCodeAt(i); + bytes += 1; + if (bytes === 3) { + btoaNibble(accumulator, bytes, result); + accumulator = bytes = 0; + } + } + if (bytes > 0) { + btoaNibble(accumulator, bytes, result); + } + return result.join(''); + }; + atob = function(base64) { + var accumulator, digit, digits, i, result, _i, _ref; + result = []; + accumulator = 0; + digits = 0; + for (i = _i = 0, _ref = base64.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + digit = base64.charAt(i); + if (digit === '=') { + break; + } + accumulator = (accumulator << 6) | base64Digits.indexOf(digit); + digits += 1; + if (digits === 4) { + atobNibble(accumulator, digits, result); + accumulator = digits = 0; + } + } + if (digits > 0) { + atobNibble(accumulator, digits, result); + } + return result.join(''); + }; + } + } else { + atob = function(arg) { + var buffer, i; + buffer = new Buffer(arg, 'base64'); + return ((function() { + var _i, _ref, _results; + _results = []; + for (i = _i = 0, _ref = buffer.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + _results.push(String.fromCharCode(buffer[i])); + } + return _results; + })()).join(''); + }; + btoa = function(arg) { + var buffer, i; + buffer = new Buffer((function() { + var _i, _ref, _results; + _results = []; + for (i = _i = 0, _ref = arg.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + _results.push(arg.charCodeAt(i)); + } + return _results; + })()); + return buffer.toString('base64'); + }; + } + + Dropbox.Client = (function() { + + function Client(options) { + this.sandbox = options.sandbox || false; + this.apiServer = options.server || this.defaultApiServer(); + this.authServer = options.authServer || this.defaultAuthServer(); + this.fileServer = options.fileServer || this.defaultFileServer(); + this.downloadServer = options.downloadServer || this.defaultDownloadServer(); + this.oauth = new Dropbox.Oauth(options); + this.driver = null; + this.filter = null; + this.uid = null; + this.authState = null; + this.authError = null; + this._credentials = null; + this.setCredentials(options); + this.setupUrls(); + } + + Client.prototype.authDriver = function(driver) { + this.driver = driver; + return this; + }; + + Client.prototype.xhrFilter = function(filter) { + this.filter = filter; + return this; + }; + + Client.prototype.dropboxUid = function() { + return this.uid; + }; + + Client.prototype.credentials = function() { + if (!this._credentials) { + this.computeCredentials(); + } + return this._credentials; + }; + + Client.prototype.authenticate = function(callback) { + var oldAuthState, _fsmStep, + _this = this; + oldAuthState = null; + _fsmStep = function() { + var authUrl; + if (oldAuthState !== _this.authState) { + oldAuthState = _this.authState; + if (_this.driver.onAuthStateChange) { + return _this.driver.onAuthStateChange(_this, _fsmStep); + } + } + switch (_this.authState) { + case DropboxClient.RESET: + return _this.requestToken(function(error, data) { + var token, tokenSecret; + if (error) { + _this.authError = error; + _this.authState = DropboxClient.ERROR; + } else { + token = data.oauth_token; + tokenSecret = data.oauth_token_secret; + _this.oauth.setToken(token, tokenSecret); + _this.authState = DropboxClient.REQUEST; + } + _this._credentials = null; + return _fsmStep(); + }); + case DropboxClient.REQUEST: + authUrl = _this.authorizeUrl(_this.oauth.token); + return _this.driver.doAuthorize(authUrl, _this.oauth.token, _this.oauth.tokenSecret, function() { + _this.authState = DropboxClient.AUTHORIZED; + _this._credentials = null; + return _fsmStep(); + }); + case DropboxClient.AUTHORIZED: + return _this.getAccessToken(function(error, data) { + if (error) { + _this.authError = error; + _this.authState = DropboxClient.ERROR; + } else { + _this.oauth.setToken(data.oauth_token, data.oauth_token_secret); + _this.uid = data.uid; + _this.authState = DropboxClient.DONE; + } + _this._credentials = null; + return _fsmStep(); + }); + case DropboxClient.DONE: + return callback(null, _this); + case Dropbox.SIGNED_OFF: + _this.reset(); + return _fsmStep(); + case DropboxClient.ERROR: + return callback(_this.authError); + } + }; + _fsmStep(); + return this; + }; + + Client.prototype.signOut = function(callback) { + var xhr, + _this = this; + xhr = new Dropbox.Xhr('POST', this.urls.signOut); + xhr.signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error) { + if (error) { + return callback(error); + } + _this.reset(); + _this.authState = DropboxClient.SIGNED_OFF; + if (_this.driver.onAuthStateChange) { + return _this.driver.onAuthStateChange(_this, function() { + return callback(error); + }); + } else { + return callback(error); + } + }); + }; + + Client.prototype.signOff = function(callback) { + return this.signOut(callback); + }; + + Client.prototype.getUserInfo = function(callback) { + var xhr; + xhr = new Dropbox.Xhr('GET', this.urls.accountInfo); + xhr.signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error, userData) { + return callback(error, Dropbox.UserInfo.parse(userData), userData); + }); + }; + + Client.prototype.readFile = function(path, options, callback) { + var params, rangeEnd, rangeHeader, rangeStart, responseType, xhr; + if ((!callback) && (typeof options === 'function')) { + callback = options; + options = null; + } + params = {}; + responseType = null; + rangeHeader = null; + if (options) { + if (options.versionTag) { + params.rev = options.versionTag; + } else if (options.rev) { + params.rev = options.rev; + } + if (options.arrayBuffer) { + responseType = 'arraybuffer'; + } else if (options.blob) { + responseType = 'blob'; + } else if (options.binary) { + responseType = 'b'; + } + if (options.length) { + if (options.start != null) { + rangeStart = options.start; + rangeEnd = options.start + options.length - 1; + } else { + rangeStart = ''; + rangeEnd = options.length; + } + rangeHeader = "bytes=" + rangeStart + "-" + rangeEnd; + } else if (options.start != null) { + rangeHeader = "bytes=" + options.start + "-"; + } + } + xhr = new Dropbox.Xhr('GET', "" + this.urls.getFile + "/" + (this.urlEncodePath(path))); + xhr.setParams(params).signWithOauth(this.oauth).setResponseType(responseType); + if (rangeHeader) { + xhr.setHeader('Range', rangeHeader); + } + return this.dispatchXhr(xhr, function(error, data, metadata) { + return callback(error, data, Dropbox.Stat.parse(metadata)); + }); + }; + + Client.prototype.writeFile = function(path, data, options, callback) { + var useForm; + if ((!callback) && (typeof options === 'function')) { + callback = options; + options = null; + } + useForm = Dropbox.Xhr.canSendForms && typeof data === 'object'; + if (useForm) { + return this.writeFileUsingForm(path, data, options, callback); + } else { + return this.writeFileUsingPut(path, data, options, callback); + } + }; + + Client.prototype.writeFileUsingForm = function(path, data, options, callback) { + var fileName, params, slashIndex, xhr; + slashIndex = path.lastIndexOf('/'); + if (slashIndex === -1) { + fileName = path; + path = ''; + } else { + fileName = path.substring(slashIndex); + path = path.substring(0, slashIndex); + } + params = { + file: fileName + }; + if (options) { + if (options.noOverwrite) { + params.overwrite = 'false'; + } + if (options.lastVersionTag) { + params.parent_rev = options.lastVersionTag; + } else if (options.parentRev || options.parent_rev) { + params.parent_rev = options.parentRev || options.parent_rev; + } + } + xhr = new Dropbox.Xhr('POST', "" + this.urls.postFile + "/" + (this.urlEncodePath(path))); + xhr.setParams(params).signWithOauth(this.oauth).setFileField('file', fileName, data, 'application/octet-stream'); + delete params.file; + return this.dispatchXhr(xhr, function(error, metadata) { + return callback(error, Dropbox.Stat.parse(metadata)); + }); + }; + + Client.prototype.writeFileUsingPut = function(path, data, options, callback) { + var params, xhr; + params = {}; + if (options) { + if (options.noOverwrite) { + params.overwrite = 'false'; + } + if (options.lastVersionTag) { + params.parent_rev = options.lastVersionTag; + } else if (options.parentRev || options.parent_rev) { + params.parent_rev = options.parentRev || options.parent_rev; + } + } + xhr = new Dropbox.Xhr('POST', "" + this.urls.putFile + "/" + (this.urlEncodePath(path))); + xhr.setBody(data).setParams(params).signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error, metadata) { + return callback(error, Dropbox.Stat.parse(metadata)); + }); + }; + + Client.prototype.stat = function(path, options, callback) { + var params, xhr; + if ((!callback) && (typeof options === 'function')) { + callback = options; + options = null; + } + params = {}; + if (options) { + if (options.version != null) { + params.rev = options.version; + } + if (options.removed || options.deleted) { + params.include_deleted = 'true'; + } + if (options.readDir) { + params.list = 'true'; + if (options.readDir !== true) { + params.file_limit = options.readDir.toString(); + } + } + if (options.cacheHash) { + params.hash = options.cacheHash; + } + } + params.include_deleted || (params.include_deleted = 'false'); + params.list || (params.list = 'false'); + xhr = new Dropbox.Xhr('GET', "" + this.urls.metadata + "/" + (this.urlEncodePath(path))); + xhr.setParams(params).signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error, metadata) { + var entries, entry, stat; + stat = Dropbox.Stat.parse(metadata); + if (metadata != null ? metadata.contents : void 0) { + entries = (function() { + var _i, _len, _ref, _results; + _ref = metadata.contents; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + entry = _ref[_i]; + _results.push(Dropbox.Stat.parse(entry)); + } + return _results; + })(); + } else { + entries = void 0; + } + return callback(error, stat, entries); + }); + }; + + Client.prototype.readdir = function(path, options, callback) { + var statOptions; + if ((!callback) && (typeof options === 'function')) { + callback = options; + options = null; + } + statOptions = { + readDir: true + }; + if (options) { + if (options.limit != null) { + statOptions.readDir = options.limit; + } + if (options.versionTag) { + statOptions.versionTag = options.versionTag; + } + } + return this.stat(path, statOptions, function(error, stat, entry_stats) { + var entries, entry_stat; + if (entry_stats) { + entries = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = entry_stats.length; _i < _len; _i++) { + entry_stat = entry_stats[_i]; + _results.push(entry_stat.name); + } + return _results; + })(); + } else { + entries = null; + } + return callback(error, entries, stat, entry_stats); + }); + }; + + Client.prototype.metadata = function(path, options, callback) { + return this.stat(path, options, callback); + }; + + Client.prototype.makeUrl = function(path, options, callback) { + var isDirect, params, url, useDownloadHack, xhr; + if ((!callback) && (typeof options === 'function')) { + callback = options; + options = null; + } + if (options && (options['long'] || options.longUrl || options.downloadHack)) { + params = { + short_url: 'false' + }; + } else { + params = {}; + } + path = this.urlEncodePath(path); + url = "" + this.urls.shares + "/" + path; + isDirect = false; + useDownloadHack = false; + if (options) { + if (options.downloadHack) { + isDirect = true; + useDownloadHack = true; + } else if (options.download) { + isDirect = true; + url = "" + this.urls.media + "/" + path; + } + } + xhr = new Dropbox.Xhr('POST', url).setParams(params).signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error, urlData) { + if (useDownloadHack && urlData && urlData.url) { + urlData.url = urlData.url.replace(this.authServer, this.downloadServer); + } + return callback(error, Dropbox.PublicUrl.parse(urlData, isDirect)); + }); + }; + + Client.prototype.history = function(path, options, callback) { + var params, xhr; + if ((!callback) && (typeof options === 'function')) { + callback = options; + options = null; + } + params = {}; + if (options && (options.limit != null)) { + params.rev_limit = options.limit; + } + xhr = new Dropbox.Xhr('GET', "" + this.urls.revisions + "/" + (this.urlEncodePath(path))); + xhr.setParams(params).signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error, versions) { + var metadata, stats; + if (versions) { + stats = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = versions.length; _i < _len; _i++) { + metadata = versions[_i]; + _results.push(Dropbox.Stat.parse(metadata)); + } + return _results; + })(); + } else { + stats = void 0; + } + return callback(error, stats); + }); + }; + + Client.prototype.revisions = function(path, options, callback) { + return this.history(path, options, callback); + }; + + Client.prototype.thumbnailUrl = function(path, options) { + var xhr; + xhr = this.thumbnailXhr(path, options); + return xhr.paramsToUrl().url; + }; + + Client.prototype.readThumbnail = function(path, options, callback) { + var responseType, xhr; + if ((!callback) && (typeof options === 'function')) { + callback = options; + options = null; + } + responseType = 'b'; + if (options) { + if (options.blob) { + responseType = 'blob'; + } + } + xhr = this.thumbnailXhr(path, options); + xhr.setResponseType(responseType); + return this.dispatchXhr(xhr, function(error, data, metadata) { + return callback(error, data, Dropbox.Stat.parse(metadata)); + }); + }; + + Client.prototype.thumbnailXhr = function(path, options) { + var params, xhr; + params = {}; + if (options) { + if (options.format) { + params.format = options.format; + } else if (options.png) { + params.format = 'png'; + } + if (options.size) { + params.size = options.size; + } + } + xhr = new Dropbox.Xhr('GET', "" + this.urls.thumbnails + "/" + (this.urlEncodePath(path))); + return xhr.setParams(params).signWithOauth(this.oauth); + }; + + Client.prototype.revertFile = function(path, versionTag, callback) { + var xhr; + xhr = new Dropbox.Xhr('POST', "" + this.urls.restore + "/" + (this.urlEncodePath(path))); + xhr.setParams({ + rev: versionTag + }).signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error, metadata) { + return callback(error, Dropbox.Stat.parse(metadata)); + }); + }; + + Client.prototype.restore = function(path, versionTag, callback) { + return this.revertFile(path, versionTag, callback); + }; + + Client.prototype.findByName = function(path, namePattern, options, callback) { + var params, xhr; + if ((!callback) && (typeof options === 'function')) { + callback = options; + options = null; + } + params = { + query: namePattern + }; + if (options) { + if (options.limit != null) { + params.file_limit = options.limit; + } + if (options.removed || options.deleted) { + params.include_deleted = true; + } + } + xhr = new Dropbox.Xhr('GET', "" + this.urls.search + "/" + (this.urlEncodePath(path))); + xhr.setParams(params).signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error, results) { + var metadata, stats; + if (results) { + stats = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = results.length; _i < _len; _i++) { + metadata = results[_i]; + _results.push(Dropbox.Stat.parse(metadata)); + } + return _results; + })(); + } else { + stats = void 0; + } + return callback(error, stats); + }); + }; + + Client.prototype.search = function(path, namePattern, options, callback) { + return this.findByName(path, namePattern, options, callback); + }; + + Client.prototype.makeCopyReference = function(path, callback) { + var xhr; + xhr = new Dropbox.Xhr('GET', "" + this.urls.copyRef + "/" + (this.urlEncodePath(path))); + xhr.signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error, refData) { + return callback(error, Dropbox.CopyReference.parse(refData)); + }); + }; + + Client.prototype.copyRef = function(path, callback) { + return this.makeCopyReference(path, callback); + }; + + Client.prototype.pullChanges = function(cursor, callback) { + var params, xhr; + if ((!callback) && (typeof cursor === 'function')) { + callback = cursor; + cursor = null; + } + if (cursor) { + if (cursor.cursorTag) { + params = { + cursor: cursor.cursorTag + }; + } else { + params = { + cursor: cursor + }; + } + } else { + params = {}; + } + xhr = new Dropbox.Xhr('POST', this.urls.delta); + xhr.setParams(params).signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error, deltaInfo) { + return callback(error, Dropbox.PulledChanges.parse(deltaInfo)); + }); + }; + + Client.prototype.delta = function(cursor, callback) { + return this.pullChanges(cursor, callback); + }; + + Client.prototype.mkdir = function(path, callback) { + var xhr; + xhr = new Dropbox.Xhr('POST', this.urls.fileopsCreateFolder); + xhr.setParams({ + root: this.fileRoot, + path: this.normalizePath(path) + }).signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error, metadata) { + return callback(error, Dropbox.Stat.parse(metadata)); + }); + }; + + Client.prototype.remove = function(path, callback) { + var xhr; + xhr = new Dropbox.Xhr('POST', this.urls.fileopsDelete); + xhr.setParams({ + root: this.fileRoot, + path: this.normalizePath(path) + }).signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error, metadata) { + return callback(error, Dropbox.Stat.parse(metadata)); + }); + }; + + Client.prototype.unlink = function(path, callback) { + return this.remove(path, callback); + }; + + Client.prototype["delete"] = function(path, callback) { + return this.remove(path, callback); + }; + + Client.prototype.copy = function(from, toPath, callback) { + var options, params, xhr; + if ((!callback) && (typeof options === 'function')) { + callback = options; + options = null; + } + params = { + root: this.fileRoot, + to_path: this.normalizePath(toPath) + }; + if (from instanceof Dropbox.CopyReference) { + params.from_copy_ref = from.tag; + } else { + params.from_path = this.normalizePath(from); + } + xhr = new Dropbox.Xhr('POST', this.urls.fileopsCopy); + xhr.setParams(params).signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error, metadata) { + return callback(error, Dropbox.Stat.parse(metadata)); + }); + }; + + Client.prototype.move = function(fromPath, toPath, callback) { + var options, xhr; + if ((!callback) && (typeof options === 'function')) { + callback = options; + options = null; + } + xhr = new Dropbox.Xhr('POST', this.urls.fileopsMove); + xhr.setParams({ + root: this.fileRoot, + from_path: this.normalizePath(fromPath), + to_path: this.normalizePath(toPath) + }).signWithOauth(this.oauth); + return this.dispatchXhr(xhr, function(error, metadata) { + return callback(error, Dropbox.Stat.parse(metadata)); + }); + }; + + Client.prototype.reset = function() { + this.uid = null; + this.oauth.setToken(null, ''); + this.authState = DropboxClient.RESET; + this.authError = null; + this._credentials = null; + return this; + }; + + Client.prototype.setCredentials = function(credentials) { + this.oauth.reset(credentials); + this.uid = credentials.uid || null; + if (credentials.authState) { + this.authState = credentials.authState; + } else { + if (credentials.token) { + this.authState = DropboxClient.DONE; + } else { + this.authState = DropboxClient.RESET; + } + } + this.authError = null; + this._credentials = null; + return this; + }; + + Client.prototype.appHash = function() { + return this.oauth.appHash(); + }; + + Client.prototype.setupUrls = function() { + this.fileRoot = this.sandbox ? 'sandbox' : 'dropbox'; + return this.urls = { + requestToken: "" + this.apiServer + "/1/oauth/request_token", + authorize: "" + this.authServer + "/1/oauth/authorize", + accessToken: "" + this.apiServer + "/1/oauth/access_token", + signOut: "" + this.apiServer + "/1/unlink_access_token", + accountInfo: "" + this.apiServer + "/1/account/info", + getFile: "" + this.fileServer + "/1/files/" + this.fileRoot, + postFile: "" + this.fileServer + "/1/files/" + this.fileRoot, + putFile: "" + this.fileServer + "/1/files_put/" + this.fileRoot, + metadata: "" + this.apiServer + "/1/metadata/" + this.fileRoot, + delta: "" + this.apiServer + "/1/delta", + revisions: "" + this.apiServer + "/1/revisions/" + this.fileRoot, + restore: "" + this.apiServer + "/1/restore/" + this.fileRoot, + search: "" + this.apiServer + "/1/search/" + this.fileRoot, + shares: "" + this.apiServer + "/1/shares/" + this.fileRoot, + media: "" + this.apiServer + "/1/media/" + this.fileRoot, + copyRef: "" + this.apiServer + "/1/copy_ref/" + this.fileRoot, + thumbnails: "" + this.fileServer + "/1/thumbnails/" + this.fileRoot, + fileopsCopy: "" + this.apiServer + "/1/fileops/copy", + fileopsCreateFolder: "" + this.apiServer + "/1/fileops/create_folder", + fileopsDelete: "" + this.apiServer + "/1/fileops/delete", + fileopsMove: "" + this.apiServer + "/1/fileops/move" + }; + }; + + Client.ERROR = 0; + + Client.RESET = 1; + + Client.REQUEST = 2; + + Client.AUTHORIZED = 3; + + Client.DONE = 4; + + Client.SIGNED_OFF = 5; + + Client.prototype.urlEncodePath = function(path) { + return Dropbox.Xhr.urlEncodeValue(this.normalizePath(path)).replace(/%2F/gi, '/'); + }; + + Client.prototype.normalizePath = function(path) { + var i; + if (path.substring(0, 1) === '/') { + i = 1; + while (path.substring(i, i + 1) === '/') { + i += 1; + } + return path.substring(i); + } else { + return path; + } + }; + + Client.prototype.requestToken = function(callback) { + var xhr; + xhr = new Dropbox.Xhr('POST', this.urls.requestToken).signWithOauth(this.oauth); + return this.dispatchXhr(xhr, callback); + }; + + Client.prototype.authorizeUrl = function(token) { + var params; + params = { + oauth_token: token, + oauth_callback: this.driver.url() + }; + return ("" + this.urls.authorize + "?") + Dropbox.Xhr.urlEncode(params); + }; + + Client.prototype.getAccessToken = function(callback) { + var xhr; + xhr = new Dropbox.Xhr('POST', this.urls.accessToken).signWithOauth(this.oauth); + return this.dispatchXhr(xhr, callback); + }; + + Client.prototype.dispatchXhr = function(xhr, callback) { + var nativeXhr; + xhr.setCallback(callback); + xhr.prepare(); + nativeXhr = xhr.xhr; + if (this.filter) { + if (!this.filter(nativeXhr, xhr)) { + return nativeXhr; + } + } + xhr.send(); + return nativeXhr; + }; + + Client.prototype.defaultApiServer = function() { + return 'https://api.dropbox.com'; + }; + + Client.prototype.defaultAuthServer = function() { + return this.apiServer.replace('api.', 'www.'); + }; + + Client.prototype.defaultFileServer = function() { + return this.apiServer.replace('api.', 'api-content.'); + }; + + Client.prototype.defaultDownloadServer = function() { + return this.apiServer.replace('api.', 'dl.'); + }; + + Client.prototype.computeCredentials = function() { + var value; + value = { + key: this.oauth.key, + sandbox: this.sandbox + }; + if (this.oauth.secret) { + value.secret = this.oauth.secret; + } + if (this.oauth.token) { + value.token = this.oauth.token; + value.tokenSecret = this.oauth.tokenSecret; + } + if (this.uid) { + value.uid = this.uid; + } + if (this.authState !== DropboxClient.ERROR && this.authState !== DropboxClient.RESET && this.authState !== DropboxClient.DONE && this.authState !== DropboxClient.SIGNED_OFF) { + value.authState = this.authState; + } + if (this.apiServer !== this.defaultApiServer()) { + value.server = this.apiServer; + } + if (this.authServer !== this.defaultAuthServer()) { + value.authServer = this.authServer; + } + if (this.fileServer !== this.defaultFileServer()) { + value.fileServer = this.fileServer; + } + if (this.downloadServer !== this.defaultDownloadServer()) { + value.downloadServer = this.downloadServer; + } + return this._credentials = value; + }; + + return Client; + + })(); + + DropboxClient = Dropbox.Client; + + Dropbox.AuthDriver = (function() { + + function AuthDriver() {} + + AuthDriver.prototype.url = function() { + return 'https://some.url'; + }; + + AuthDriver.prototype.doAuthorize = function(authUrl, token, tokenSecret, callback) { + return callback('oauth-token'); + }; + + AuthDriver.prototype.onAuthStateChange = function(client, callback) { + return callback(); + }; + + return AuthDriver; + + })(); + + Dropbox.Drivers = {}; + + Dropbox.Drivers.BrowserBase = (function() { + + function BrowserBase(options) { + this.rememberUser = (options != null ? options.rememberUser : void 0) || false; + this.scope = (options != null ? options.scope : void 0) || 'default'; + } + + BrowserBase.prototype.onAuthStateChange = function(client, callback) { + var _this = this; + this.setStorageKey(client); + switch (client.authState) { + case DropboxClient.RESET: + return this.loadCredentials(function(credentials) { + if (!credentials) { + return callback(); + } + if (credentials.authState) { + client.setCredentials(credentials); + return callback(); + } + if (!_this.rememberUser) { + _this.forgetCredentials(); + return callback(); + } + client.setCredentials(credentials); + return client.getUserInfo(function(error) { + if (error) { + client.reset(); + return _this.forgetCredentials(callback); + } else { + return callback(); + } + }); + }); + case DropboxClient.REQUEST: + return this.storeCredentials(client.credentials(), callback); + case DropboxClient.DONE: + if (this.rememberUser) { + return this.storeCredentials(client.credentials(), callback); + } + return this.forgetCredentials(callback); + case DropboxClient.SIGNED_OFF: + return this.forgetCredentials(callback); + case DropboxClient.ERROR: + return this.forgetCredentials(callback); + default: + callback(); + return this; + } + }; + + BrowserBase.prototype.setStorageKey = function(client) { + this.storageKey = "dropbox-auth:" + this.scope + ":" + (client.appHash()); + return this; + }; + + BrowserBase.prototype.storeCredentials = function(credentials, callback) { + localStorage.setItem(this.storageKey, JSON.stringify(credentials)); + callback(); + return this; + }; + + BrowserBase.prototype.loadCredentials = function(callback) { + var jsonString; + jsonString = localStorage.getItem(this.storageKey); + if (!jsonString) { + callback(null); + return this; + } + try { + callback(JSON.parse(jsonString)); + } catch (e) { + callback(null); + } + return this; + }; + + BrowserBase.prototype.forgetCredentials = function(callback) { + localStorage.removeItem(this.storageKey); + callback(); + return this; + }; + + BrowserBase.currentLocation = function() { + return window.location.href; + }; + + return BrowserBase; + + })(); + + Dropbox.Drivers.Redirect = (function(_super) { + + __extends(Redirect, _super); + + function Redirect(options) { + Redirect.__super__.constructor.call(this, options); + this.useQuery = (options != null ? options.useQuery : void 0) || false; + this.receiverUrl = this.computeUrl(options); + this.tokenRe = new RegExp("(#|\\?|&)oauth_token=([^&#]+)(&|#|$)"); + } + + Redirect.prototype.onAuthStateChange = function(client, callback) { + var superCall, + _this = this; + superCall = (function() { + return function() { + return Redirect.__super__.onAuthStateChange.call(_this, client, callback); + }; + })(); + this.setStorageKey(client); + if (client.authState === DropboxClient.RESET) { + return this.loadCredentials(function(credentials) { + if (credentials && credentials.authState) { + if (credentials.token === _this.locationToken() && credentials.authState === DropboxClient.REQUEST) { + credentials.authState = DropboxClient.AUTHORIZED; + return _this.storeCredentials(credentials, superCall); + } else { + return _this.forgetCredentials(superCall); + } + } + return superCall(); + }); + } else { + return superCall(); + } + }; + + Redirect.prototype.url = function() { + return this.receiverUrl; + }; + + Redirect.prototype.doAuthorize = function(authUrl) { + /* */ + return DOM.openWindow(authUrl); + /* return window.location.assign(authUrl); */ + }; + + Redirect.prototype.computeUrl = function() { + var fragment, location, locationPair, querySuffix; + querySuffix = "_dropboxjs_scope=" + (encodeURIComponent(this.scope)); + location = Dropbox.Drivers.BrowserBase.currentLocation(); + if (location.indexOf('#') === -1) { + fragment = null; + } else { + locationPair = location.split('#', 2); + location = locationPair[0]; + fragment = locationPair[1]; + } + if (this.useQuery) { + if (location.indexOf('?') === -1) { + location += "?" + querySuffix; + } else { + location += "&" + querySuffix; + } + } else { + fragment = "?" + querySuffix; + } + if (fragment) { + return location + '#' + fragment; + } else { + return location; + } + }; + + Redirect.prototype.locationToken = function() { + var location, match, scopePattern; + location = Dropbox.Drivers.BrowserBase.currentLocation(); + scopePattern = "_dropboxjs_scope=" + (encodeURIComponent(this.scope)) + "&"; + if ((typeof location.indexOf === "function" ? location.indexOf(scopePattern) : void 0) === -1) { + return null; + } + match = this.tokenRe.exec(location); + if (match) { + return decodeURIComponent(match[2]); + } else { + return null; + } + }; + + return Redirect; + + })(Dropbox.Drivers.BrowserBase); + + Dropbox.Drivers.Popup = (function(_super) { + + __extends(Popup, _super); + + function Popup(options) { + Popup.__super__.constructor.call(this, options); + this.receiverUrl = this.computeUrl(options); + this.tokenRe = new RegExp("(#|\\?|&)oauth_token=([^&#]+)(&|#|$)"); + } + + Popup.prototype.onAuthStateChange = function(client, callback) { + var superCall, + _this = this; + superCall = (function() { + return function() { + return Popup.__super__.onAuthStateChange.call(_this, client, callback); + }; + })(); + this.setStorageKey(client); + if (client.authState === DropboxClient.RESET) { + return this.loadCredentials(function(credentials) { + if (credentials && credentials.authState) { + return this.forgetCredentials(superCall); + } + return superCall(); + }); + } else { + return superCall(); + } + }; + + Popup.prototype.doAuthorize = function(authUrl, token, tokenSecret, callback) { + this.listenForMessage(token, callback); + return this.openWindow(authUrl); + }; + + Popup.prototype.url = function() { + return this.receiverUrl; + }; + + Popup.prototype.computeUrl = function(options) { + var fragments; + if (options) { + if (options.receiverUrl) { + if (options.noFragment || options.receiverUrl.indexOf('#') !== -1) { + return options.receiverUrl; + } else { + return options.receiverUrl + '#'; + } + } else if (options.receiverFile) { + fragments = Dropbox.Drivers.BrowserBase.currentLocation().split('/'); + fragments[fragments.length - 1] = options.receiverFile; + if (options.noFragment) { + return fragments.join('/'); + } else { + return fragments.join('/') + '#'; + } + } + } + return Dropbox.Drivers.BrowserBase.currentLocation(); + }; + + Popup.prototype.openWindow = function(url) { + return window.open(url, '_dropboxOauthSigninWindow', this.popupWindowSpec(980, 700)); + }; + + Popup.prototype.popupWindowSpec = function(popupWidth, popupHeight) { + var height, popupLeft, popupTop, width, x0, y0, _ref, _ref1, _ref2, _ref3; + x0 = (_ref = window.screenX) != null ? _ref : window.screenLeft; + y0 = (_ref1 = window.screenY) != null ? _ref1 : window.screenTop; + width = (_ref2 = window.outerWidth) != null ? _ref2 : document.documentElement.clientWidth; + height = (_ref3 = window.outerHeight) != null ? _ref3 : document.documentElement.clientHeight; + popupLeft = Math.round(x0 + (width - popupWidth) / 2); + popupTop = Math.round(y0 + (height - popupHeight) / 2.5); + if (popupLeft < x0) { + popupLeft = x0; + } + if (popupTop < y0) { + popupTop = y0; + } + return ("width=" + popupWidth + ",height=" + popupHeight + ",") + ("left=" + popupLeft + ",top=" + popupTop) + 'dialog=yes,dependent=yes,scrollbars=yes,location=yes'; + }; + + Popup.prototype.listenForMessage = function(token, callback) { + var listener, + _this = this; + listener = function(event) { + var match; + match = _this.tokenRe.exec(event.data.toString()); + if (match && decodeURIComponent(match[2]) === token) { + window.removeEventListener('message', listener); + return callback(); + } + }; + return window.addEventListener('message', listener, false); + }; + + return Popup; + + })(Dropbox.Drivers.BrowserBase); + + Dropbox.Drivers.NodeServer = (function() { + + function NodeServer(options) { + this.port = (options != null ? options.port : void 0) || 8912; + this.faviconFile = (options != null ? options.favicon : void 0) || null; + this.fs = require('fs'); + this.http = require('http'); + this.open = require('open'); + this.callbacks = {}; + this.urlRe = new RegExp("^/oauth_callback\\?"); + this.tokenRe = new RegExp("(\\?|&)oauth_token=([^&]+)(&|$)"); + this.createApp(); + } + + NodeServer.prototype.url = function() { + return "http://localhost:" + this.port + "/oauth_callback"; + }; + + NodeServer.prototype.doAuthorize = function(authUrl, token, tokenSecret, callback) { + this.callbacks[token] = callback; + return this.openBrowser(authUrl); + }; + + NodeServer.prototype.openBrowser = function(url) { + if (!url.match(/^https?:\/\//)) { + throw new Error("Not a http/https URL: " + url); + } + return this.open(url); + }; + + NodeServer.prototype.createApp = function() { + var _this = this; + this.app = this.http.createServer(function(request, response) { + return _this.doRequest(request, response); + }); + return this.app.listen(this.port); + }; + + NodeServer.prototype.closeServer = function() { + return this.app.close(); + }; + + NodeServer.prototype.doRequest = function(request, response) { + var data, match, token, + _this = this; + if (this.urlRe.exec(request.url)) { + match = this.tokenRe.exec(request.url); + if (match) { + token = decodeURIComponent(match[2]); + if (this.callbacks[token]) { + this.callbacks[token](); + delete this.callbacks[token]; + } + } + } + data = ''; + request.on('data', function(dataFragment) { + return data += dataFragment; + }); + return request.on('end', function() { + if (_this.faviconFile && (request.url === '/favicon.ico')) { + return _this.sendFavicon(response); + } else { + return _this.closeBrowser(response); + } + }); + }; + + NodeServer.prototype.closeBrowser = function(response) { + var closeHtml; + closeHtml = "\n\n

Please close this window.

"; + response.writeHead(200, { + 'Content-Length': closeHtml.length, + 'Content-Type': 'text/html' + }); + response.write(closeHtml); + return response.end; + }; + + NodeServer.prototype.sendFavicon = function(response) { + return this.fs.readFile(this.faviconFile, function(error, data) { + response.writeHead(200, { + 'Content-Length': data.length, + 'Content-Type': 'image/x-icon' + }); + response.write(data); + return response.end; + }); + }; + + return NodeServer; + + })(); + + base64HmacSha1 = function(string, key) { + return arrayToBase64(hmacSha1(stringToArray(string), stringToArray(key), string.length, key.length)); + }; + + base64Sha1 = function(string) { + return arrayToBase64(sha1(stringToArray(string), string.length)); + }; + + if (typeof window === "undefined" || window === null) { + crypto = require('crypto'); + base64HmacSha1 = function(string, key) { + var hmac; + hmac = crypto.createHmac('sha1', key); + hmac.update(string); + return hmac.digest('base64'); + }; + base64Sha1 = function(string) { + var hash; + hash = crypto.createHash('sha1'); + hash.update(string); + return hash.digest('base64'); + }; + } + + hmacSha1 = function(string, key, length, keyLength) { + var hash1, i, ipad, opad; + if (key.length > 16) { + key = sha1(key, keyLength); + } + ipad = (function() { + var _i, _results; + _results = []; + for (i = _i = 0; _i < 16; i = ++_i) { + _results.push(key[i] ^ 0x36363636); + } + return _results; + })(); + opad = (function() { + var _i, _results; + _results = []; + for (i = _i = 0; _i < 16; i = ++_i) { + _results.push(key[i] ^ 0x5C5C5C5C); + } + return _results; + })(); + hash1 = sha1(ipad.concat(string), 64 + length); + return sha1(opad.concat(hash1), 64 + 20); + }; + + sha1 = function(string, length) { + var a, a0, b, b0, c, c0, d, d0, e, e0, ft, i, j, kt, limit, state, t, _i; + string[length >> 2] |= 1 << (31 - ((length & 0x03) << 3)); + string[(((length + 8) >> 6) << 4) + 15] = length << 3; + state = Array(80); + a = 1732584193; + b = -271733879; + c = -1732584194; + d = 271733878; + e = -1009589776; + i = 0; + limit = string.length; + while (i < limit) { + a0 = a; + b0 = b; + c0 = c; + d0 = d; + e0 = e; + for (j = _i = 0; _i < 80; j = ++_i) { + if (j < 16) { + state[j] = string[i + j]; + } else { + state[j] = rotateLeft32(state[j - 3] ^ state[j - 8] ^ state[j - 14] ^ state[j - 16], 1); + } + if (j < 20) { + ft = (b & c) | ((~b) & d); + kt = 1518500249; + } else if (j < 40) { + ft = b ^ c ^ d; + kt = 1859775393; + } else if (j < 60) { + ft = (b & c) | (b & d) | (c & d); + kt = -1894007588; + } else { + ft = b ^ c ^ d; + kt = -899497514; + } + t = add32(add32(rotateLeft32(a, 5), ft), add32(add32(e, state[j]), kt)); + e = d; + d = c; + c = rotateLeft32(b, 30); + b = a; + a = t; + } + a = add32(a, a0); + b = add32(b, b0); + c = add32(c, c0); + d = add32(d, d0); + e = add32(e, e0); + i += 16; + } + return [a, b, c, d, e]; + }; + + /* + # Uncomment the definition below for debugging. + # + # Returns the hexadecimal representation of a 32-bit number. + xxx = (n) -> + if n < 0 + n = (1 << 30) * 4 + n + n.toString 16 + */ + + + rotateLeft32 = function(value, count) { + return (value << count) | (value >>> (32 - count)); + }; + + add32 = function(a, b) { + var high, low; + low = (a & 0xFFFF) + (b & 0xFFFF); + high = (a >> 16) + (b >> 16) + (low >> 16); + return (high << 16) | (low & 0xFFFF); + }; + + arrayToBase64 = function(array) { + var i, i2, limit, string, trit; + string = ""; + i = 0; + limit = array.length * 4; + while (i < limit) { + i2 = i; + trit = ((array[i2 >> 2] >> ((3 - (i2 & 3)) << 3)) & 0xFF) << 16; + i2 += 1; + trit |= ((array[i2 >> 2] >> ((3 - (i2 & 3)) << 3)) & 0xFF) << 8; + i2 += 1; + trit |= (array[i2 >> 2] >> ((3 - (i2 & 3)) << 3)) & 0xFF; + string += _base64Digits[(trit >> 18) & 0x3F]; + string += _base64Digits[(trit >> 12) & 0x3F]; + i += 1; + if (i >= limit) { + string += '='; + } else { + string += _base64Digits[(trit >> 6) & 0x3F]; + } + i += 1; + if (i >= limit) { + string += '='; + } else { + string += _base64Digits[trit & 0x3F]; + } + i += 1; + } + return string; + }; + + _base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + stringToArray = function(string) { + var array, i, mask, _i, _ref; + array = []; + mask = 0xFF; + for (i = _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + array[i >> 2] |= (string.charCodeAt(i) & mask) << ((3 - (i & 3)) << 3); + } + return array; + }; + + Dropbox.Oauth = (function() { + + function Oauth(options) { + this.key = this.k = null; + this.secret = this.s = null; + this.token = null; + this.tokenSecret = null; + this._appHash = null; + this.reset(options); + } + + Oauth.prototype.reset = function(options) { + var k, s, secret, _ref; + if (options.secret) { + this.k = this.key = options.key; + this.s = this.secret = options.secret; + this._appHash = null; + } else if (options.key) { + this.key = options.key; + this.secret = null; + secret = atob(dropboxEncodeKey(this.key).split('|', 2)[1]); + _ref = secret.split('?', 2), k = _ref[0], s = _ref[1]; + this.k = decodeURIComponent(k); + this.s = decodeURIComponent(s); + this._appHash = null; + } else { + if (!this.k) { + throw new Error('No API key supplied'); + } + } + if (options.token) { + return this.setToken(options.token, options.tokenSecret); + } else { + return this.setToken(null, ''); + } + }; + + Oauth.prototype.setToken = function(token, tokenSecret) { + if (token && (!tokenSecret)) { + throw new Error('No secret supplied with the user token'); + } + this.token = token; + this.tokenSecret = tokenSecret || ''; + this.hmacKey = Dropbox.Xhr.urlEncodeValue(this.s) + '&' + Dropbox.Xhr.urlEncodeValue(tokenSecret); + return null; + }; + + Oauth.prototype.authHeader = function(method, url, params) { + var header, oauth_params, param, value, _i, _len; + this.addAuthParams(method, url, params); + oauth_params = []; + for (param in params) { + value = params[param]; + if (param.substring(0, 6) === 'oauth_') { + oauth_params.push(param); + } + } + oauth_params.sort(); + header = []; + for (_i = 0, _len = oauth_params.length; _i < _len; _i++) { + param = oauth_params[_i]; + header.push(Dropbox.Xhr.urlEncodeValue(param) + '="' + Dropbox.Xhr.urlEncodeValue(params[param]) + '"'); + delete params[param]; + } + return 'OAuth ' + header.join(','); + }; + + Oauth.prototype.addAuthParams = function(method, url, params) { + this.boilerplateParams(params); + params.oauth_signature = this.signature(method, url, params); + return params; + }; + + Oauth.prototype.boilerplateParams = function(params) { + params.oauth_consumer_key = this.k; + params.oauth_nonce = this.nonce(); + params.oauth_signature_method = 'HMAC-SHA1'; + if (this.token) { + params.oauth_token = this.token; + } + params.oauth_timestamp = Math.floor(Date.now() / 1000); + params.oauth_version = '1.0'; + return params; + }; + + Oauth.prototype.nonce = function() { + return Date.now().toString(36) + Math.random().toString(36); + }; + + Oauth.prototype.signature = function(method, url, params) { + var string; + string = method.toUpperCase() + '&' + Dropbox.Xhr.urlEncodeValue(url) + '&' + Dropbox.Xhr.urlEncodeValue(Dropbox.Xhr.urlEncode(params)); + return base64HmacSha1(string, this.hmacKey); + }; + + Oauth.prototype.appHash = function() { + if (this._appHash) { + return this._appHash; + } + return this._appHash = base64Sha1(this.k).replace(/\=/g, ''); + }; + + return Oauth; + + })(); + + if (Date.now == null) { + Date.now = function() { + return (new Date()).getTime(); + }; + } + + dropboxEncodeKey = function(key, secret) { + var i, k, result, s, x, y, z, _i, _j, _ref, _ref1, _results; + if (secret) { + secret = [encodeURIComponent(key), encodeURIComponent(secret)].join('?'); + key = (function() { + var _i, _ref, _results; + _results = []; + for (i = _i = 0, _ref = key.length / 2; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + _results.push(((key.charCodeAt(i * 2) & 15) * 16) + (key.charCodeAt(i * 2 + 1) & 15)); + } + return _results; + })(); + } else { + _ref = key.split('|', 2), key = _ref[0], secret = _ref[1]; + key = atob(key); + key = (function() { + var _i, _ref1, _results; + _results = []; + for (i = _i = 0, _ref1 = key.length; 0 <= _ref1 ? _i < _ref1 : _i > _ref1; i = 0 <= _ref1 ? ++_i : --_i) { + _results.push(key.charCodeAt(i)); + } + return _results; + })(); + secret = atob(secret); + } + s = (function() { + _results = []; + for (_i = 0; _i < 256; _i++){ _results.push(_i); } + return _results; + }).apply(this); + y = 0; + for (x = _j = 0; _j < 256; x = ++_j) { + y = (y + s[i] + key[x % key.length]) % 256; + _ref1 = [s[y], s[x]], s[x] = _ref1[0], s[y] = _ref1[1]; + } + x = y = 0; + result = (function() { + var _k, _ref2, _ref3, _results1; + _results1 = []; + for (z = _k = 0, _ref2 = secret.length; 0 <= _ref2 ? _k < _ref2 : _k > _ref2; z = 0 <= _ref2 ? ++_k : --_k) { + x = (x + 1) % 256; + y = (y + s[x]) % 256; + _ref3 = [s[y], s[x]], s[x] = _ref3[0], s[y] = _ref3[1]; + k = s[(s[x] + s[y]) % 256]; + _results1.push(String.fromCharCode((k ^ secret.charCodeAt(z)) % 256)); + } + return _results1; + })(); + key = (function() { + var _k, _ref2, _results1; + _results1 = []; + for (i = _k = 0, _ref2 = key.length; 0 <= _ref2 ? _k < _ref2 : _k > _ref2; i = 0 <= _ref2 ? ++_k : --_k) { + _results1.push(String.fromCharCode(key[i])); + } + return _results1; + })(); + return [btoa(key.join('')), btoa(result.join(''))].join('|'); + }; + + Dropbox.PulledChanges = (function() { + + PulledChanges.parse = function(deltaInfo) { + if (deltaInfo && typeof deltaInfo === 'object') { + return new Dropbox.PulledChanges(deltaInfo); + } else { + return deltaInfo; + } + }; + + PulledChanges.prototype.blankSlate = void 0; + + PulledChanges.prototype.cursorTag = void 0; + + PulledChanges.prototype.changes = void 0; + + PulledChanges.prototype.shouldPullAgain = void 0; + + PulledChanges.prototype.shouldBackOff = void 0; + + function PulledChanges(deltaInfo) { + var entry; + this.blankSlate = deltaInfo.reset || false; + this.cursorTag = deltaInfo.cursor; + this.shouldPullAgain = deltaInfo.has_more; + this.shouldBackOff = !this.shouldPullAgain; + if (deltaInfo.cursor && deltaInfo.cursor.length) { + this.changes = (function() { + var _i, _len, _ref, _results; + _ref = deltaInfo.entries; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + entry = _ref[_i]; + _results.push(Dropbox.PullChange.parse(entry)); + } + return _results; + })(); + } else { + this.changes = []; + } + } + + return PulledChanges; + + })(); + + Dropbox.PullChange = (function() { + + PullChange.parse = function(entry) { + if (entry && typeof entry === 'object') { + return new Dropbox.PullChange(entry); + } else { + return entry; + } + }; + + PullChange.prototype.path = void 0; + + PullChange.prototype.wasRemoved = void 0; + + PullChange.prototype.stat = void 0; + + function PullChange(entry) { + this.path = entry[0]; + this.stat = Dropbox.Stat.parse(entry[1]); + if (this.stat) { + this.wasRemoved = false; + } else { + this.stat = null; + this.wasRemoved = true; + } + } + + return PullChange; + + })(); + + Dropbox.PublicUrl = (function() { + + PublicUrl.parse = function(urlData, isDirect) { + if (urlData && typeof urlData === 'object') { + return new Dropbox.PublicUrl(urlData, isDirect); + } else { + return urlData; + } + }; + + PublicUrl.prototype.url = void 0; + + PublicUrl.prototype.expiresAt = void 0; + + PublicUrl.prototype.isDirect = void 0; + + PublicUrl.prototype.isPreview = void 0; + + function PublicUrl(urlData, isDirect) { + this.url = urlData.url; + this.expiresAt = new Date(Date.parse(urlData.expires)); + if (isDirect === true) { + this.isDirect = true; + } else if (isDirect === false) { + this.isDirect = false; + } else { + this.isDirect = Date.now() - this.expiresAt <= 86400000; + } + this.isPreview = !this.isDirect; + } + + return PublicUrl; + + })(); + + Dropbox.CopyReference = (function() { + + CopyReference.parse = function(refData) { + if (refData && (typeof refData === 'object' || typeof refData === 'string')) { + return new Dropbox.CopyReference(refData); + } else { + return refData; + } + }; + + CopyReference.prototype.tag = void 0; + + CopyReference.prototype.expiresAt = void 0; + + function CopyReference(refData) { + if (typeof refData === 'object') { + this.tag = refData.copy_ref; + this.expiresAt = new Date(Date.parse(refData.expires)); + } else { + this.tag = refData; + this.expiresAt = new Date(); + } + } + + return CopyReference; + + })(); + + Dropbox.Stat = (function() { + + Stat.parse = function(metadata) { + if (metadata && typeof metadata === 'object') { + return new Dropbox.Stat(metadata); + } else { + return metadata; + } + }; + + Stat.prototype.path = null; + + Stat.prototype.name = null; + + Stat.prototype.inAppFolder = null; + + Stat.prototype.isFolder = null; + + Stat.prototype.isFile = null; + + Stat.prototype.isRemoved = null; + + Stat.prototype.typeIcon = null; + + Stat.prototype.versionTag = null; + + Stat.prototype.mimeType = null; + + Stat.prototype.size = null; + + Stat.prototype.humanSize = null; + + Stat.prototype.hasThumbnail = null; + + Stat.prototype.modifiedAt = null; + + Stat.prototype.clientModifiedAt = null; + + function Stat(metadata) { + var lastIndex, nameSlash, _ref, _ref1; + this.path = metadata.path; + if (this.path.substring(0, 1) !== '/') { + this.path = '/' + this.path; + } + lastIndex = this.path.length - 1; + if (lastIndex >= 0 && this.path.substring(lastIndex) === '/') { + this.path = this.path.substring(0, lastIndex); + } + nameSlash = this.path.lastIndexOf('/'); + this.name = this.path.substring(nameSlash + 1); + this.isFolder = metadata.is_dir || false; + this.isFile = !this.isFolder; + this.isRemoved = metadata.is_deleted || false; + this.typeIcon = metadata.icon; + if ((_ref = metadata.modified) != null ? _ref.length : void 0) { + this.modifiedAt = new Date(Date.parse(metadata.modified)); + } else { + this.modifiedAt = null; + } + if ((_ref1 = metadata.client_mtime) != null ? _ref1.length : void 0) { + this.clientModifiedAt = new Date(Date.parse(metadata.client_mtime)); + } else { + this.clientModifiedAt = null; + } + switch (metadata.root) { + case 'dropbox': + this.inAppFolder = false; + break; + case 'app_folder': + this.inAppFolder = true; + break; + default: + this.inAppFolder = null; + } + this.size = metadata.bytes || 0; + this.humanSize = metadata.size || ''; + this.hasThumbnail = metadata.thumb_exists || false; + if (this.isFolder) { + this.versionTag = metadata.hash; + this.mimeType = metadata.mime_type || 'inode/directory'; + } else { + this.versionTag = metadata.rev; + this.mimeType = metadata.mime_type || 'application/octet-stream'; + } + } + + return Stat; + + })(); + + Dropbox.UserInfo = (function() { + + UserInfo.parse = function(userInfo) { + if (userInfo && typeof userInfo === 'object') { + return new Dropbox.UserInfo(userInfo); + } else { + return userInfo; + } + }; + + UserInfo.prototype.name = null; + + UserInfo.prototype.email = null; + + UserInfo.prototype.countryCode = null; + + UserInfo.prototype.uid = null; + + UserInfo.prototype.referralUrl = null; + + UserInfo.prototype.publicAppUrl = null; + + UserInfo.prototype.quota = null; + + UserInfo.prototype.usedQuota = null; + + UserInfo.prototype.privateBytes = null; + + UserInfo.prototype.sharedBytes = null; + + function UserInfo(userInfo) { + var lastIndex; + this.name = userInfo.display_name; + this.email = userInfo.email; + this.countryCode = userInfo.country || null; + this.uid = userInfo.uid.toString(); + if (userInfo.public_app_url) { + this.publicAppUrl = userInfo.public_app_url; + lastIndex = this.publicAppUrl.length - 1; + if (lastIndex >= 0 && this.publicAppUrl.substring(lastIndex) === '/') { + this.publicAppUrl = this.publicAppUrl.substring(0, lastIndex); + } + } else { + this.publicAppUrl = null; + } + this.referralUrl = userInfo.referral_link; + this.quota = userInfo.quota_info.quota; + this.privateBytes = userInfo.quota_info.normal || 0; + this.sharedBytes = userInfo.quota_info.shared || 0; + this.usedQuota = this.privateBytes + this.sharedBytes; + } + + return UserInfo; + + })(); + + if (typeof window !== "undefined" && window !== null) { + if (window.XDomainRequest && !('withCredentials' in new XMLHttpRequest())) { + DropboxXhrRequest = window.XDomainRequest; + DropboxXhrIeMode = true; + DropboxXhrCanSendForms = false; + } else { + DropboxXhrRequest = window.XMLHttpRequest; + DropboxXhrIeMode = false; + DropboxXhrCanSendForms = window.navigator.userAgent.indexOf('Firefox') === -1; + } + DropboxXhrDoesPreflight = true; + } else { + DropboxXhrRequest = require('xmlhttprequest').XMLHttpRequest; + DropboxXhrIeMode = false; + DropboxXhrCanSendForms = false; + DropboxXhrDoesPreflight = false; + } + + if (typeof Uint8Array === 'undefined') { + DropboxXhrArrayBufferView = null; + } else { + DropboxXhrArrayBufferView = (new Uint8Array(0)).__proto__.__proto__.constructor; + } + + Dropbox.Xhr = (function() { + + Xhr.Request = DropboxXhrRequest; + + Xhr.ieMode = DropboxXhrIeMode; + + Xhr.canSendForms = DropboxXhrCanSendForms; + + Xhr.doesPreflight = DropboxXhrDoesPreflight; + + Xhr.ArrayBufferView = DropboxXhrArrayBufferView; + + function Xhr(method, baseUrl) { + this.method = method; + this.isGet = this.method === 'GET'; + this.url = baseUrl; + this.headers = {}; + this.params = null; + this.body = null; + this.preflight = !(this.isGet || (this.method === 'POST')); + this.signed = false; + this.responseType = null; + this.callback = null; + this.xhr = null; + } + + Xhr.prototype.setParams = function(params) { + if (this.signed) { + throw new Error('setParams called after addOauthParams or addOauthHeader'); + } + if (this.params) { + throw new Error('setParams cannot be called twice'); + } + this.params = params; + return this; + }; + + Xhr.prototype.setCallback = function(callback) { + this.callback = callback; + return this; + }; + + Xhr.prototype.signWithOauth = function(oauth) { + if (Dropbox.Xhr.ieMode || (Dropbox.Xhr.doesPreflight && (!this.preflight))) { + return this.addOauthParams(oauth); + } else { + return this.addOauthHeader(oauth); + } + }; + + Xhr.prototype.addOauthParams = function(oauth) { + if (this.signed) { + throw new Error('Request already has an OAuth signature'); + } + this.params || (this.params = {}); + oauth.addAuthParams(this.method, this.url, this.params); + this.signed = true; + return this; + }; + + Xhr.prototype.addOauthHeader = function(oauth) { + if (this.signed) { + throw new Error('Request already has an OAuth signature'); + } + this.params || (this.params = {}); + this.signed = true; + return this.setHeader('Authorization', oauth.authHeader(this.method, this.url, this.params)); + }; + + Xhr.prototype.setBody = function(body) { + if (this.isGet) { + throw new Error('setBody cannot be called on GET requests'); + } + if (this.body !== null) { + throw new Error('Request already has a body'); + } + if (!this.preflight) { + if (!((typeof FormData !== 'undefined') && (body instanceof FormData))) { + this.preflight = true; + } + } + this.body = body; + return this; + }; + + Xhr.prototype.setResponseType = function(responseType) { + this.responseType = responseType; + return this; + }; + + Xhr.prototype.setHeader = function(headerName, value) { + var oldValue; + if (this.headers[headerName]) { + oldValue = this.headers[headerName]; + throw new Error("HTTP header " + headerName + " already set to " + oldValue); + } + if (headerName === 'Content-Type') { + throw new Error('Content-Type is automatically computed based on setBody'); + } + this.preflight = true; + this.headers[headerName] = value; + return this; + }; + + Xhr.prototype.setFileField = function(fieldName, fileName, fileData, contentType) { + var boundary, useFormData; + if (this.body !== null) { + throw new Error('Request already has a body'); + } + if (this.isGet) { + throw new Error('paramsToBody cannot be called on GET requests'); + } + if (typeof fileData === 'object' && typeof Blob !== 'undefined') { + if ((typeof ArrayBuffer !== "undefined" && ArrayBuffer !== null) && fileData instanceof ArrayBuffer) { + fileData = new Uint8Array(fileData); + } + if (Dropbox.Xhr.ArrayBufferView && fileData instanceof Dropbox.Xhr.ArrayBufferView) { + contentType || (contentType = 'application/octet-stream'); + fileData = new Blob([fileData], { + type: contentType + }); + } + if (typeof File !== 'undefined' && fileData instanceof File) { + fileData = new Blob([fileData], { + type: fileData.type + }); + } + useFormData = fileData instanceof Blob; + } else { + useFormData = false; + } + if (useFormData) { + this.body = new FormData(); + return this.body.append(fieldName, fileData, fileName); + } else { + contentType || (contentType = 'application/octet-stream'); + boundary = this.multipartBoundary(); + this.headers['Content-Type'] = "multipart/form-data; boundary=" + boundary; + return this.body = ['--', boundary, "\r\n", 'Content-Disposition: form-data; name="', fieldName, '"; filename="', fileName, "\"\r\n", 'Content-Type: ', contentType, "\r\n", "Content-Transfer-Encoding: binary\r\n\r\n", fileData, "\r\n", '--', boundary, '--', "\r\n"].join(''); + } + }; + + Xhr.prototype.multipartBoundary = function() { + return [Date.now().toString(36), Math.random().toString(36)].join('----'); + }; + + Xhr.prototype.paramsToUrl = function() { + var queryString; + if (this.params) { + queryString = Dropbox.Xhr.urlEncode(this.params); + if (queryString.length !== 0) { + this.url = [this.url, '?', queryString].join(''); + } + this.params = null; + } + return this; + }; + + Xhr.prototype.paramsToBody = function() { + if (this.params) { + if (this.body !== null) { + throw new Error('Request already has a body'); + } + if (this.isGet) { + throw new Error('paramsToBody cannot be called on GET requests'); + } + this.headers['Content-Type'] = 'application/x-www-form-urlencoded'; + this.body = Dropbox.Xhr.urlEncode(this.params); + this.params = null; + } + return this; + }; + + Xhr.prototype.prepare = function() { + var header, ieMode, value, _ref, + _this = this; + ieMode = Dropbox.Xhr.ieMode; + if (this.isGet || this.body !== null || ieMode) { + this.paramsToUrl(); + if (this.body !== null && typeof this.body === 'string') { + this.headers['Content-Type'] = 'text/plain; charset=utf8'; + } + } else { + this.paramsToBody(); + } + this.xhr = new Dropbox.Xhr.Request(); + if (ieMode) { + this.xhr.onload = function() { + return _this.onLoad(); + }; + this.xhr.onerror = function() { + return _this.onError(); + }; + } else { + this.xhr.onreadystatechange = function() { + return _this.onReadyStateChange(); + }; + } + this.xhr.open(this.method, this.url, true); + if (!ieMode) { + _ref = this.headers; + for (header in _ref) { + if (!__hasProp.call(_ref, header)) continue; + value = _ref[header]; + this.xhr.setRequestHeader(header, value); + } + } + if (this.responseType) { + if (this.responseType === 'b') { + if (this.xhr.overrideMimeType) { + this.xhr.overrideMimeType('text/plain; charset=x-user-defined'); + } + } else { + this.xhr.responseType = this.responseType; + } + } + return this; + }; + + Xhr.prototype.send = function(callback) { + var body; + this.callback = callback || this.callback; + if (this.body !== null) { + body = this.body; + if (Dropbox.Xhr.ArrayBufferView && body instanceof ArrayBuffer) { + body = new Uint8Array(body); + } + try { + this.xhr.send(body); + } catch (e) { + if (typeof Blob !== 'undefined' && Dropbox.Xhr.ArrayBufferView && body instanceof Dropbox.Xhr.ArrayBufferView) { + body = new Blob([body], { + type: 'application/octet-stream' + }); + this.xhr.send(body); + } else { + throw e; + } + } + } else { + this.xhr.send(); + } + return this; + }; + + Xhr.urlEncode = function(object) { + var chunks, key, value; + chunks = []; + for (key in object) { + value = object[key]; + chunks.push(this.urlEncodeValue(key) + '=' + this.urlEncodeValue(value)); + } + return chunks.sort().join('&'); + }; + + Xhr.urlEncodeValue = function(object) { + return encodeURIComponent(object.toString()).replace(/\!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A'); + }; + + Xhr.urlDecode = function(string) { + var kvp, result, token, _i, _len, _ref; + result = {}; + _ref = string.split('&'); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + token = _ref[_i]; + kvp = token.split('='); + result[decodeURIComponent(kvp[0])] = decodeURIComponent(kvp[1]); + } + return result; + }; + + Xhr.prototype.onReadyStateChange = function() { + var apiError, bytes, dirtyText, i, metadata, metadataJson, text, _i, _ref; + if (this.xhr.readyState !== 4) { + return true; + } + if (this.xhr.status < 200 || this.xhr.status >= 300) { + apiError = new Dropbox.ApiError(this.xhr, this.method, this.url); + this.callback(apiError); + return true; + } + metadataJson = this.xhr.getResponseHeader('x-dropbox-metadata'); + if (metadataJson != null ? metadataJson.length : void 0) { + try { + metadata = JSON.parse(metadataJson); + } catch (e) { + metadata = void 0; + } + } else { + metadata = void 0; + } + if (this.responseType) { + if (this.responseType === 'b') { + dirtyText = this.xhr.responseText != null ? this.xhr.responseText : this.xhr.response; + /* + jsString = ['["'] + for i in [0...dirtyText.length] + hexByte = (dirtyText.charCodeAt(i) & 0xFF).toString(16) + if hexByte.length is 2 + jsString.push "\\u00#{hexByte}" + else + jsString.push "\\u000#{hexByte}" + jsString.push '"]' + console.log jsString + text = JSON.parse(jsString.join(''))[0] + */ + + bytes = []; + for (i = _i = 0, _ref = dirtyText.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + bytes.push(String.fromCharCode(dirtyText.charCodeAt(i) & 0xFF)); + } + text = bytes.join(''); + this.callback(null, text, metadata); + } else { + this.callback(null, this.xhr.response, metadata); + } + return true; + } + text = this.xhr.responseText != null ? this.xhr.responseText : this.xhr.response; + switch (this.xhr.getResponseHeader('Content-Type')) { + case 'application/x-www-form-urlencoded': + this.callback(null, Dropbox.Xhr.urlDecode(text), metadata); + break; + case 'application/json': + case 'text/javascript': + this.callback(null, JSON.parse(text), metadata); + break; + default: + this.callback(null, text, metadata); + } + return true; + }; + + Xhr.prototype.onLoad = function() { + var text; + text = this.xhr.responseText; + switch (this.xhr.contentType) { + case 'application/x-www-form-urlencoded': + this.callback(null, Dropbox.Xhr.urlDecode(text), void 0); + break; + case 'application/json': + case 'text/javascript': + this.callback(null, JSON.parse(text), void 0); + break; + default: + this.callback(null, text, void 0); + } + return true; + }; + + Xhr.prototype.onError = function() { + var apiError; + apiError = new Dropbox.ApiError(this.xhr, this.method, this.url); + this.callback(apiError); + return true; + }; + + return Xhr; + + })(); + + if ((typeof module !== "undefined" && module !== null ? module.exports : void 0) != null) { + module.exports = Dropbox; + } else if (typeof window !== "undefined" && window !== null) { + window.Dropbox = Dropbox; + } else { + throw new Error('This library only supports node.js and modern browsers.'); + } + + Dropbox.atob = atob; + + Dropbox.btoa = btoa; + + Dropbox.hmac = base64HmacSha1; + + Dropbox.sha1 = base64Sha1; + + Dropbox.encodeKey = dropboxEncodeKey; + +}).call(this);