--- /dev/null
+var hiddenKeys = require('../internals/hidden-keys');
+var isObject = require('../internals/is-object');
+var has = require('../internals/has');
+var defineProperty = require('../internals/object-define-property').f;
+var uid = require('../internals/uid');
+var FREEZING = require('../internals/freezing');
+
+var METADATA = uid('meta');
+var id = 0;
+
+var isExtensible = Object.isExtensible || function () {
+ return true;
+};
+
+var setMetadata = function (it) {
+ defineProperty(it, METADATA, { value: {
+ objectID: 'O' + ++id, // object ID
+ weakData: {} // weak collections IDs
+ } });
+};
+
+var fastKey = function (it, create) {
+ // return a primitive with prefix
+ if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
+ if (!has(it, METADATA)) {
+ // can't set metadata to uncaught frozen object
+ if (!isExtensible(it)) return 'F';
+ // not necessary to add metadata
+ if (!create) return 'E';
+ // add missing metadata
+ setMetadata(it);
+ // return object ID
+ } return it[METADATA].objectID;
+};
+
+var getWeakData = function (it, create) {
+ if (!has(it, METADATA)) {
+ // can't set metadata to uncaught frozen object
+ if (!isExtensible(it)) return true;
+ // not necessary to add metadata
+ if (!create) return false;
+ // add missing metadata
+ setMetadata(it);
+ // return the store of weak collections IDs
+ } return it[METADATA].weakData;
+};
+
+// add metadata on freeze-family methods calling
+var onFreeze = function (it) {
+ if (FREEZING && meta.REQUIRED && isExtensible(it) && !has(it, METADATA)) setMetadata(it);
+ return it;
+};
+
+var meta = module.exports = {
+ REQUIRED: false,
+ fastKey: fastKey,
+ getWeakData: getWeakData,
+ onFreeze: onFreeze
+};
+
+hiddenKeys[METADATA] = true;