1var global = require('./_global');
2var core = require('./_core');
3var ctx = require('./_ctx');
4var hide = require('./_hide');
5var has = require('./_has');
6var PROTOTYPE = 'prototype';
7
8var $export = function (type, name, source) {
9  var IS_FORCED = type & $export.F;
10  var IS_GLOBAL = type & $export.G;
11  var IS_STATIC = type & $export.S;
12  var IS_PROTO = type & $export.P;
13  var IS_BIND = type & $export.B;
14  var IS_WRAP = type & $export.W;
15  var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});
16  var expProto = exports[PROTOTYPE];
17  var target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE];
18  var key, own, out;
19  if (IS_GLOBAL) source = name;
20  for (key in source) {
21    // contains in native
22    own = !IS_FORCED && target && target[key] !== undefined;
23    if (own && has(exports, key)) continue;
24    // export native or passed
25    out = own ? target[key] : source[key];
26    // prevent global pollution for namespaces
27    exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]
28    // bind timers to global for call from export context
29    : IS_BIND && own ? ctx(out, global)
30    // wrap global constructors for prevent change them in library
31    : IS_WRAP && target[key] == out ? (function (C) {
32      var F = function (a, b, c) {
33        if (this instanceof C) {
34          switch (arguments.length) {
35            case 0: return new C();
36            case 1: return new C(a);
37            case 2: return new C(a, b);
38          } return new C(a, b, c);
39        } return C.apply(this, arguments);
40      };
41      F[PROTOTYPE] = C[PROTOTYPE];
42      return F;
43    // make static versions for prototype methods
44    })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
45    // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%
46    if (IS_PROTO) {
47      (exports.virtual || (exports.virtual = {}))[key] = out;
48      // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%
49      if (type & $export.R && expProto && !expProto[key]) hide(expProto, key, out);
50    }
51  }
52};
53// type bitmap
54$export.F = 1;   // forced
55$export.G = 2;   // global
56$export.S = 4;   // static
57$export.P = 8;   // proto
58$export.B = 16;  // bind
59$export.W = 32;  // wrap
60$export.U = 64;  // safe
61$export.R = 128; // real proto method for `library`
62module.exports = $export;
63