text: // Copyright IBM Corp. 2013,2015. All Rights Reserved.
  // Node module: strong-data-uri
  // This file is licensed under the Artistic License 2.0.
  // License text available at https://opensource.org/licenses/Artistic-2.0
  
  /* Copyright (c) 2013 StrongLoop, Inc.
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy
   * of this software and associated documentation files (the "Software"), to deal
   * in the Software without restriction, including without limitation the rights
   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the Software is
   * furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included
   * in all copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   * THE SOFTWARE.
   */
  'use strict';
  
  var truncate = require('truncate');
  
  /**
   * Decode payload in the given data URI, return the result as a Buffer.
   * See [RFC2397](http://www.ietf.org/rfc/rfc2397.txt) for the specification
   * of data URL scheme.
   * @param {String} uri
   * @returns {Buffer}
   */
  function decode(uri) {
  
    //  dataurl    := "data:" [ mediatype ] [ ";base64" ] "," data
    //  mediatype  := [ type "/" subtype ] *( ";" parameter )
    //  data       := *urlchar
    //  parameter  := attribute "=" value
  
    var m = /^data:([^;,]+)?((?:;(?:[^;,]+))*?)(;base64)?,(.*)/.exec(uri);
    if (!m) {
      throw new Error('Not a valid data URI: "' + truncate(uri, 20) + '"');
    }
  
    var media    = '';
    var b64      = m[3];
    var body     = m[4];
    var result   = null;
    var charset  = null;
    var mimetype = null;
  
    // If <mediatype> is omitted, it defaults to text/plain;charset=US-ASCII.
    // As a shorthand, "text/plain" can be omitted but the charset parameter
    // supplied.
    if (m[1]) {
      mimetype = m[1];
      media = mimetype + (m[2] || '');
    } else {
      mimetype = 'text/plain';
      if (m[2]) {
        media = mimetype + m[2];
      } else {
        charset = 'US-ASCII';
        media = 'text/plain;charset=US-ASCII';
      }
    }
  
    // The RFC doesn't say what the default encoding is if there is a mediatype
    // so we will return null.  For example, charset doesn't make sense for
    // binary types like image/png
    if (!charset && m[2]) {
      var cm = /;charset=([^;,]+)/.exec(m[2]);
      if (cm) {
        charset = cm[1];
      }
    }
  
    if (b64) {
      result = new Buffer(body, 'base64');
    } else {
      result = new Buffer(decodeURIComponent(body), 'ascii');
    }
  
    result.mimetype  = mimetype;
    result.mediatype = media;
    result.charset   = charset;
  
    return result;
  }
  
  exports.decode = decode;
  
  function encode(input, mediatype) {
    var buf;
    if (Buffer.isBuffer(input)) {
      buf = input;
      mediatype = mediatype || 'application/octet-stream';
    } else if (typeof(input) == 'string') {
      buf = new Buffer(input, 'utf8');
      mediatype = mediatype || 'text/plain;charset=UTF-8';
    } else {
      // TODO: support streams?
      throw new Error('Invalid input, expected Buffer or string');
    }
    // opinionatedly base64
    return 'data:' + mediatype + ';base64,' + buf.toString('base64');
  }
  
  exports.encode = encode;
  