1var META = require('./_uid')('meta');
2var isObject = require('./_is-object');
3var has = require('./_has');
4var setDesc = require('./_object-dp').f;
5var id = 0;
6var isExtensible = Object.isExtensible || function () {
7  return true;
8};
9var FREEZE = !require('./_fails')(function () {
10  return isExtensible(Object.preventExtensions({}));
11});
12var setMeta = function (it) {
13  setDesc(it, META, { value: {
14    i: 'O' + ++id, // object ID
15    w: {}          // weak collections IDs
16  } });
17};
18var fastKey = function (it, create) {
19  // return primitive with prefix
20  if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
21  if (!has(it, META)) {
22    // can't set metadata to uncaught frozen object
23    if (!isExtensible(it)) return 'F';
24    // not necessary to add metadata
25    if (!create) return 'E';
26    // add missing metadata
27    setMeta(it);
28  // return object ID
29  } return it[META].i;
30};
31var getWeak = function (it, create) {
32  if (!has(it, META)) {
33    // can't set metadata to uncaught frozen object
34    if (!isExtensible(it)) return true;
35    // not necessary to add metadata
36    if (!create) return false;
37    // add missing metadata
38    setMeta(it);
39  // return hash weak collections IDs
40  } return it[META].w;
41};
42// add metadata on freeze-family methods calling
43var onFreeze = function (it) {
44  if (FREEZE && meta.NEED && isExtensible(it) && !has(it, META)) setMeta(it);
45  return it;
46};
47var meta = module.exports = {
48  KEY: META,
49  NEED: false,
50  fastKey: fastKey,
51  getWeak: getWeak,
52  onFreeze: onFreeze
53};
54