diff --git a/dist/amd/can-reflect.js b/dist/amd/can-reflect.js
new file mode 100644
index 0000000..692d08e
--- /dev/null
+++ b/dist/amd/can-reflect.js
@@ -0,0 +1,39 @@
+/*can-reflect@1.7.3#can-reflect*/
+define([
+    'require',
+    'exports',
+    'module',
+    './reflections/call/call',
+    './reflections/get-set/get-set',
+    './reflections/observe/observe',
+    './reflections/shape/shape',
+    './reflections/type/type',
+    './reflections/get-name/get-name',
+    'can-namespace',
+    './types/map',
+    './types/set'
+], function (require, exports, module) {
+    var functionReflections = require('./reflections/call/call');
+    var getSet = require('./reflections/get-set/get-set');
+    var observe = require('./reflections/observe/observe');
+    var shape = require('./reflections/shape/shape');
+    var type = require('./reflections/type/type');
+    var getName = require('./reflections/get-name/get-name');
+    var namespace = require('can-namespace');
+    var reflect = {};
+    [
+        functionReflections,
+        getSet,
+        observe,
+        shape,
+        type,
+        getName
+    ].forEach(function (reflections) {
+        for (var prop in reflections) {
+            reflect[prop] = reflections[prop];
+        }
+    });
+    require('./types/map');
+    require('./types/set');
+    module.exports = namespace.Reflect = reflect;
+});
\ No newline at end of file
diff --git a/dist/amd/reflections/call/call.js b/dist/amd/reflections/call/call.js
new file mode 100644
index 0000000..686efae
--- /dev/null
+++ b/dist/amd/reflections/call/call.js
@@ -0,0 +1,45 @@
+/*can-reflect@1.7.3#reflections/call/call*/
+define([
+    'require',
+    'exports',
+    'module',
+    'can-symbol',
+    '../type/type'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    var typeReflections = require('../type/type');
+    module.exports = {
+        call: function (func, context) {
+            var args = [].slice.call(arguments, 2);
+            var apply = func[canSymbol.for('can.apply')];
+            if (apply) {
+                return apply.call(func, context, args);
+            } else {
+                return func.apply(context, args);
+            }
+        },
+        apply: function (func, context, args) {
+            var apply = func[canSymbol.for('can.apply')];
+            if (apply) {
+                return apply.call(func, context, args);
+            } else {
+                return func.apply(context, args);
+            }
+        },
+        'new': function (func) {
+            var args = [].slice.call(arguments, 1);
+            var makeNew = func[canSymbol.for('can.new')];
+            if (makeNew) {
+                return makeNew.apply(func, args);
+            } else {
+                var context = Object.create(func.prototype);
+                var ret = func.apply(context, args);
+                if (typeReflections.isPrimitive(ret)) {
+                    return context;
+                } else {
+                    return ret;
+                }
+            }
+        }
+    };
+});
\ No newline at end of file
diff --git a/dist/amd/reflections/get-name/get-name.js b/dist/amd/reflections/get-name/get-name.js
new file mode 100644
index 0000000..eb430cf
--- /dev/null
+++ b/dist/amd/reflections/get-name/get-name.js
@@ -0,0 +1,49 @@
+/*can-reflect@1.7.3#reflections/get-name/get-name*/
+define([
+    'require',
+    'exports',
+    'module',
+    'can-symbol',
+    '../type/type'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    var typeReflections = require('../type/type');
+    var getNameSymbol = canSymbol.for('can.getName');
+    function setName(obj, nameGetter) {
+        if (typeof nameGetter !== 'function') {
+            var value = nameGetter;
+            nameGetter = function () {
+                return value;
+            };
+        }
+        Object.defineProperty(obj, getNameSymbol, { value: nameGetter });
+    }
+    function getName(obj) {
+        var nameGetter = obj[getNameSymbol];
+        if (nameGetter) {
+            return nameGetter.call(obj);
+        }
+        if (typeof obj === 'function') {
+            return obj.name;
+        }
+        if (obj.constructor && obj !== obj.constructor) {
+            var parent = getName(obj.constructor);
+            if (parent) {
+                if (typeReflections.isValueLike(obj)) {
+                    return parent + '<>';
+                }
+                if (typeReflections.isMoreListLikeThanMapLike(obj)) {
+                    return parent + '[]';
+                }
+                if (typeReflections.isMapLike(obj)) {
+                    return parent + '{}';
+                }
+            }
+        }
+        return undefined;
+    }
+    module.exports = {
+        setName: setName,
+        getName: getName
+    };
+});
\ No newline at end of file
diff --git a/dist/amd/reflections/get-set/get-set.js b/dist/amd/reflections/get-set/get-set.js
new file mode 100644
index 0000000..fa3fdd6
--- /dev/null
+++ b/dist/amd/reflections/get-set/get-set.js
@@ -0,0 +1,117 @@
+/*can-reflect@1.7.3#reflections/get-set/get-set*/
+define([
+    'require',
+    'exports',
+    'module',
+    'can-symbol',
+    '../type/type'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    var typeReflections = require('../type/type');
+    var setKeyValueSymbol = canSymbol.for('can.setKeyValue'), getKeyValueSymbol = canSymbol.for('can.getKeyValue'), getValueSymbol = canSymbol.for('can.getValue'), setValueSymbol = canSymbol.for('can.setValue');
+    var reflections = {
+        setKeyValue: function (obj, key, value) {
+            if (typeReflections.isSymbolLike(key)) {
+                if (typeof key === 'symbol') {
+                    obj[key] = value;
+                } else {
+                    Object.defineProperty(obj, key, {
+                        enumerable: false,
+                        configurable: true,
+                        value: value,
+                        writable: true
+                    });
+                }
+                return;
+            }
+            var setKeyValue = obj[setKeyValueSymbol];
+            if (setKeyValue !== undefined) {
+                return setKeyValue.call(obj, key, value);
+            } else {
+                obj[key] = value;
+            }
+        },
+        getKeyValue: function (obj, key) {
+            var getKeyValue = obj[getKeyValueSymbol];
+            if (getKeyValue) {
+                return getKeyValue.call(obj, key);
+            }
+            return obj[key];
+        },
+        deleteKeyValue: function (obj, key) {
+            var deleteKeyValue = obj[canSymbol.for('can.deleteKeyValue')];
+            if (deleteKeyValue) {
+                return deleteKeyValue.call(obj, key);
+            }
+            delete obj[key];
+        },
+        getValue: function (value) {
+            if (typeReflections.isPrimitive(value)) {
+                return value;
+            }
+            var getValue = value[getValueSymbol];
+            if (getValue) {
+                return getValue.call(value);
+            }
+            return value;
+        },
+        setValue: function (item, value) {
+            var setValue = item && item[setValueSymbol];
+            if (setValue) {
+                return setValue.call(item, value);
+            } else {
+                throw new Error('can-reflect.setValue - Can not set value.');
+            }
+        },
+        splice: function (obj, index, removing, adding) {
+            var howMany;
+            if (typeof removing !== 'number') {
+                var updateValues = obj[canSymbol.for('can.updateValues')];
+                if (updateValues) {
+                    return updateValues.call(obj, index, removing, adding);
+                }
+                howMany = removing.length;
+            } else {
+                howMany = removing;
+            }
+            var splice = obj[canSymbol.for('can.splice')];
+            if (splice) {
+                return splice.call(obj, index, howMany, adding);
+            }
+            return [].splice.apply(obj, [
+                index,
+                howMany
+            ].concat(adding));
+        },
+        addValues: function (obj, adding, index) {
+            var add = obj[canSymbol.for('can.addValues')];
+            if (add) {
+                return add.call(obj, adding, index);
+            }
+            if (Array.isArray(obj) && index === undefined) {
+                return obj.push.apply(obj, adding);
+            }
+            return reflections.splice(obj, index, [], adding);
+        },
+        removeValues: function (obj, removing, index) {
+            var removeValues = obj[canSymbol.for('can.removeValues')];
+            if (removeValues) {
+                return removeValues.call(obj, removing, index);
+            }
+            if (Array.isArray(obj) && index === undefined) {
+                removing.forEach(function (item) {
+                    var index = obj.indexOf(item);
+                    if (index >= 0) {
+                        obj.splice(index, 1);
+                    }
+                });
+                return;
+            }
+            return reflections.splice(obj, index, removing, []);
+        }
+    };
+    reflections.get = reflections.getKeyValue;
+    reflections.set = reflections.setKeyValue;
+    reflections['delete'] = reflections.deleteKeyValue;
+    module.exports = reflections;
+});
\ No newline at end of file
diff --git a/dist/amd/reflections/helpers.js b/dist/amd/reflections/helpers.js
new file mode 100644
index 0000000..f73b7bb
--- /dev/null
+++ b/dist/amd/reflections/helpers.js
@@ -0,0 +1,30 @@
+/*can-reflect@1.7.3#reflections/helpers*/
+define([
+    'require',
+    'exports',
+    'module',
+    'can-symbol'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    module.exports = {
+        makeGetFirstSymbolValue: function (symbolNames) {
+            var symbols = symbolNames.map(function (name) {
+                return canSymbol.for(name);
+            });
+            var length = symbols.length;
+            return function getFirstSymbol(obj) {
+                var index = -1;
+                while (++index < length) {
+                    if (obj[symbols[index]] !== undefined) {
+                        return obj[symbols[index]];
+                    }
+                }
+            };
+        },
+        hasLength: function (list) {
+            var type = typeof list;
+            var length = list && type !== 'boolean' && typeof list !== 'number' && 'length' in list && list.length;
+            return typeof list !== 'function' && (length === 0 || typeof length === 'number' && length > 0 && length - 1 in list);
+        }
+    };
+});
\ No newline at end of file
diff --git a/dist/amd/reflections/observe/observe.js b/dist/amd/reflections/observe/observe.js
new file mode 100644
index 0000000..399c683
--- /dev/null
+++ b/dist/amd/reflections/observe/observe.js
@@ -0,0 +1,86 @@
+/*can-reflect@1.7.3#reflections/observe/observe*/
+define([
+    'require',
+    'exports',
+    'module',
+    'can-symbol'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    var slice = [].slice;
+    function makeFallback(symbolName, fallbackName) {
+        return function (obj, event, handler, queueName) {
+            var method = obj[canSymbol.for(symbolName)];
+            if (method !== undefined) {
+                return method.call(obj, event, handler, queueName);
+            }
+            return this[fallbackName].apply(this, arguments);
+        };
+    }
+    function makeErrorIfMissing(symbolName, errorMessage) {
+        return function (obj) {
+            var method = obj[canSymbol.for(symbolName)];
+            if (method !== undefined) {
+                var args = slice.call(arguments, 1);
+                return method.apply(obj, args);
+            }
+            throw new Error(errorMessage);
+        };
+    }
+    module.exports = {
+        onKeyValue: makeFallback('can.onKeyValue', 'onEvent'),
+        offKeyValue: makeFallback('can.offKeyValue', 'offEvent'),
+        onKeys: makeErrorIfMissing('can.onKeys', 'can-reflect: can not observe an onKeys event'),
+        onKeysAdded: makeErrorIfMissing('can.onKeysAdded', 'can-reflect: can not observe an onKeysAdded event'),
+        onKeysRemoved: makeErrorIfMissing('can.onKeysRemoved', 'can-reflect: can not unobserve an onKeysRemoved event'),
+        getKeyDependencies: makeErrorIfMissing('can.getKeyDependencies', 'can-reflect: can not determine dependencies'),
+        keyHasDependencies: makeErrorIfMissing('can.keyHasDependencies', 'can-reflect: can not determine if this has key dependencies'),
+        onValue: makeErrorIfMissing('can.onValue', 'can-reflect: can not observe value change'),
+        offValue: makeErrorIfMissing('can.offValue', 'can-reflect: can not unobserve value change'),
+        getValueDependencies: makeErrorIfMissing('can.getValueDependencies', 'can-reflect: can not determine dependencies'),
+        valueHasDependencies: makeErrorIfMissing('can.valueHasDependencies', 'can-reflect: can not determine if value has dependencies'),
+        onPatches: makeErrorIfMissing('can.onPatches', 'can-reflect: can not observe patches on object'),
+        offPatches: makeErrorIfMissing('can.offPatches', 'can-reflect: can not unobserve patches on object'),
+        onInstanceBoundChange: makeErrorIfMissing('can.onInstanceBoundChange', 'can-reflect: can not observe bound state change in instances.'),
+        offInstanceBoundChange: makeErrorIfMissing('can.offInstanceBoundChange', 'can-reflect: can not unobserve bound state change'),
+        isBound: makeErrorIfMissing('can.isBound', 'can-reflect: cannot determine if object is bound'),
+        onEvent: function (obj, eventName, callback, queue) {
+            if (obj) {
+                var onEvent = obj[canSymbol.for('can.onEvent')];
+                if (onEvent !== undefined) {
+                    return onEvent.call(obj, eventName, callback, queue);
+                } else if (obj.addEventListener) {
+                    obj.addEventListener(eventName, callback, queue);
+                }
+            }
+        },
+        offEvent: function (obj, eventName, callback, queue) {
+            if (obj) {
+                var offEvent = obj[canSymbol.for('can.offEvent')];
+                if (offEvent !== undefined) {
+                    return offEvent.call(obj, eventName, callback, queue);
+                } else if (obj.removeEventListener) {
+                    obj.removeEventListener(eventName, callback, queue);
+                }
+            }
+        },
+        setPriority: function (obj, priority) {
+            if (obj) {
+                var setPriority = obj[canSymbol.for('can.setPriority')];
+                if (setPriority !== undefined) {
+                    setPriority.call(obj, priority);
+                    return true;
+                }
+            }
+            return false;
+        },
+        getPriority: function (obj) {
+            if (obj) {
+                var getPriority = obj[canSymbol.for('can.getPriority')];
+                if (getPriority !== undefined) {
+                    return getPriority.call(obj);
+                }
+            }
+            return undefined;
+        }
+    };
+});
\ No newline at end of file
diff --git a/dist/amd/reflections/shape/shape.js b/dist/amd/reflections/shape/shape.js
new file mode 100644
index 0000000..30c42f1
--- /dev/null
+++ b/dist/amd/reflections/shape/shape.js
@@ -0,0 +1,517 @@
+/*can-reflect@1.7.3#reflections/shape/shape*/
+define([
+    'require',
+    'exports',
+    'module',
+    'can-symbol',
+    '../get-set/get-set',
+    '../type/type',
+    '../helpers'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    var getSetReflections = require('../get-set/get-set');
+    var typeReflections = require('../type/type');
+    var helpers = require('../helpers');
+    var shapeReflections;
+    var shiftFirstArgumentToThis = function (func) {
+        return function () {
+            var args = [this];
+            args.push.apply(args, arguments);
+            return func.apply(null, args);
+        };
+    };
+    var getKeyValueSymbol = canSymbol.for('can.getKeyValue');
+    var shiftedGetKeyValue = shiftFirstArgumentToThis(getSetReflections.getKeyValue);
+    var setKeyValueSymbol = canSymbol.for('can.setKeyValue');
+    var shiftedSetKeyValue = shiftFirstArgumentToThis(getSetReflections.setKeyValue);
+    var sizeSymbol = canSymbol.for('can.size');
+    var serializeMap = null;
+    var hasUpdateSymbol = helpers.makeGetFirstSymbolValue([
+        'can.updateDeep',
+        'can.assignDeep',
+        'can.setKeyValue'
+    ]);
+    var shouldUpdateOrAssign = function (obj) {
+        return typeReflections.isPlainObject(obj) || Array.isArray(obj) || !!hasUpdateSymbol(obj);
+    };
+    function isSerializable(obj) {
+        if (typeReflections.isPrimitive(obj)) {
+            return true;
+        }
+        if (hasUpdateSymbol(obj)) {
+            return false;
+        }
+        return typeReflections.isBuiltIn(obj) && !typeReflections.isPlainObject(obj);
+    }
+    var Object_Keys;
+    try {
+        Object.keys(1);
+        Object_Keys = Object.keys;
+    } catch (e) {
+        Object_Keys = function (obj) {
+            if (typeReflections.isPrimitive(obj)) {
+                return [];
+            } else {
+                return Object.keys(obj);
+            }
+        };
+    }
+    function makeSerializer(methodName, symbolsToCheck) {
+        return function serializer(value, MapType) {
+            if (isSerializable(value)) {
+                return value;
+            }
+            var firstSerialize;
+            if (MapType && !serializeMap) {
+                serializeMap = {
+                    unwrap: new MapType(),
+                    serialize: new MapType()
+                };
+                firstSerialize = true;
+            }
+            var serialized;
+            if (typeReflections.isValueLike(value)) {
+                serialized = this[methodName](getSetReflections.getValue(value));
+            } else {
+                var isListLike = typeReflections.isIteratorLike(value) || typeReflections.isMoreListLikeThanMapLike(value);
+                serialized = isListLike ? [] : {};
+                if (serializeMap) {
+                    if (serializeMap[methodName].has(value)) {
+                        return serializeMap[methodName].get(value);
+                    } else {
+                        serializeMap[methodName].set(value, serialized);
+                    }
+                }
+                for (var i = 0, len = symbolsToCheck.length; i < len; i++) {
+                    var serializer = value[symbolsToCheck[i]];
+                    if (serializer) {
+                        var result = serializer.call(value, serialized);
+                        if (firstSerialize) {
+                            serializeMap = null;
+                        }
+                        return result;
+                    }
+                }
+                if (typeof obj === 'function') {
+                    if (serializeMap) {
+                        serializeMap[methodName].set(value, value);
+                    }
+                    serialized = value;
+                } else if (isListLike) {
+                    this.eachIndex(value, function (childValue, index) {
+                        serialized[index] = this[methodName](childValue);
+                    }, this);
+                } else {
+                    this.eachKey(value, function (childValue, prop) {
+                        serialized[prop] = this[methodName](childValue);
+                    }, this);
+                }
+            }
+            if (firstSerialize) {
+                serializeMap = null;
+            }
+            return serialized;
+        };
+    }
+    var makeMap;
+    if (typeof Map !== 'undefined') {
+        makeMap = function (keys) {
+            var map = new Map();
+            shapeReflections.eachIndex(keys, function (key) {
+                map.set(key, true);
+            });
+            return map;
+        };
+    } else {
+        makeMap = function (keys) {
+            var map = {};
+            keys.forEach(function (key) {
+                map[key] = true;
+            });
+            return {
+                get: function (key) {
+                    return map[key];
+                },
+                set: function (key, value) {
+                    map[key] = value;
+                },
+                keys: function () {
+                    return keys;
+                }
+            };
+        };
+    }
+    var fastHasOwnKey = function (obj) {
+        var hasOwnKey = obj[canSymbol.for('can.hasOwnKey')];
+        if (hasOwnKey) {
+            return hasOwnKey.bind(obj);
+        } else {
+            var map = makeMap(shapeReflections.getOwnEnumerableKeys(obj));
+            return function (key) {
+                return map.get(key);
+            };
+        }
+    };
+    function addPatch(patches, patch) {
+        var lastPatch = patches[patches.length - 1];
+        if (lastPatch) {
+            if (lastPatch.deleteCount === lastPatch.insert.length && patch.index - lastPatch.index === lastPatch.deleteCount) {
+                lastPatch.insert.push.apply(lastPatch.insert, patch.insert);
+                lastPatch.deleteCount += patch.deleteCount;
+                return;
+            }
+        }
+        patches.push(patch);
+    }
+    function updateDeepList(target, source, isAssign) {
+        var sourceArray = this.toArray(source);
+        var patches = [], lastIndex = -1;
+        this.eachIndex(target, function (curVal, index) {
+            lastIndex = index;
+            if (index >= sourceArray.length) {
+                if (!isAssign) {
+                    addPatch(patches, {
+                        index: index,
+                        deleteCount: sourceArray.length - index + 1,
+                        insert: []
+                    });
+                }
+                return false;
+            }
+            var newVal = sourceArray[index];
+            if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) {
+                addPatch(patches, {
+                    index: index,
+                    deleteCount: 1,
+                    insert: [newVal]
+                });
+            } else {
+                this.updateDeep(curVal, newVal);
+            }
+        }, this);
+        if (sourceArray.length > lastIndex) {
+            addPatch(patches, {
+                index: lastIndex + 1,
+                deleteCount: 0,
+                insert: sourceArray.slice(lastIndex + 1)
+            });
+        }
+        for (var i = 0, patchLen = patches.length; i < patchLen; i++) {
+            var patch = patches[i];
+            getSetReflections.splice(target, patch.index, patch.deleteCount, patch.insert);
+        }
+        return target;
+    }
+    shapeReflections = {
+        each: function (obj, callback, context) {
+            if (typeReflections.isIteratorLike(obj) || typeReflections.isMoreListLikeThanMapLike(obj)) {
+                return this.eachIndex(obj, callback, context);
+            } else {
+                return this.eachKey(obj, callback, context);
+            }
+        },
+        eachIndex: function (list, callback, context) {
+            if (Array.isArray(list)) {
+                return this.eachListLike(list, callback, context);
+            } else {
+                var iter, iterator = list[canSymbol.iterator];
+                if (typeReflections.isIteratorLike(list)) {
+                    iter = list;
+                } else if (iterator) {
+                    iter = iterator.call(list);
+                }
+                if (iter) {
+                    var res, index = 0;
+                    while (!(res = iter.next()).done) {
+                        if (callback.call(context || list, res.value, index++, list) === false) {
+                            break;
+                        }
+                    }
+                } else {
+                    this.eachListLike(list, callback, context);
+                }
+            }
+            return list;
+        },
+        eachListLike: function (list, callback, context) {
+            var index = -1;
+            var length = list.length;
+            if (length === undefined) {
+                var size = list[sizeSymbol];
+                if (size) {
+                    length = size.call(list);
+                } else {
+                    throw new Error('can-reflect: unable to iterate.');
+                }
+            }
+            while (++index < length) {
+                var item = list[index];
+                if (callback.call(context || item, item, index, list) === false) {
+                    break;
+                }
+            }
+            return list;
+        },
+        toArray: function (obj) {
+            var arr = [];
+            this.each(obj, function (value) {
+                arr.push(value);
+            });
+            return arr;
+        },
+        eachKey: function (obj, callback, context) {
+            if (obj) {
+                var enumerableKeys = this.getOwnEnumerableKeys(obj);
+                var getKeyValue = obj[getKeyValueSymbol] || shiftedGetKeyValue;
+                return this.eachIndex(enumerableKeys, function (key) {
+                    var value = getKeyValue.call(obj, key);
+                    return callback.call(context || obj, value, key, obj);
+                });
+            }
+            return obj;
+        },
+        'hasOwnKey': function (obj, key) {
+            var hasOwnKey = obj[canSymbol.for('can.hasOwnKey')];
+            if (hasOwnKey) {
+                return hasOwnKey.call(obj, key);
+            }
+            var getOwnKeys = obj[canSymbol.for('can.getOwnKeys')];
+            if (getOwnKeys) {
+                var found = false;
+                this.eachIndex(getOwnKeys.call(obj), function (objKey) {
+                    if (objKey === key) {
+                        found = true;
+                        return false;
+                    }
+                });
+                return found;
+            }
+            return obj.hasOwnProperty(key);
+        },
+        getOwnEnumerableKeys: function (obj) {
+            var getOwnEnumerableKeys = obj[canSymbol.for('can.getOwnEnumerableKeys')];
+            if (getOwnEnumerableKeys) {
+                return getOwnEnumerableKeys.call(obj);
+            }
+            if (obj[canSymbol.for('can.getOwnKeys')] && obj[canSymbol.for('can.getOwnKeyDescriptor')]) {
+                var keys = [];
+                this.eachIndex(this.getOwnKeys(obj), function (key) {
+                    var descriptor = this.getOwnKeyDescriptor(obj, key);
+                    if (descriptor.enumerable) {
+                        keys.push(key);
+                    }
+                }, this);
+                return keys;
+            } else {
+                return Object_Keys(obj);
+            }
+        },
+        getOwnKeys: function (obj) {
+            var getOwnKeys = obj[canSymbol.for('can.getOwnKeys')];
+            if (getOwnKeys) {
+                return getOwnKeys.call(obj);
+            } else {
+                return Object.getOwnPropertyNames(obj);
+            }
+        },
+        getOwnKeyDescriptor: function (obj, key) {
+            var getOwnKeyDescriptor = obj[canSymbol.for('can.getOwnKeyDescriptor')];
+            if (getOwnKeyDescriptor) {
+                return getOwnKeyDescriptor.call(obj, key);
+            } else {
+                return Object.getOwnPropertyDescriptor(obj, key);
+            }
+        },
+        unwrap: makeSerializer('unwrap', [canSymbol.for('can.unwrap')]),
+        serialize: makeSerializer('serialize', [
+            canSymbol.for('can.serialize'),
+            canSymbol.for('can.unwrap')
+        ]),
+        assignMap: function (target, source) {
+            var hasOwnKey = fastHasOwnKey(target);
+            var getKeyValue = target[getKeyValueSymbol] || shiftedGetKeyValue;
+            var setKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue;
+            this.eachKey(source, function (value, key) {
+                if (!hasOwnKey(key) || getKeyValue.call(target, key) !== value) {
+                    setKeyValue.call(target, key, value);
+                }
+            });
+            return target;
+        },
+        assignList: function (target, source) {
+            var inserting = this.toArray(source);
+            getSetReflections.splice(target, 0, inserting, inserting);
+            return target;
+        },
+        assign: function (target, source) {
+            if (typeReflections.isIteratorLike(source) || typeReflections.isMoreListLikeThanMapLike(source)) {
+                this.assignList(target, source);
+            } else {
+                this.assignMap(target, source);
+            }
+            return target;
+        },
+        assignDeepMap: function (target, source) {
+            var hasOwnKey = fastHasOwnKey(target);
+            var getKeyValue = target[getKeyValueSymbol] || shiftedGetKeyValue;
+            var setKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue;
+            this.eachKey(source, function (newVal, key) {
+                if (!hasOwnKey(key)) {
+                    getSetReflections.setKeyValue(target, key, newVal);
+                } else {
+                    var curVal = getKeyValue.call(target, key);
+                    if (newVal === curVal) {
+                    } else if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) {
+                        setKeyValue.call(target, key, newVal);
+                    } else {
+                        this.assignDeep(curVal, newVal);
+                    }
+                }
+            }, this);
+            return target;
+        },
+        assignDeepList: function (target, source) {
+            return updateDeepList.call(this, target, source, true);
+        },
+        assignDeep: function (target, source) {
+            var assignDeep = target[canSymbol.for('can.assignDeep')];
+            if (assignDeep) {
+                assignDeep.call(target, source);
+            } else if (typeReflections.isMoreListLikeThanMapLike(source)) {
+                this.assignDeepList(target, source);
+            } else {
+                this.assignDeepMap(target, source);
+            }
+            return target;
+        },
+        updateMap: function (target, source) {
+            var sourceKeyMap = makeMap(this.getOwnEnumerableKeys(source));
+            var sourceGetKeyValue = source[getKeyValueSymbol] || shiftedGetKeyValue;
+            var targetSetKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue;
+            this.eachKey(target, function (curVal, key) {
+                if (!sourceKeyMap.get(key)) {
+                    getSetReflections.deleteKeyValue(target, key);
+                    return;
+                }
+                sourceKeyMap.set(key, false);
+                var newVal = sourceGetKeyValue.call(source, key);
+                if (newVal !== curVal) {
+                    targetSetKeyValue.call(target, key, newVal);
+                }
+            }, this);
+            this.eachIndex(sourceKeyMap.keys(), function (key) {
+                if (sourceKeyMap.get(key)) {
+                    targetSetKeyValue.call(target, key, sourceGetKeyValue.call(source, key));
+                }
+            });
+            return target;
+        },
+        updateList: function (target, source) {
+            var inserting = this.toArray(source);
+            getSetReflections.splice(target, 0, target, inserting);
+            return target;
+        },
+        update: function (target, source) {
+            if (typeReflections.isIteratorLike(source) || typeReflections.isMoreListLikeThanMapLike(source)) {
+                this.updateList(target, source);
+            } else {
+                this.updateMap(target, source);
+            }
+            return target;
+        },
+        updateDeepMap: function (target, source) {
+            var sourceKeyMap = makeMap(this.getOwnEnumerableKeys(source));
+            var sourceGetKeyValue = source[getKeyValueSymbol] || shiftedGetKeyValue;
+            var targetSetKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue;
+            this.eachKey(target, function (curVal, key) {
+                if (!sourceKeyMap.get(key)) {
+                    getSetReflections.deleteKeyValue(target, key);
+                    return;
+                }
+                sourceKeyMap.set(key, false);
+                var newVal = sourceGetKeyValue.call(source, key);
+                if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) {
+                    targetSetKeyValue.call(target, key, newVal);
+                } else {
+                    this.updateDeep(curVal, newVal);
+                }
+            }, this);
+            this.eachIndex(sourceKeyMap.keys(), function (key) {
+                if (sourceKeyMap.get(key)) {
+                    targetSetKeyValue.call(target, key, sourceGetKeyValue.call(source, key));
+                }
+            });
+            return target;
+        },
+        updateDeepList: function (target, source) {
+            return updateDeepList.call(this, target, source);
+        },
+        updateDeep: function (target, source) {
+            var updateDeep = target[canSymbol.for('can.updateDeep')];
+            if (updateDeep) {
+                updateDeep.call(target, source);
+            } else if (typeReflections.isMoreListLikeThanMapLike(source)) {
+                this.updateDeepList(target, source);
+            } else {
+                this.updateDeepMap(target, source);
+            }
+            return target;
+        },
+        'in': function () {
+        },
+        getAllEnumerableKeys: function () {
+        },
+        getAllKeys: function () {
+        },
+        assignSymbols: function (target, source) {
+            this.eachKey(source, function (value, key) {
+                var symbol = typeReflections.isSymbolLike(canSymbol[key]) ? canSymbol[key] : canSymbol.for(key);
+                getSetReflections.setKeyValue(target, symbol, value);
+            });
+            return target;
+        },
+        isSerializable: isSerializable,
+        size: function (obj) {
+            var size = obj[sizeSymbol];
+            var count = 0;
+            if (size) {
+                return size.call(obj);
+            } else if (helpers.hasLength(obj)) {
+                return obj.length;
+            } else if (typeReflections.isListLike(obj)) {
+                this.each(obj, function () {
+                    count++;
+                });
+                return count;
+            } else if (obj) {
+                for (var prop in obj) {
+                    if (obj.hasOwnProperty(prop)) {
+                        count++;
+                    }
+                }
+                return count;
+            } else {
+                return undefined;
+            }
+        },
+        defineInstanceKey: function (cls, key, properties) {
+            var defineInstanceKey = cls[canSymbol.for('can.defineInstanceKey')];
+            if (defineInstanceKey) {
+                return defineInstanceKey.call(cls, key, properties);
+            }
+            var proto = cls.prototype;
+            defineInstanceKey = proto[canSymbol.for('can.defineInstanceKey')];
+            if (defineInstanceKey) {
+                defineInstanceKey.call(proto, key, properties);
+            } else {
+                Object.defineProperty(proto, key, shapeReflections.assign({
+                    configurable: true,
+                    enumerable: !typeReflections.isSymbolLike(key),
+                    writable: true
+                }, properties));
+            }
+        }
+    };
+    shapeReflections.keys = shapeReflections.getOwnEnumerableKeys;
+    module.exports = shapeReflections;
+});
\ No newline at end of file
diff --git a/dist/amd/reflections/type/type.js b/dist/amd/reflections/type/type.js
new file mode 100644
index 0000000..f0f569f
--- /dev/null
+++ b/dist/amd/reflections/type/type.js
@@ -0,0 +1,200 @@
+/*can-reflect@1.7.3#reflections/type/type*/
+define([
+    'require',
+    'exports',
+    'module',
+    'can-symbol',
+    '../helpers'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    var helpers = require('../helpers');
+    var plainFunctionPrototypePropertyNames = Object.getOwnPropertyNames(function () {
+    }.prototype);
+    var plainFunctionPrototypeProto = Object.getPrototypeOf(function () {
+    }.prototype);
+    function isConstructorLike(func) {
+        var value = func[canSymbol.for('can.new')];
+        if (value !== undefined) {
+            return value;
+        }
+        if (typeof func !== 'function') {
+            return false;
+        }
+        var prototype = func.prototype;
+        if (!prototype) {
+            return false;
+        }
+        if (plainFunctionPrototypeProto !== Object.getPrototypeOf(prototype)) {
+            return true;
+        }
+        var propertyNames = Object.getOwnPropertyNames(prototype);
+        if (propertyNames.length === plainFunctionPrototypePropertyNames.length) {
+            for (var i = 0, len = propertyNames.length; i < len; i++) {
+                if (propertyNames[i] !== plainFunctionPrototypePropertyNames[i]) {
+                    return true;
+                }
+            }
+            return false;
+        } else {
+            return true;
+        }
+    }
+    var getNewOrApply = helpers.makeGetFirstSymbolValue([
+        'can.new',
+        'can.apply'
+    ]);
+    function isFunctionLike(obj) {
+        var result, symbolValue = obj[canSymbol.for('can.isFunctionLike')];
+        if (symbolValue !== undefined) {
+            return symbolValue;
+        }
+        result = getNewOrApply(obj);
+        if (result !== undefined) {
+            return !!result;
+        }
+        return typeof obj === 'function';
+    }
+    function isPrimitive(obj) {
+        var type = typeof obj;
+        if (obj == null || type !== 'function' && type !== 'object') {
+            return true;
+        } else {
+            return false;
+        }
+    }
+    function isBuiltIn(obj) {
+        if (isPrimitive(obj) || Array.isArray(obj) || isPlainObject(obj) || Object.prototype.toString.call(obj) !== '[object Object]' && Object.prototype.toString.call(obj).indexOf('[object ') !== -1) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+    function isValueLike(obj) {
+        var symbolValue;
+        if (isPrimitive(obj)) {
+            return true;
+        }
+        symbolValue = obj[canSymbol.for('can.isValueLike')];
+        if (typeof symbolValue !== 'undefined') {
+            return symbolValue;
+        }
+        var value = obj[canSymbol.for('can.getValue')];
+        if (value !== undefined) {
+            return !!value;
+        }
+    }
+    function isMapLike(obj) {
+        if (isPrimitive(obj)) {
+            return false;
+        }
+        var isMapLike = obj[canSymbol.for('can.isMapLike')];
+        if (typeof isMapLike !== 'undefined') {
+            return !!isMapLike;
+        }
+        var value = obj[canSymbol.for('can.getKeyValue')];
+        if (value !== undefined) {
+            return !!value;
+        }
+        return true;
+    }
+    var getObservableLikeSymbol = helpers.makeGetFirstSymbolValue([
+        'can.onValue',
+        'can.onKeyValue',
+        'can.onKeys',
+        'can.onKeysAdded'
+    ]);
+    function isObservableLike(obj) {
+        if (isPrimitive(obj)) {
+            return false;
+        }
+        var result = getObservableLikeSymbol(obj);
+        if (result !== undefined) {
+            return !!result;
+        }
+        return false;
+    }
+    function isListLike(list) {
+        var symbolValue, type = typeof list;
+        if (type === 'string') {
+            return true;
+        }
+        if (isPrimitive(list)) {
+            return false;
+        }
+        symbolValue = list[canSymbol.for('can.isListLike')];
+        if (typeof symbolValue !== 'undefined') {
+            return symbolValue;
+        }
+        var value = list[canSymbol.iterator];
+        if (value !== undefined) {
+            return !!value;
+        }
+        if (Array.isArray(list)) {
+            return true;
+        }
+        return helpers.hasLength(list);
+    }
+    var supportsSymbols = typeof Symbol !== 'undefined' && typeof Symbol.for === 'function';
+    var isSymbolLike;
+    if (supportsSymbols) {
+        isSymbolLike = function (symbol) {
+            return typeof symbol === 'symbol';
+        };
+    } else {
+        var symbolStart = '@@symbol';
+        isSymbolLike = function (symbol) {
+            if (typeof symbol === 'object' && !Array.isArray(symbol)) {
+                return symbol.toString().substr(0, symbolStart.length) === symbolStart;
+            } else {
+                return false;
+            }
+        };
+    }
+    var coreHasOwn = Object.prototype.hasOwnProperty;
+    var funcToString = Function.prototype.toString;
+    var objectCtorString = funcToString.call(Object);
+    function isPlainObject(obj) {
+        if (!obj || typeof obj !== 'object') {
+            return false;
+        }
+        var proto = Object.getPrototypeOf(obj);
+        if (proto === Object.prototype || proto === null) {
+            return true;
+        }
+        var Constructor = coreHasOwn.call(proto, 'constructor') && proto.constructor;
+        return typeof Constructor === 'function' && Constructor instanceof Constructor && funcToString.call(Constructor) === objectCtorString;
+    }
+    module.exports = {
+        isConstructorLike: isConstructorLike,
+        isFunctionLike: isFunctionLike,
+        isListLike: isListLike,
+        isMapLike: isMapLike,
+        isObservableLike: isObservableLike,
+        isPrimitive: isPrimitive,
+        isBuiltIn: isBuiltIn,
+        isValueLike: isValueLike,
+        isSymbolLike: isSymbolLike,
+        isMoreListLikeThanMapLike: function (obj) {
+            if (Array.isArray(obj)) {
+                return true;
+            }
+            var value = obj[canSymbol.for('can.isMoreListLikeThanMapLike')];
+            if (value !== undefined) {
+                return value;
+            }
+            var isListLike = this.isListLike(obj), isMapLike = this.isMapLike(obj);
+            if (isListLike && !isMapLike) {
+                return true;
+            } else if (!isListLike && isMapLike) {
+                return false;
+            }
+        },
+        isIteratorLike: function (obj) {
+            return obj && typeof obj === 'object' && typeof obj.next === 'function' && obj.next.length === 0;
+        },
+        isPromise: function (obj) {
+            return obj instanceof Promise || Object.prototype.toString.call(obj) === '[object Promise]';
+        },
+        isPlainObject: isPlainObject
+    };
+});
\ No newline at end of file
diff --git a/dist/amd/types/map.js b/dist/amd/types/map.js
new file mode 100644
index 0000000..1f03e45
--- /dev/null
+++ b/dist/amd/types/map.js
@@ -0,0 +1,49 @@
+/*can-reflect@1.7.3#types/map*/
+define([
+    'require',
+    'exports',
+    'module',
+    '../reflections/shape/shape',
+    'can-symbol'
+], function (require, exports, module) {
+    var shape = require('../reflections/shape/shape');
+    var CanSymbol = require('can-symbol');
+    function keysPolyfill() {
+        var keys = [];
+        var currentIndex = 0;
+        this.forEach(function (val, key) {
+            keys.push(key);
+        });
+        return {
+            next: function () {
+                return {
+                    value: keys[currentIndex],
+                    done: currentIndex++ === keys.length
+                };
+            }
+        };
+    }
+    if (typeof Map !== 'undefined') {
+        shape.assignSymbols(Map.prototype, {
+            'can.getOwnEnumerableKeys': Map.prototype.keys,
+            'can.setKeyValue': Map.prototype.set,
+            'can.getKeyValue': Map.prototype.get,
+            'can.deleteKeyValue': Map.prototype['delete'],
+            'can.hasOwnKey': Map.prototype.has
+        });
+        if (typeof Map.prototype.keys !== 'function') {
+            Map.prototype.keys = Map.prototype[CanSymbol.for('can.getOwnEnumerableKeys')] = keysPolyfill;
+        }
+    }
+    if (typeof WeakMap !== 'undefined') {
+        shape.assignSymbols(WeakMap.prototype, {
+            'can.getOwnEnumerableKeys': function () {
+                throw new Error('can-reflect: WeakMaps do not have enumerable keys.');
+            },
+            'can.setKeyValue': WeakMap.prototype.set,
+            'can.getKeyValue': WeakMap.prototype.get,
+            'can.deleteKeyValue': WeakMap.prototype['delete'],
+            'can.hasOwnKey': WeakMap.prototype.has
+        });
+    }
+});
\ No newline at end of file
diff --git a/dist/amd/types/set.js b/dist/amd/types/set.js
new file mode 100644
index 0000000..dc75cff
--- /dev/null
+++ b/dist/amd/types/set.js
@@ -0,0 +1,65 @@
+/*can-reflect@1.7.3#types/set*/
+define([
+    'require',
+    'exports',
+    'module',
+    '../reflections/shape/shape',
+    'can-symbol'
+], function (require, exports, module) {
+    var shape = require('../reflections/shape/shape');
+    var CanSymbol = require('can-symbol');
+    if (typeof Set !== 'undefined') {
+        shape.assignSymbols(Set.prototype, {
+            'can.isMoreListLikeThanMapLike': true,
+            'can.updateValues': function (index, removing, adding) {
+                if (removing !== adding) {
+                    shape.each(removing, function (value) {
+                        this.delete(value);
+                    }, this);
+                }
+                shape.each(adding, function (value) {
+                    this.add(value);
+                }, this);
+            },
+            'can.size': function () {
+                return this.size;
+            }
+        });
+        if (typeof Set.prototype[CanSymbol.iterator] !== 'function') {
+            Set.prototype[CanSymbol.iterator] = function () {
+                var arr = [];
+                var currentIndex = 0;
+                this.forEach(function (val) {
+                    arr.push(val);
+                });
+                return {
+                    next: function () {
+                        return {
+                            value: arr[currentIndex],
+                            done: currentIndex++ === arr.length
+                        };
+                    }
+                };
+            };
+        }
+    }
+    if (typeof WeakSet !== 'undefined') {
+        shape.assignSymbols(WeakSet.prototype, {
+            'can.isListLike': true,
+            'can.isMoreListLikeThanMapLike': true,
+            'can.updateValues': function (index, removing, adding) {
+                if (removing !== adding) {
+                    shape.each(removing, function (value) {
+                        this.delete(value);
+                    }, this);
+                }
+                shape.each(adding, function (value) {
+                    this.add(value);
+                }, this);
+            },
+            'can.size': function () {
+                throw new Error('can-reflect: WeakSets do not have enumerable keys.');
+            }
+        });
+    }
+});
\ No newline at end of file
diff --git a/dist/cjs/can-reflect.js b/dist/cjs/can-reflect.js
new file mode 100644
index 0000000..a83cc39
--- /dev/null
+++ b/dist/cjs/can-reflect.js
@@ -0,0 +1,24 @@
+/*can-reflect@1.7.3#can-reflect*/
+var functionReflections = require('./reflections/call/call.js');
+var getSet = require('./reflections/get-set/get-set.js');
+var observe = require('./reflections/observe/observe.js');
+var shape = require('./reflections/shape/shape.js');
+var type = require('./reflections/type/type.js');
+var getName = require('./reflections/get-name/get-name.js');
+var namespace = require('can-namespace');
+var reflect = {};
+[
+    functionReflections,
+    getSet,
+    observe,
+    shape,
+    type,
+    getName
+].forEach(function (reflections) {
+    for (var prop in reflections) {
+        reflect[prop] = reflections[prop];
+    }
+});
+require('./types/map.js');
+require('./types/set.js');
+module.exports = namespace.Reflect = reflect;
\ No newline at end of file
diff --git a/dist/cjs/reflections/call/call.js b/dist/cjs/reflections/call/call.js
new file mode 100644
index 0000000..4d537ff
--- /dev/null
+++ b/dist/cjs/reflections/call/call.js
@@ -0,0 +1,37 @@
+/*can-reflect@1.7.3#reflections/call/call*/
+var canSymbol = require('can-symbol');
+var typeReflections = require('../type/type.js');
+module.exports = {
+    call: function (func, context) {
+        var args = [].slice.call(arguments, 2);
+        var apply = func[canSymbol.for('can.apply')];
+        if (apply) {
+            return apply.call(func, context, args);
+        } else {
+            return func.apply(context, args);
+        }
+    },
+    apply: function (func, context, args) {
+        var apply = func[canSymbol.for('can.apply')];
+        if (apply) {
+            return apply.call(func, context, args);
+        } else {
+            return func.apply(context, args);
+        }
+    },
+    'new': function (func) {
+        var args = [].slice.call(arguments, 1);
+        var makeNew = func[canSymbol.for('can.new')];
+        if (makeNew) {
+            return makeNew.apply(func, args);
+        } else {
+            var context = Object.create(func.prototype);
+            var ret = func.apply(context, args);
+            if (typeReflections.isPrimitive(ret)) {
+                return context;
+            } else {
+                return ret;
+            }
+        }
+    }
+};
\ No newline at end of file
diff --git a/dist/cjs/reflections/get-name/get-name.js b/dist/cjs/reflections/get-name/get-name.js
new file mode 100644
index 0000000..d3ffdb3
--- /dev/null
+++ b/dist/cjs/reflections/get-name/get-name.js
@@ -0,0 +1,41 @@
+/*can-reflect@1.7.3#reflections/get-name/get-name*/
+var canSymbol = require('can-symbol');
+var typeReflections = require('../type/type.js');
+var getNameSymbol = canSymbol.for('can.getName');
+function setName(obj, nameGetter) {
+    if (typeof nameGetter !== 'function') {
+        var value = nameGetter;
+        nameGetter = function () {
+            return value;
+        };
+    }
+    Object.defineProperty(obj, getNameSymbol, { value: nameGetter });
+}
+function getName(obj) {
+    var nameGetter = obj[getNameSymbol];
+    if (nameGetter) {
+        return nameGetter.call(obj);
+    }
+    if (typeof obj === 'function') {
+        return obj.name;
+    }
+    if (obj.constructor && obj !== obj.constructor) {
+        var parent = getName(obj.constructor);
+        if (parent) {
+            if (typeReflections.isValueLike(obj)) {
+                return parent + '<>';
+            }
+            if (typeReflections.isMoreListLikeThanMapLike(obj)) {
+                return parent + '[]';
+            }
+            if (typeReflections.isMapLike(obj)) {
+                return parent + '{}';
+            }
+        }
+    }
+    return undefined;
+}
+module.exports = {
+    setName: setName,
+    getName: getName
+};
\ No newline at end of file
diff --git a/dist/cjs/reflections/get-set/get-set.js b/dist/cjs/reflections/get-set/get-set.js
new file mode 100644
index 0000000..7d188e8
--- /dev/null
+++ b/dist/cjs/reflections/get-set/get-set.js
@@ -0,0 +1,109 @@
+/*can-reflect@1.7.3#reflections/get-set/get-set*/
+var canSymbol = require('can-symbol');
+var typeReflections = require('../type/type.js');
+var setKeyValueSymbol = canSymbol.for('can.setKeyValue'), getKeyValueSymbol = canSymbol.for('can.getKeyValue'), getValueSymbol = canSymbol.for('can.getValue'), setValueSymbol = canSymbol.for('can.setValue');
+var reflections = {
+    setKeyValue: function (obj, key, value) {
+        if (typeReflections.isSymbolLike(key)) {
+            if (typeof key === 'symbol') {
+                obj[key] = value;
+            } else {
+                Object.defineProperty(obj, key, {
+                    enumerable: false,
+                    configurable: true,
+                    value: value,
+                    writable: true
+                });
+            }
+            return;
+        }
+        var setKeyValue = obj[setKeyValueSymbol];
+        if (setKeyValue !== undefined) {
+            return setKeyValue.call(obj, key, value);
+        } else {
+            obj[key] = value;
+        }
+    },
+    getKeyValue: function (obj, key) {
+        var getKeyValue = obj[getKeyValueSymbol];
+        if (getKeyValue) {
+            return getKeyValue.call(obj, key);
+        }
+        return obj[key];
+    },
+    deleteKeyValue: function (obj, key) {
+        var deleteKeyValue = obj[canSymbol.for('can.deleteKeyValue')];
+        if (deleteKeyValue) {
+            return deleteKeyValue.call(obj, key);
+        }
+        delete obj[key];
+    },
+    getValue: function (value) {
+        if (typeReflections.isPrimitive(value)) {
+            return value;
+        }
+        var getValue = value[getValueSymbol];
+        if (getValue) {
+            return getValue.call(value);
+        }
+        return value;
+    },
+    setValue: function (item, value) {
+        var setValue = item && item[setValueSymbol];
+        if (setValue) {
+            return setValue.call(item, value);
+        } else {
+            throw new Error('can-reflect.setValue - Can not set value.');
+        }
+    },
+    splice: function (obj, index, removing, adding) {
+        var howMany;
+        if (typeof removing !== 'number') {
+            var updateValues = obj[canSymbol.for('can.updateValues')];
+            if (updateValues) {
+                return updateValues.call(obj, index, removing, adding);
+            }
+            howMany = removing.length;
+        } else {
+            howMany = removing;
+        }
+        var splice = obj[canSymbol.for('can.splice')];
+        if (splice) {
+            return splice.call(obj, index, howMany, adding);
+        }
+        return [].splice.apply(obj, [
+            index,
+            howMany
+        ].concat(adding));
+    },
+    addValues: function (obj, adding, index) {
+        var add = obj[canSymbol.for('can.addValues')];
+        if (add) {
+            return add.call(obj, adding, index);
+        }
+        if (Array.isArray(obj) && index === undefined) {
+            return obj.push.apply(obj, adding);
+        }
+        return reflections.splice(obj, index, [], adding);
+    },
+    removeValues: function (obj, removing, index) {
+        var removeValues = obj[canSymbol.for('can.removeValues')];
+        if (removeValues) {
+            return removeValues.call(obj, removing, index);
+        }
+        if (Array.isArray(obj) && index === undefined) {
+            removing.forEach(function (item) {
+                var index = obj.indexOf(item);
+                if (index >= 0) {
+                    obj.splice(index, 1);
+                }
+            });
+            return;
+        }
+        return reflections.splice(obj, index, removing, []);
+    }
+};
+reflections.get = reflections.getKeyValue;
+reflections.set = reflections.setKeyValue;
+reflections['delete'] = reflections.deleteKeyValue;
+module.exports = reflections;
\ No newline at end of file
diff --git a/dist/cjs/reflections/helpers.js b/dist/cjs/reflections/helpers.js
new file mode 100644
index 0000000..46fbb92
--- /dev/null
+++ b/dist/cjs/reflections/helpers.js
@@ -0,0 +1,23 @@
+/*can-reflect@1.7.3#reflections/helpers*/
+var canSymbol = require('can-symbol');
+module.exports = {
+    makeGetFirstSymbolValue: function (symbolNames) {
+        var symbols = symbolNames.map(function (name) {
+            return canSymbol.for(name);
+        });
+        var length = symbols.length;
+        return function getFirstSymbol(obj) {
+            var index = -1;
+            while (++index < length) {
+                if (obj[symbols[index]] !== undefined) {
+                    return obj[symbols[index]];
+                }
+            }
+        };
+    },
+    hasLength: function (list) {
+        var type = typeof list;
+        var length = list && type !== 'boolean' && typeof list !== 'number' && 'length' in list && list.length;
+        return typeof list !== 'function' && (length === 0 || typeof length === 'number' && length > 0 && length - 1 in list);
+    }
+};
\ No newline at end of file
diff --git a/dist/cjs/reflections/observe/observe.js b/dist/cjs/reflections/observe/observe.js
new file mode 100644
index 0000000..e587cec
--- /dev/null
+++ b/dist/cjs/reflections/observe/observe.js
@@ -0,0 +1,79 @@
+/*can-reflect@1.7.3#reflections/observe/observe*/
+var canSymbol = require('can-symbol');
+var slice = [].slice;
+function makeFallback(symbolName, fallbackName) {
+    return function (obj, event, handler, queueName) {
+        var method = obj[canSymbol.for(symbolName)];
+        if (method !== undefined) {
+            return method.call(obj, event, handler, queueName);
+        }
+        return this[fallbackName].apply(this, arguments);
+    };
+}
+function makeErrorIfMissing(symbolName, errorMessage) {
+    return function (obj) {
+        var method = obj[canSymbol.for(symbolName)];
+        if (method !== undefined) {
+            var args = slice.call(arguments, 1);
+            return method.apply(obj, args);
+        }
+        throw new Error(errorMessage);
+    };
+}
+module.exports = {
+    onKeyValue: makeFallback('can.onKeyValue', 'onEvent'),
+    offKeyValue: makeFallback('can.offKeyValue', 'offEvent'),
+    onKeys: makeErrorIfMissing('can.onKeys', 'can-reflect: can not observe an onKeys event'),
+    onKeysAdded: makeErrorIfMissing('can.onKeysAdded', 'can-reflect: can not observe an onKeysAdded event'),
+    onKeysRemoved: makeErrorIfMissing('can.onKeysRemoved', 'can-reflect: can not unobserve an onKeysRemoved event'),
+    getKeyDependencies: makeErrorIfMissing('can.getKeyDependencies', 'can-reflect: can not determine dependencies'),
+    keyHasDependencies: makeErrorIfMissing('can.keyHasDependencies', 'can-reflect: can not determine if this has key dependencies'),
+    onValue: makeErrorIfMissing('can.onValue', 'can-reflect: can not observe value change'),
+    offValue: makeErrorIfMissing('can.offValue', 'can-reflect: can not unobserve value change'),
+    getValueDependencies: makeErrorIfMissing('can.getValueDependencies', 'can-reflect: can not determine dependencies'),
+    valueHasDependencies: makeErrorIfMissing('can.valueHasDependencies', 'can-reflect: can not determine if value has dependencies'),
+    onPatches: makeErrorIfMissing('can.onPatches', 'can-reflect: can not observe patches on object'),
+    offPatches: makeErrorIfMissing('can.offPatches', 'can-reflect: can not unobserve patches on object'),
+    onInstanceBoundChange: makeErrorIfMissing('can.onInstanceBoundChange', 'can-reflect: can not observe bound state change in instances.'),
+    offInstanceBoundChange: makeErrorIfMissing('can.offInstanceBoundChange', 'can-reflect: can not unobserve bound state change'),
+    isBound: makeErrorIfMissing('can.isBound', 'can-reflect: cannot determine if object is bound'),
+    onEvent: function (obj, eventName, callback, queue) {
+        if (obj) {
+            var onEvent = obj[canSymbol.for('can.onEvent')];
+            if (onEvent !== undefined) {
+                return onEvent.call(obj, eventName, callback, queue);
+            } else if (obj.addEventListener) {
+                obj.addEventListener(eventName, callback, queue);
+            }
+        }
+    },
+    offEvent: function (obj, eventName, callback, queue) {
+        if (obj) {
+            var offEvent = obj[canSymbol.for('can.offEvent')];
+            if (offEvent !== undefined) {
+                return offEvent.call(obj, eventName, callback, queue);
+            } else if (obj.removeEventListener) {
+                obj.removeEventListener(eventName, callback, queue);
+            }
+        }
+    },
+    setPriority: function (obj, priority) {
+        if (obj) {
+            var setPriority = obj[canSymbol.for('can.setPriority')];
+            if (setPriority !== undefined) {
+                setPriority.call(obj, priority);
+                return true;
+            }
+        }
+        return false;
+    },
+    getPriority: function (obj) {
+        if (obj) {
+            var getPriority = obj[canSymbol.for('can.getPriority')];
+            if (getPriority !== undefined) {
+                return getPriority.call(obj);
+            }
+        }
+        return undefined;
+    }
+};
\ No newline at end of file
diff --git a/dist/cjs/reflections/shape/shape.js b/dist/cjs/reflections/shape/shape.js
new file mode 100644
index 0000000..a5b179b
--- /dev/null
+++ b/dist/cjs/reflections/shape/shape.js
@@ -0,0 +1,507 @@
+/*can-reflect@1.7.3#reflections/shape/shape*/
+var canSymbol = require('can-symbol');
+var getSetReflections = require('../get-set/get-set.js');
+var typeReflections = require('../type/type.js');
+var helpers = require('../helpers.js');
+var shapeReflections;
+var shiftFirstArgumentToThis = function (func) {
+    return function () {
+        var args = [this];
+        args.push.apply(args, arguments);
+        return func.apply(null, args);
+    };
+};
+var getKeyValueSymbol = canSymbol.for('can.getKeyValue');
+var shiftedGetKeyValue = shiftFirstArgumentToThis(getSetReflections.getKeyValue);
+var setKeyValueSymbol = canSymbol.for('can.setKeyValue');
+var shiftedSetKeyValue = shiftFirstArgumentToThis(getSetReflections.setKeyValue);
+var sizeSymbol = canSymbol.for('can.size');
+var serializeMap = null;
+var hasUpdateSymbol = helpers.makeGetFirstSymbolValue([
+    'can.updateDeep',
+    'can.assignDeep',
+    'can.setKeyValue'
+]);
+var shouldUpdateOrAssign = function (obj) {
+    return typeReflections.isPlainObject(obj) || Array.isArray(obj) || !!hasUpdateSymbol(obj);
+};
+function isSerializable(obj) {
+    if (typeReflections.isPrimitive(obj)) {
+        return true;
+    }
+    if (hasUpdateSymbol(obj)) {
+        return false;
+    }
+    return typeReflections.isBuiltIn(obj) && !typeReflections.isPlainObject(obj);
+}
+var Object_Keys;
+try {
+    Object.keys(1);
+    Object_Keys = Object.keys;
+} catch (e) {
+    Object_Keys = function (obj) {
+        if (typeReflections.isPrimitive(obj)) {
+            return [];
+        } else {
+            return Object.keys(obj);
+        }
+    };
+}
+function makeSerializer(methodName, symbolsToCheck) {
+    return function serializer(value, MapType) {
+        if (isSerializable(value)) {
+            return value;
+        }
+        var firstSerialize;
+        if (MapType && !serializeMap) {
+            serializeMap = {
+                unwrap: new MapType(),
+                serialize: new MapType()
+            };
+            firstSerialize = true;
+        }
+        var serialized;
+        if (typeReflections.isValueLike(value)) {
+            serialized = this[methodName](getSetReflections.getValue(value));
+        } else {
+            var isListLike = typeReflections.isIteratorLike(value) || typeReflections.isMoreListLikeThanMapLike(value);
+            serialized = isListLike ? [] : {};
+            if (serializeMap) {
+                if (serializeMap[methodName].has(value)) {
+                    return serializeMap[methodName].get(value);
+                } else {
+                    serializeMap[methodName].set(value, serialized);
+                }
+            }
+            for (var i = 0, len = symbolsToCheck.length; i < len; i++) {
+                var serializer = value[symbolsToCheck[i]];
+                if (serializer) {
+                    var result = serializer.call(value, serialized);
+                    if (firstSerialize) {
+                        serializeMap = null;
+                    }
+                    return result;
+                }
+            }
+            if (typeof obj === 'function') {
+                if (serializeMap) {
+                    serializeMap[methodName].set(value, value);
+                }
+                serialized = value;
+            } else if (isListLike) {
+                this.eachIndex(value, function (childValue, index) {
+                    serialized[index] = this[methodName](childValue);
+                }, this);
+            } else {
+                this.eachKey(value, function (childValue, prop) {
+                    serialized[prop] = this[methodName](childValue);
+                }, this);
+            }
+        }
+        if (firstSerialize) {
+            serializeMap = null;
+        }
+        return serialized;
+    };
+}
+var makeMap;
+if (typeof Map !== 'undefined') {
+    makeMap = function (keys) {
+        var map = new Map();
+        shapeReflections.eachIndex(keys, function (key) {
+            map.set(key, true);
+        });
+        return map;
+    };
+} else {
+    makeMap = function (keys) {
+        var map = {};
+        keys.forEach(function (key) {
+            map[key] = true;
+        });
+        return {
+            get: function (key) {
+                return map[key];
+            },
+            set: function (key, value) {
+                map[key] = value;
+            },
+            keys: function () {
+                return keys;
+            }
+        };
+    };
+}
+var fastHasOwnKey = function (obj) {
+    var hasOwnKey = obj[canSymbol.for('can.hasOwnKey')];
+    if (hasOwnKey) {
+        return hasOwnKey.bind(obj);
+    } else {
+        var map = makeMap(shapeReflections.getOwnEnumerableKeys(obj));
+        return function (key) {
+            return map.get(key);
+        };
+    }
+};
+function addPatch(patches, patch) {
+    var lastPatch = patches[patches.length - 1];
+    if (lastPatch) {
+        if (lastPatch.deleteCount === lastPatch.insert.length && patch.index - lastPatch.index === lastPatch.deleteCount) {
+            lastPatch.insert.push.apply(lastPatch.insert, patch.insert);
+            lastPatch.deleteCount += patch.deleteCount;
+            return;
+        }
+    }
+    patches.push(patch);
+}
+function updateDeepList(target, source, isAssign) {
+    var sourceArray = this.toArray(source);
+    var patches = [], lastIndex = -1;
+    this.eachIndex(target, function (curVal, index) {
+        lastIndex = index;
+        if (index >= sourceArray.length) {
+            if (!isAssign) {
+                addPatch(patches, {
+                    index: index,
+                    deleteCount: sourceArray.length - index + 1,
+                    insert: []
+                });
+            }
+            return false;
+        }
+        var newVal = sourceArray[index];
+        if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) {
+            addPatch(patches, {
+                index: index,
+                deleteCount: 1,
+                insert: [newVal]
+            });
+        } else {
+            this.updateDeep(curVal, newVal);
+        }
+    }, this);
+    if (sourceArray.length > lastIndex) {
+        addPatch(patches, {
+            index: lastIndex + 1,
+            deleteCount: 0,
+            insert: sourceArray.slice(lastIndex + 1)
+        });
+    }
+    for (var i = 0, patchLen = patches.length; i < patchLen; i++) {
+        var patch = patches[i];
+        getSetReflections.splice(target, patch.index, patch.deleteCount, patch.insert);
+    }
+    return target;
+}
+shapeReflections = {
+    each: function (obj, callback, context) {
+        if (typeReflections.isIteratorLike(obj) || typeReflections.isMoreListLikeThanMapLike(obj)) {
+            return this.eachIndex(obj, callback, context);
+        } else {
+            return this.eachKey(obj, callback, context);
+        }
+    },
+    eachIndex: function (list, callback, context) {
+        if (Array.isArray(list)) {
+            return this.eachListLike(list, callback, context);
+        } else {
+            var iter, iterator = list[canSymbol.iterator];
+            if (typeReflections.isIteratorLike(list)) {
+                iter = list;
+            } else if (iterator) {
+                iter = iterator.call(list);
+            }
+            if (iter) {
+                var res, index = 0;
+                while (!(res = iter.next()).done) {
+                    if (callback.call(context || list, res.value, index++, list) === false) {
+                        break;
+                    }
+                }
+            } else {
+                this.eachListLike(list, callback, context);
+            }
+        }
+        return list;
+    },
+    eachListLike: function (list, callback, context) {
+        var index = -1;
+        var length = list.length;
+        if (length === undefined) {
+            var size = list[sizeSymbol];
+            if (size) {
+                length = size.call(list);
+            } else {
+                throw new Error('can-reflect: unable to iterate.');
+            }
+        }
+        while (++index < length) {
+            var item = list[index];
+            if (callback.call(context || item, item, index, list) === false) {
+                break;
+            }
+        }
+        return list;
+    },
+    toArray: function (obj) {
+        var arr = [];
+        this.each(obj, function (value) {
+            arr.push(value);
+        });
+        return arr;
+    },
+    eachKey: function (obj, callback, context) {
+        if (obj) {
+            var enumerableKeys = this.getOwnEnumerableKeys(obj);
+            var getKeyValue = obj[getKeyValueSymbol] || shiftedGetKeyValue;
+            return this.eachIndex(enumerableKeys, function (key) {
+                var value = getKeyValue.call(obj, key);
+                return callback.call(context || obj, value, key, obj);
+            });
+        }
+        return obj;
+    },
+    'hasOwnKey': function (obj, key) {
+        var hasOwnKey = obj[canSymbol.for('can.hasOwnKey')];
+        if (hasOwnKey) {
+            return hasOwnKey.call(obj, key);
+        }
+        var getOwnKeys = obj[canSymbol.for('can.getOwnKeys')];
+        if (getOwnKeys) {
+            var found = false;
+            this.eachIndex(getOwnKeys.call(obj), function (objKey) {
+                if (objKey === key) {
+                    found = true;
+                    return false;
+                }
+            });
+            return found;
+        }
+        return obj.hasOwnProperty(key);
+    },
+    getOwnEnumerableKeys: function (obj) {
+        var getOwnEnumerableKeys = obj[canSymbol.for('can.getOwnEnumerableKeys')];
+        if (getOwnEnumerableKeys) {
+            return getOwnEnumerableKeys.call(obj);
+        }
+        if (obj[canSymbol.for('can.getOwnKeys')] && obj[canSymbol.for('can.getOwnKeyDescriptor')]) {
+            var keys = [];
+            this.eachIndex(this.getOwnKeys(obj), function (key) {
+                var descriptor = this.getOwnKeyDescriptor(obj, key);
+                if (descriptor.enumerable) {
+                    keys.push(key);
+                }
+            }, this);
+            return keys;
+        } else {
+            return Object_Keys(obj);
+        }
+    },
+    getOwnKeys: function (obj) {
+        var getOwnKeys = obj[canSymbol.for('can.getOwnKeys')];
+        if (getOwnKeys) {
+            return getOwnKeys.call(obj);
+        } else {
+            return Object.getOwnPropertyNames(obj);
+        }
+    },
+    getOwnKeyDescriptor: function (obj, key) {
+        var getOwnKeyDescriptor = obj[canSymbol.for('can.getOwnKeyDescriptor')];
+        if (getOwnKeyDescriptor) {
+            return getOwnKeyDescriptor.call(obj, key);
+        } else {
+            return Object.getOwnPropertyDescriptor(obj, key);
+        }
+    },
+    unwrap: makeSerializer('unwrap', [canSymbol.for('can.unwrap')]),
+    serialize: makeSerializer('serialize', [
+        canSymbol.for('can.serialize'),
+        canSymbol.for('can.unwrap')
+    ]),
+    assignMap: function (target, source) {
+        var hasOwnKey = fastHasOwnKey(target);
+        var getKeyValue = target[getKeyValueSymbol] || shiftedGetKeyValue;
+        var setKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue;
+        this.eachKey(source, function (value, key) {
+            if (!hasOwnKey(key) || getKeyValue.call(target, key) !== value) {
+                setKeyValue.call(target, key, value);
+            }
+        });
+        return target;
+    },
+    assignList: function (target, source) {
+        var inserting = this.toArray(source);
+        getSetReflections.splice(target, 0, inserting, inserting);
+        return target;
+    },
+    assign: function (target, source) {
+        if (typeReflections.isIteratorLike(source) || typeReflections.isMoreListLikeThanMapLike(source)) {
+            this.assignList(target, source);
+        } else {
+            this.assignMap(target, source);
+        }
+        return target;
+    },
+    assignDeepMap: function (target, source) {
+        var hasOwnKey = fastHasOwnKey(target);
+        var getKeyValue = target[getKeyValueSymbol] || shiftedGetKeyValue;
+        var setKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue;
+        this.eachKey(source, function (newVal, key) {
+            if (!hasOwnKey(key)) {
+                getSetReflections.setKeyValue(target, key, newVal);
+            } else {
+                var curVal = getKeyValue.call(target, key);
+                if (newVal === curVal) {
+                } else if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) {
+                    setKeyValue.call(target, key, newVal);
+                } else {
+                    this.assignDeep(curVal, newVal);
+                }
+            }
+        }, this);
+        return target;
+    },
+    assignDeepList: function (target, source) {
+        return updateDeepList.call(this, target, source, true);
+    },
+    assignDeep: function (target, source) {
+        var assignDeep = target[canSymbol.for('can.assignDeep')];
+        if (assignDeep) {
+            assignDeep.call(target, source);
+        } else if (typeReflections.isMoreListLikeThanMapLike(source)) {
+            this.assignDeepList(target, source);
+        } else {
+            this.assignDeepMap(target, source);
+        }
+        return target;
+    },
+    updateMap: function (target, source) {
+        var sourceKeyMap = makeMap(this.getOwnEnumerableKeys(source));
+        var sourceGetKeyValue = source[getKeyValueSymbol] || shiftedGetKeyValue;
+        var targetSetKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue;
+        this.eachKey(target, function (curVal, key) {
+            if (!sourceKeyMap.get(key)) {
+                getSetReflections.deleteKeyValue(target, key);
+                return;
+            }
+            sourceKeyMap.set(key, false);
+            var newVal = sourceGetKeyValue.call(source, key);
+            if (newVal !== curVal) {
+                targetSetKeyValue.call(target, key, newVal);
+            }
+        }, this);
+        this.eachIndex(sourceKeyMap.keys(), function (key) {
+            if (sourceKeyMap.get(key)) {
+                targetSetKeyValue.call(target, key, sourceGetKeyValue.call(source, key));
+            }
+        });
+        return target;
+    },
+    updateList: function (target, source) {
+        var inserting = this.toArray(source);
+        getSetReflections.splice(target, 0, target, inserting);
+        return target;
+    },
+    update: function (target, source) {
+        if (typeReflections.isIteratorLike(source) || typeReflections.isMoreListLikeThanMapLike(source)) {
+            this.updateList(target, source);
+        } else {
+            this.updateMap(target, source);
+        }
+        return target;
+    },
+    updateDeepMap: function (target, source) {
+        var sourceKeyMap = makeMap(this.getOwnEnumerableKeys(source));
+        var sourceGetKeyValue = source[getKeyValueSymbol] || shiftedGetKeyValue;
+        var targetSetKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue;
+        this.eachKey(target, function (curVal, key) {
+            if (!sourceKeyMap.get(key)) {
+                getSetReflections.deleteKeyValue(target, key);
+                return;
+            }
+            sourceKeyMap.set(key, false);
+            var newVal = sourceGetKeyValue.call(source, key);
+            if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) {
+                targetSetKeyValue.call(target, key, newVal);
+            } else {
+                this.updateDeep(curVal, newVal);
+            }
+        }, this);
+        this.eachIndex(sourceKeyMap.keys(), function (key) {
+            if (sourceKeyMap.get(key)) {
+                targetSetKeyValue.call(target, key, sourceGetKeyValue.call(source, key));
+            }
+        });
+        return target;
+    },
+    updateDeepList: function (target, source) {
+        return updateDeepList.call(this, target, source);
+    },
+    updateDeep: function (target, source) {
+        var updateDeep = target[canSymbol.for('can.updateDeep')];
+        if (updateDeep) {
+            updateDeep.call(target, source);
+        } else if (typeReflections.isMoreListLikeThanMapLike(source)) {
+            this.updateDeepList(target, source);
+        } else {
+            this.updateDeepMap(target, source);
+        }
+        return target;
+    },
+    'in': function () {
+    },
+    getAllEnumerableKeys: function () {
+    },
+    getAllKeys: function () {
+    },
+    assignSymbols: function (target, source) {
+        this.eachKey(source, function (value, key) {
+            var symbol = typeReflections.isSymbolLike(canSymbol[key]) ? canSymbol[key] : canSymbol.for(key);
+            getSetReflections.setKeyValue(target, symbol, value);
+        });
+        return target;
+    },
+    isSerializable: isSerializable,
+    size: function (obj) {
+        var size = obj[sizeSymbol];
+        var count = 0;
+        if (size) {
+            return size.call(obj);
+        } else if (helpers.hasLength(obj)) {
+            return obj.length;
+        } else if (typeReflections.isListLike(obj)) {
+            this.each(obj, function () {
+                count++;
+            });
+            return count;
+        } else if (obj) {
+            for (var prop in obj) {
+                if (obj.hasOwnProperty(prop)) {
+                    count++;
+                }
+            }
+            return count;
+        } else {
+            return undefined;
+        }
+    },
+    defineInstanceKey: function (cls, key, properties) {
+        var defineInstanceKey = cls[canSymbol.for('can.defineInstanceKey')];
+        if (defineInstanceKey) {
+            return defineInstanceKey.call(cls, key, properties);
+        }
+        var proto = cls.prototype;
+        defineInstanceKey = proto[canSymbol.for('can.defineInstanceKey')];
+        if (defineInstanceKey) {
+            defineInstanceKey.call(proto, key, properties);
+        } else {
+            Object.defineProperty(proto, key, shapeReflections.assign({
+                configurable: true,
+                enumerable: !typeReflections.isSymbolLike(key),
+                writable: true
+            }, properties));
+        }
+    }
+};
+shapeReflections.keys = shapeReflections.getOwnEnumerableKeys;
+module.exports = shapeReflections;
\ No newline at end of file
diff --git a/dist/cjs/reflections/type/type.js b/dist/cjs/reflections/type/type.js
new file mode 100644
index 0000000..4cc6ad5
--- /dev/null
+++ b/dist/cjs/reflections/type/type.js
@@ -0,0 +1,192 @@
+/*can-reflect@1.7.3#reflections/type/type*/
+var canSymbol = require('can-symbol');
+var helpers = require('../helpers.js');
+var plainFunctionPrototypePropertyNames = Object.getOwnPropertyNames(function () {
+}.prototype);
+var plainFunctionPrototypeProto = Object.getPrototypeOf(function () {
+}.prototype);
+function isConstructorLike(func) {
+    var value = func[canSymbol.for('can.new')];
+    if (value !== undefined) {
+        return value;
+    }
+    if (typeof func !== 'function') {
+        return false;
+    }
+    var prototype = func.prototype;
+    if (!prototype) {
+        return false;
+    }
+    if (plainFunctionPrototypeProto !== Object.getPrototypeOf(prototype)) {
+        return true;
+    }
+    var propertyNames = Object.getOwnPropertyNames(prototype);
+    if (propertyNames.length === plainFunctionPrototypePropertyNames.length) {
+        for (var i = 0, len = propertyNames.length; i < len; i++) {
+            if (propertyNames[i] !== plainFunctionPrototypePropertyNames[i]) {
+                return true;
+            }
+        }
+        return false;
+    } else {
+        return true;
+    }
+}
+var getNewOrApply = helpers.makeGetFirstSymbolValue([
+    'can.new',
+    'can.apply'
+]);
+function isFunctionLike(obj) {
+    var result, symbolValue = obj[canSymbol.for('can.isFunctionLike')];
+    if (symbolValue !== undefined) {
+        return symbolValue;
+    }
+    result = getNewOrApply(obj);
+    if (result !== undefined) {
+        return !!result;
+    }
+    return typeof obj === 'function';
+}
+function isPrimitive(obj) {
+    var type = typeof obj;
+    if (obj == null || type !== 'function' && type !== 'object') {
+        return true;
+    } else {
+        return false;
+    }
+}
+function isBuiltIn(obj) {
+    if (isPrimitive(obj) || Array.isArray(obj) || isPlainObject(obj) || Object.prototype.toString.call(obj) !== '[object Object]' && Object.prototype.toString.call(obj).indexOf('[object ') !== -1) {
+        return true;
+    } else {
+        return false;
+    }
+}
+function isValueLike(obj) {
+    var symbolValue;
+    if (isPrimitive(obj)) {
+        return true;
+    }
+    symbolValue = obj[canSymbol.for('can.isValueLike')];
+    if (typeof symbolValue !== 'undefined') {
+        return symbolValue;
+    }
+    var value = obj[canSymbol.for('can.getValue')];
+    if (value !== undefined) {
+        return !!value;
+    }
+}
+function isMapLike(obj) {
+    if (isPrimitive(obj)) {
+        return false;
+    }
+    var isMapLike = obj[canSymbol.for('can.isMapLike')];
+    if (typeof isMapLike !== 'undefined') {
+        return !!isMapLike;
+    }
+    var value = obj[canSymbol.for('can.getKeyValue')];
+    if (value !== undefined) {
+        return !!value;
+    }
+    return true;
+}
+var getObservableLikeSymbol = helpers.makeGetFirstSymbolValue([
+    'can.onValue',
+    'can.onKeyValue',
+    'can.onKeys',
+    'can.onKeysAdded'
+]);
+function isObservableLike(obj) {
+    if (isPrimitive(obj)) {
+        return false;
+    }
+    var result = getObservableLikeSymbol(obj);
+    if (result !== undefined) {
+        return !!result;
+    }
+    return false;
+}
+function isListLike(list) {
+    var symbolValue, type = typeof list;
+    if (type === 'string') {
+        return true;
+    }
+    if (isPrimitive(list)) {
+        return false;
+    }
+    symbolValue = list[canSymbol.for('can.isListLike')];
+    if (typeof symbolValue !== 'undefined') {
+        return symbolValue;
+    }
+    var value = list[canSymbol.iterator];
+    if (value !== undefined) {
+        return !!value;
+    }
+    if (Array.isArray(list)) {
+        return true;
+    }
+    return helpers.hasLength(list);
+}
+var supportsSymbols = typeof Symbol !== 'undefined' && typeof Symbol.for === 'function';
+var isSymbolLike;
+if (supportsSymbols) {
+    isSymbolLike = function (symbol) {
+        return typeof symbol === 'symbol';
+    };
+} else {
+    var symbolStart = '@@symbol';
+    isSymbolLike = function (symbol) {
+        if (typeof symbol === 'object' && !Array.isArray(symbol)) {
+            return symbol.toString().substr(0, symbolStart.length) === symbolStart;
+        } else {
+            return false;
+        }
+    };
+}
+var coreHasOwn = Object.prototype.hasOwnProperty;
+var funcToString = Function.prototype.toString;
+var objectCtorString = funcToString.call(Object);
+function isPlainObject(obj) {
+    if (!obj || typeof obj !== 'object') {
+        return false;
+    }
+    var proto = Object.getPrototypeOf(obj);
+    if (proto === Object.prototype || proto === null) {
+        return true;
+    }
+    var Constructor = coreHasOwn.call(proto, 'constructor') && proto.constructor;
+    return typeof Constructor === 'function' && Constructor instanceof Constructor && funcToString.call(Constructor) === objectCtorString;
+}
+module.exports = {
+    isConstructorLike: isConstructorLike,
+    isFunctionLike: isFunctionLike,
+    isListLike: isListLike,
+    isMapLike: isMapLike,
+    isObservableLike: isObservableLike,
+    isPrimitive: isPrimitive,
+    isBuiltIn: isBuiltIn,
+    isValueLike: isValueLike,
+    isSymbolLike: isSymbolLike,
+    isMoreListLikeThanMapLike: function (obj) {
+        if (Array.isArray(obj)) {
+            return true;
+        }
+        var value = obj[canSymbol.for('can.isMoreListLikeThanMapLike')];
+        if (value !== undefined) {
+            return value;
+        }
+        var isListLike = this.isListLike(obj), isMapLike = this.isMapLike(obj);
+        if (isListLike && !isMapLike) {
+            return true;
+        } else if (!isListLike && isMapLike) {
+            return false;
+        }
+    },
+    isIteratorLike: function (obj) {
+        return obj && typeof obj === 'object' && typeof obj.next === 'function' && obj.next.length === 0;
+    },
+    isPromise: function (obj) {
+        return obj instanceof Promise || Object.prototype.toString.call(obj) === '[object Promise]';
+    },
+    isPlainObject: isPlainObject
+};
\ No newline at end of file
diff --git a/dist/cjs/types/map.js b/dist/cjs/types/map.js
new file mode 100644
index 0000000..48c2be0
--- /dev/null
+++ b/dist/cjs/types/map.js
@@ -0,0 +1,41 @@
+/*can-reflect@1.7.3#types/map*/
+var shape = require('../reflections/shape/shape.js');
+var CanSymbol = require('can-symbol');
+function keysPolyfill() {
+    var keys = [];
+    var currentIndex = 0;
+    this.forEach(function (val, key) {
+        keys.push(key);
+    });
+    return {
+        next: function () {
+            return {
+                value: keys[currentIndex],
+                done: currentIndex++ === keys.length
+            };
+        }
+    };
+}
+if (typeof Map !== 'undefined') {
+    shape.assignSymbols(Map.prototype, {
+        'can.getOwnEnumerableKeys': Map.prototype.keys,
+        'can.setKeyValue': Map.prototype.set,
+        'can.getKeyValue': Map.prototype.get,
+        'can.deleteKeyValue': Map.prototype['delete'],
+        'can.hasOwnKey': Map.prototype.has
+    });
+    if (typeof Map.prototype.keys !== 'function') {
+        Map.prototype.keys = Map.prototype[CanSymbol.for('can.getOwnEnumerableKeys')] = keysPolyfill;
+    }
+}
+if (typeof WeakMap !== 'undefined') {
+    shape.assignSymbols(WeakMap.prototype, {
+        'can.getOwnEnumerableKeys': function () {
+            throw new Error('can-reflect: WeakMaps do not have enumerable keys.');
+        },
+        'can.setKeyValue': WeakMap.prototype.set,
+        'can.getKeyValue': WeakMap.prototype.get,
+        'can.deleteKeyValue': WeakMap.prototype['delete'],
+        'can.hasOwnKey': WeakMap.prototype.has
+    });
+}
\ No newline at end of file
diff --git a/dist/cjs/types/set.js b/dist/cjs/types/set.js
new file mode 100644
index 0000000..2328789
--- /dev/null
+++ b/dist/cjs/types/set.js
@@ -0,0 +1,57 @@
+/*can-reflect@1.7.3#types/set*/
+var shape = require('../reflections/shape/shape.js');
+var CanSymbol = require('can-symbol');
+if (typeof Set !== 'undefined') {
+    shape.assignSymbols(Set.prototype, {
+        'can.isMoreListLikeThanMapLike': true,
+        'can.updateValues': function (index, removing, adding) {
+            if (removing !== adding) {
+                shape.each(removing, function (value) {
+                    this.delete(value);
+                }, this);
+            }
+            shape.each(adding, function (value) {
+                this.add(value);
+            }, this);
+        },
+        'can.size': function () {
+            return this.size;
+        }
+    });
+    if (typeof Set.prototype[CanSymbol.iterator] !== 'function') {
+        Set.prototype[CanSymbol.iterator] = function () {
+            var arr = [];
+            var currentIndex = 0;
+            this.forEach(function (val) {
+                arr.push(val);
+            });
+            return {
+                next: function () {
+                    return {
+                        value: arr[currentIndex],
+                        done: currentIndex++ === arr.length
+                    };
+                }
+            };
+        };
+    }
+}
+if (typeof WeakSet !== 'undefined') {
+    shape.assignSymbols(WeakSet.prototype, {
+        'can.isListLike': true,
+        'can.isMoreListLikeThanMapLike': true,
+        'can.updateValues': function (index, removing, adding) {
+            if (removing !== adding) {
+                shape.each(removing, function (value) {
+                    this.delete(value);
+                }, this);
+            }
+            shape.each(adding, function (value) {
+                this.add(value);
+            }, this);
+        },
+        'can.size': function () {
+            throw new Error('can-reflect: WeakSets do not have enumerable keys.');
+        }
+    });
+}
\ No newline at end of file
diff --git a/dist/global/can-reflect.js b/dist/global/can-reflect.js
new file mode 100644
index 0000000..4aaae4c
--- /dev/null
+++ b/dist/global/can-reflect.js
@@ -0,0 +1,1332 @@
+/*[global-shim-start]*/
+(function(exports, global, doEval) {
+	// jshint ignore:line
+	var origDefine = global.define;
+
+	var get = function(name) {
+		var parts = name.split("."),
+			cur = global,
+			i;
+		for (i = 0; i < parts.length; i++) {
+			if (!cur) {
+				break;
+			}
+			cur = cur[parts[i]];
+		}
+		return cur;
+	};
+	var set = function(name, val) {
+		var parts = name.split("."),
+			cur = global,
+			i,
+			part,
+			next;
+		for (i = 0; i < parts.length - 1; i++) {
+			part = parts[i];
+			next = cur[part];
+			if (!next) {
+				next = cur[part] = {};
+			}
+			cur = next;
+		}
+		part = parts[parts.length - 1];
+		cur[part] = val;
+	};
+	var useDefault = function(mod) {
+		if (!mod || !mod.__esModule) return false;
+		var esProps = { __esModule: true, default: true };
+		for (var p in mod) {
+			if (!esProps[p]) return false;
+		}
+		return true;
+	};
+
+	var hasCjsDependencies = function(deps) {
+		return (
+			deps[0] === "require" && deps[1] === "exports" && deps[2] === "module"
+		);
+	};
+
+	var modules =
+		(global.define && global.define.modules) ||
+		(global._define && global._define.modules) ||
+		{};
+	var ourDefine = (global.define = function(moduleName, deps, callback) {
+		var module;
+		if (typeof deps === "function") {
+			callback = deps;
+			deps = [];
+		}
+		var args = [],
+			i;
+		for (i = 0; i < deps.length; i++) {
+			args.push(
+				exports[deps[i]]
+					? get(exports[deps[i]])
+					: modules[deps[i]] || get(deps[i])
+			);
+		}
+		// CJS has no dependencies but 3 callback arguments
+		if (hasCjsDependencies(deps) || (!deps.length && callback.length)) {
+			module = { exports: {} };
+			args[0] = function(name) {
+				return exports[name] ? get(exports[name]) : modules[name];
+			};
+			args[1] = module.exports;
+			args[2] = module;
+		} else if (!args[0] && deps[0] === "exports") {
+			// Babel uses the exports and module object.
+			module = { exports: {} };
+			args[0] = module.exports;
+			if (deps[1] === "module") {
+				args[1] = module;
+			}
+		} else if (!args[0] && deps[0] === "module") {
+			args[0] = { id: moduleName };
+		}
+
+		global.define = origDefine;
+		var result = callback ? callback.apply(null, args) : undefined;
+		global.define = ourDefine;
+
+		// Favor CJS module.exports over the return value
+		result = module && module.exports ? module.exports : result;
+		modules[moduleName] = result;
+
+		// Set global exports
+		var globalExport = exports[moduleName];
+		if (globalExport && !get(globalExport)) {
+			if (useDefault(result)) {
+				result = result["default"];
+			}
+			set(globalExport, result);
+		}
+	});
+	global.define.orig = origDefine;
+	global.define.modules = modules;
+	global.define.amd = true;
+	ourDefine("@loader", [], function() {
+		// shim for @@global-helpers
+		var noop = function() {};
+		return {
+			get: function() {
+				return { prepareGlobal: noop, retrieveGlobal: noop };
+			},
+			global: global,
+			__exec: function(__load) {
+				doEval(__load.source, global);
+			}
+		};
+	});
+})(
+	{},
+	typeof self == "object" && self.Object == Object ? self : window,
+	function(__$source__, __$global__) {
+		// jshint ignore:line
+		eval("(function() { " + __$source__ + " \n }).call(__$global__);");
+	}
+);
+
+/*can-reflect@1.7.3#reflections/helpers*/
+define('can-reflect/reflections/helpers', [
+    'require',
+    'exports',
+    'module',
+    'can-symbol'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    module.exports = {
+        makeGetFirstSymbolValue: function (symbolNames) {
+            var symbols = symbolNames.map(function (name) {
+                return canSymbol.for(name);
+            });
+            var length = symbols.length;
+            return function getFirstSymbol(obj) {
+                var index = -1;
+                while (++index < length) {
+                    if (obj[symbols[index]] !== undefined) {
+                        return obj[symbols[index]];
+                    }
+                }
+            };
+        },
+        hasLength: function (list) {
+            var type = typeof list;
+            var length = list && type !== 'boolean' && typeof list !== 'number' && 'length' in list && list.length;
+            return typeof list !== 'function' && (length === 0 || typeof length === 'number' && length > 0 && length - 1 in list);
+        }
+    };
+});
+/*can-reflect@1.7.3#reflections/type/type*/
+define('can-reflect/reflections/type/type', [
+    'require',
+    'exports',
+    'module',
+    'can-symbol',
+    'can-reflect/reflections/helpers'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    var helpers = require('can-reflect/reflections/helpers');
+    var plainFunctionPrototypePropertyNames = Object.getOwnPropertyNames(function () {
+    }.prototype);
+    var plainFunctionPrototypeProto = Object.getPrototypeOf(function () {
+    }.prototype);
+    function isConstructorLike(func) {
+        var value = func[canSymbol.for('can.new')];
+        if (value !== undefined) {
+            return value;
+        }
+        if (typeof func !== 'function') {
+            return false;
+        }
+        var prototype = func.prototype;
+        if (!prototype) {
+            return false;
+        }
+        if (plainFunctionPrototypeProto !== Object.getPrototypeOf(prototype)) {
+            return true;
+        }
+        var propertyNames = Object.getOwnPropertyNames(prototype);
+        if (propertyNames.length === plainFunctionPrototypePropertyNames.length) {
+            for (var i = 0, len = propertyNames.length; i < len; i++) {
+                if (propertyNames[i] !== plainFunctionPrototypePropertyNames[i]) {
+                    return true;
+                }
+            }
+            return false;
+        } else {
+            return true;
+        }
+    }
+    var getNewOrApply = helpers.makeGetFirstSymbolValue([
+        'can.new',
+        'can.apply'
+    ]);
+    function isFunctionLike(obj) {
+        var result, symbolValue = obj[canSymbol.for('can.isFunctionLike')];
+        if (symbolValue !== undefined) {
+            return symbolValue;
+        }
+        result = getNewOrApply(obj);
+        if (result !== undefined) {
+            return !!result;
+        }
+        return typeof obj === 'function';
+    }
+    function isPrimitive(obj) {
+        var type = typeof obj;
+        if (obj == null || type !== 'function' && type !== 'object') {
+            return true;
+        } else {
+            return false;
+        }
+    }
+    function isBuiltIn(obj) {
+        if (isPrimitive(obj) || Array.isArray(obj) || isPlainObject(obj) || Object.prototype.toString.call(obj) !== '[object Object]' && Object.prototype.toString.call(obj).indexOf('[object ') !== -1) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+    function isValueLike(obj) {
+        var symbolValue;
+        if (isPrimitive(obj)) {
+            return true;
+        }
+        symbolValue = obj[canSymbol.for('can.isValueLike')];
+        if (typeof symbolValue !== 'undefined') {
+            return symbolValue;
+        }
+        var value = obj[canSymbol.for('can.getValue')];
+        if (value !== undefined) {
+            return !!value;
+        }
+    }
+    function isMapLike(obj) {
+        if (isPrimitive(obj)) {
+            return false;
+        }
+        var isMapLike = obj[canSymbol.for('can.isMapLike')];
+        if (typeof isMapLike !== 'undefined') {
+            return !!isMapLike;
+        }
+        var value = obj[canSymbol.for('can.getKeyValue')];
+        if (value !== undefined) {
+            return !!value;
+        }
+        return true;
+    }
+    var getObservableLikeSymbol = helpers.makeGetFirstSymbolValue([
+        'can.onValue',
+        'can.onKeyValue',
+        'can.onKeys',
+        'can.onKeysAdded'
+    ]);
+    function isObservableLike(obj) {
+        if (isPrimitive(obj)) {
+            return false;
+        }
+        var result = getObservableLikeSymbol(obj);
+        if (result !== undefined) {
+            return !!result;
+        }
+        return false;
+    }
+    function isListLike(list) {
+        var symbolValue, type = typeof list;
+        if (type === 'string') {
+            return true;
+        }
+        if (isPrimitive(list)) {
+            return false;
+        }
+        symbolValue = list[canSymbol.for('can.isListLike')];
+        if (typeof symbolValue !== 'undefined') {
+            return symbolValue;
+        }
+        var value = list[canSymbol.iterator];
+        if (value !== undefined) {
+            return !!value;
+        }
+        if (Array.isArray(list)) {
+            return true;
+        }
+        return helpers.hasLength(list);
+    }
+    var supportsSymbols = typeof Symbol !== 'undefined' && typeof Symbol.for === 'function';
+    var isSymbolLike;
+    if (supportsSymbols) {
+        isSymbolLike = function (symbol) {
+            return typeof symbol === 'symbol';
+        };
+    } else {
+        var symbolStart = '@@symbol';
+        isSymbolLike = function (symbol) {
+            if (typeof symbol === 'object' && !Array.isArray(symbol)) {
+                return symbol.toString().substr(0, symbolStart.length) === symbolStart;
+            } else {
+                return false;
+            }
+        };
+    }
+    var coreHasOwn = Object.prototype.hasOwnProperty;
+    var funcToString = Function.prototype.toString;
+    var objectCtorString = funcToString.call(Object);
+    function isPlainObject(obj) {
+        if (!obj || typeof obj !== 'object') {
+            return false;
+        }
+        var proto = Object.getPrototypeOf(obj);
+        if (proto === Object.prototype || proto === null) {
+            return true;
+        }
+        var Constructor = coreHasOwn.call(proto, 'constructor') && proto.constructor;
+        return typeof Constructor === 'function' && Constructor instanceof Constructor && funcToString.call(Constructor) === objectCtorString;
+    }
+    module.exports = {
+        isConstructorLike: isConstructorLike,
+        isFunctionLike: isFunctionLike,
+        isListLike: isListLike,
+        isMapLike: isMapLike,
+        isObservableLike: isObservableLike,
+        isPrimitive: isPrimitive,
+        isBuiltIn: isBuiltIn,
+        isValueLike: isValueLike,
+        isSymbolLike: isSymbolLike,
+        isMoreListLikeThanMapLike: function (obj) {
+            if (Array.isArray(obj)) {
+                return true;
+            }
+            var value = obj[canSymbol.for('can.isMoreListLikeThanMapLike')];
+            if (value !== undefined) {
+                return value;
+            }
+            var isListLike = this.isListLike(obj), isMapLike = this.isMapLike(obj);
+            if (isListLike && !isMapLike) {
+                return true;
+            } else if (!isListLike && isMapLike) {
+                return false;
+            }
+        },
+        isIteratorLike: function (obj) {
+            return obj && typeof obj === 'object' && typeof obj.next === 'function' && obj.next.length === 0;
+        },
+        isPromise: function (obj) {
+            return obj instanceof Promise || Object.prototype.toString.call(obj) === '[object Promise]';
+        },
+        isPlainObject: isPlainObject
+    };
+});
+/*can-reflect@1.7.3#reflections/call/call*/
+define('can-reflect/reflections/call/call', [
+    'require',
+    'exports',
+    'module',
+    'can-symbol',
+    'can-reflect/reflections/type/type'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    var typeReflections = require('can-reflect/reflections/type/type');
+    module.exports = {
+        call: function (func, context) {
+            var args = [].slice.call(arguments, 2);
+            var apply = func[canSymbol.for('can.apply')];
+            if (apply) {
+                return apply.call(func, context, args);
+            } else {
+                return func.apply(context, args);
+            }
+        },
+        apply: function (func, context, args) {
+            var apply = func[canSymbol.for('can.apply')];
+            if (apply) {
+                return apply.call(func, context, args);
+            } else {
+                return func.apply(context, args);
+            }
+        },
+        'new': function (func) {
+            var args = [].slice.call(arguments, 1);
+            var makeNew = func[canSymbol.for('can.new')];
+            if (makeNew) {
+                return makeNew.apply(func, args);
+            } else {
+                var context = Object.create(func.prototype);
+                var ret = func.apply(context, args);
+                if (typeReflections.isPrimitive(ret)) {
+                    return context;
+                } else {
+                    return ret;
+                }
+            }
+        }
+    };
+});
+/*can-reflect@1.7.3#reflections/get-set/get-set*/
+define('can-reflect/reflections/get-set/get-set', [
+    'require',
+    'exports',
+    'module',
+    'can-symbol',
+    'can-reflect/reflections/type/type'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    var typeReflections = require('can-reflect/reflections/type/type');
+    var setKeyValueSymbol = canSymbol.for('can.setKeyValue'), getKeyValueSymbol = canSymbol.for('can.getKeyValue'), getValueSymbol = canSymbol.for('can.getValue'), setValueSymbol = canSymbol.for('can.setValue');
+    var reflections = {
+        setKeyValue: function (obj, key, value) {
+            if (typeReflections.isSymbolLike(key)) {
+                if (typeof key === 'symbol') {
+                    obj[key] = value;
+                } else {
+                    Object.defineProperty(obj, key, {
+                        enumerable: false,
+                        configurable: true,
+                        value: value,
+                        writable: true
+                    });
+                }
+                return;
+            }
+            var setKeyValue = obj[setKeyValueSymbol];
+            if (setKeyValue !== undefined) {
+                return setKeyValue.call(obj, key, value);
+            } else {
+                obj[key] = value;
+            }
+        },
+        getKeyValue: function (obj, key) {
+            var getKeyValue = obj[getKeyValueSymbol];
+            if (getKeyValue) {
+                return getKeyValue.call(obj, key);
+            }
+            return obj[key];
+        },
+        deleteKeyValue: function (obj, key) {
+            var deleteKeyValue = obj[canSymbol.for('can.deleteKeyValue')];
+            if (deleteKeyValue) {
+                return deleteKeyValue.call(obj, key);
+            }
+            delete obj[key];
+        },
+        getValue: function (value) {
+            if (typeReflections.isPrimitive(value)) {
+                return value;
+            }
+            var getValue = value[getValueSymbol];
+            if (getValue) {
+                return getValue.call(value);
+            }
+            return value;
+        },
+        setValue: function (item, value) {
+            var setValue = item && item[setValueSymbol];
+            if (setValue) {
+                return setValue.call(item, value);
+            } else {
+                throw new Error('can-reflect.setValue - Can not set value.');
+            }
+        },
+        splice: function (obj, index, removing, adding) {
+            var howMany;
+            if (typeof removing !== 'number') {
+                var updateValues = obj[canSymbol.for('can.updateValues')];
+                if (updateValues) {
+                    return updateValues.call(obj, index, removing, adding);
+                }
+                howMany = removing.length;
+            } else {
+                howMany = removing;
+            }
+            var splice = obj[canSymbol.for('can.splice')];
+            if (splice) {
+                return splice.call(obj, index, howMany, adding);
+            }
+            return [].splice.apply(obj, [
+                index,
+                howMany
+            ].concat(adding));
+        },
+        addValues: function (obj, adding, index) {
+            var add = obj[canSymbol.for('can.addValues')];
+            if (add) {
+                return add.call(obj, adding, index);
+            }
+            if (Array.isArray(obj) && index === undefined) {
+                return obj.push.apply(obj, adding);
+            }
+            return reflections.splice(obj, index, [], adding);
+        },
+        removeValues: function (obj, removing, index) {
+            var removeValues = obj[canSymbol.for('can.removeValues')];
+            if (removeValues) {
+                return removeValues.call(obj, removing, index);
+            }
+            if (Array.isArray(obj) && index === undefined) {
+                removing.forEach(function (item) {
+                    var index = obj.indexOf(item);
+                    if (index >= 0) {
+                        obj.splice(index, 1);
+                    }
+                });
+                return;
+            }
+            return reflections.splice(obj, index, removing, []);
+        }
+    };
+    reflections.get = reflections.getKeyValue;
+    reflections.set = reflections.setKeyValue;
+    reflections['delete'] = reflections.deleteKeyValue;
+    module.exports = reflections;
+});
+/*can-reflect@1.7.3#reflections/observe/observe*/
+define('can-reflect/reflections/observe/observe', [
+    'require',
+    'exports',
+    'module',
+    'can-symbol'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    var slice = [].slice;
+    function makeFallback(symbolName, fallbackName) {
+        return function (obj, event, handler, queueName) {
+            var method = obj[canSymbol.for(symbolName)];
+            if (method !== undefined) {
+                return method.call(obj, event, handler, queueName);
+            }
+            return this[fallbackName].apply(this, arguments);
+        };
+    }
+    function makeErrorIfMissing(symbolName, errorMessage) {
+        return function (obj) {
+            var method = obj[canSymbol.for(symbolName)];
+            if (method !== undefined) {
+                var args = slice.call(arguments, 1);
+                return method.apply(obj, args);
+            }
+            throw new Error(errorMessage);
+        };
+    }
+    module.exports = {
+        onKeyValue: makeFallback('can.onKeyValue', 'onEvent'),
+        offKeyValue: makeFallback('can.offKeyValue', 'offEvent'),
+        onKeys: makeErrorIfMissing('can.onKeys', 'can-reflect: can not observe an onKeys event'),
+        onKeysAdded: makeErrorIfMissing('can.onKeysAdded', 'can-reflect: can not observe an onKeysAdded event'),
+        onKeysRemoved: makeErrorIfMissing('can.onKeysRemoved', 'can-reflect: can not unobserve an onKeysRemoved event'),
+        getKeyDependencies: makeErrorIfMissing('can.getKeyDependencies', 'can-reflect: can not determine dependencies'),
+        keyHasDependencies: makeErrorIfMissing('can.keyHasDependencies', 'can-reflect: can not determine if this has key dependencies'),
+        onValue: makeErrorIfMissing('can.onValue', 'can-reflect: can not observe value change'),
+        offValue: makeErrorIfMissing('can.offValue', 'can-reflect: can not unobserve value change'),
+        getValueDependencies: makeErrorIfMissing('can.getValueDependencies', 'can-reflect: can not determine dependencies'),
+        valueHasDependencies: makeErrorIfMissing('can.valueHasDependencies', 'can-reflect: can not determine if value has dependencies'),
+        onPatches: makeErrorIfMissing('can.onPatches', 'can-reflect: can not observe patches on object'),
+        offPatches: makeErrorIfMissing('can.offPatches', 'can-reflect: can not unobserve patches on object'),
+        onInstanceBoundChange: makeErrorIfMissing('can.onInstanceBoundChange', 'can-reflect: can not observe bound state change in instances.'),
+        offInstanceBoundChange: makeErrorIfMissing('can.offInstanceBoundChange', 'can-reflect: can not unobserve bound state change'),
+        isBound: makeErrorIfMissing('can.isBound', 'can-reflect: cannot determine if object is bound'),
+        onEvent: function (obj, eventName, callback, queue) {
+            if (obj) {
+                var onEvent = obj[canSymbol.for('can.onEvent')];
+                if (onEvent !== undefined) {
+                    return onEvent.call(obj, eventName, callback, queue);
+                } else if (obj.addEventListener) {
+                    obj.addEventListener(eventName, callback, queue);
+                }
+            }
+        },
+        offEvent: function (obj, eventName, callback, queue) {
+            if (obj) {
+                var offEvent = obj[canSymbol.for('can.offEvent')];
+                if (offEvent !== undefined) {
+                    return offEvent.call(obj, eventName, callback, queue);
+                } else if (obj.removeEventListener) {
+                    obj.removeEventListener(eventName, callback, queue);
+                }
+            }
+        },
+        setPriority: function (obj, priority) {
+            if (obj) {
+                var setPriority = obj[canSymbol.for('can.setPriority')];
+                if (setPriority !== undefined) {
+                    setPriority.call(obj, priority);
+                    return true;
+                }
+            }
+            return false;
+        },
+        getPriority: function (obj) {
+            if (obj) {
+                var getPriority = obj[canSymbol.for('can.getPriority')];
+                if (getPriority !== undefined) {
+                    return getPriority.call(obj);
+                }
+            }
+            return undefined;
+        }
+    };
+});
+/*can-reflect@1.7.3#reflections/shape/shape*/
+define('can-reflect/reflections/shape/shape', [
+    'require',
+    'exports',
+    'module',
+    'can-symbol',
+    'can-reflect/reflections/get-set/get-set',
+    'can-reflect/reflections/type/type',
+    'can-reflect/reflections/helpers'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    var getSetReflections = require('can-reflect/reflections/get-set/get-set');
+    var typeReflections = require('can-reflect/reflections/type/type');
+    var helpers = require('can-reflect/reflections/helpers');
+    var shapeReflections;
+    var shiftFirstArgumentToThis = function (func) {
+        return function () {
+            var args = [this];
+            args.push.apply(args, arguments);
+            return func.apply(null, args);
+        };
+    };
+    var getKeyValueSymbol = canSymbol.for('can.getKeyValue');
+    var shiftedGetKeyValue = shiftFirstArgumentToThis(getSetReflections.getKeyValue);
+    var setKeyValueSymbol = canSymbol.for('can.setKeyValue');
+    var shiftedSetKeyValue = shiftFirstArgumentToThis(getSetReflections.setKeyValue);
+    var sizeSymbol = canSymbol.for('can.size');
+    var serializeMap = null;
+    var hasUpdateSymbol = helpers.makeGetFirstSymbolValue([
+        'can.updateDeep',
+        'can.assignDeep',
+        'can.setKeyValue'
+    ]);
+    var shouldUpdateOrAssign = function (obj) {
+        return typeReflections.isPlainObject(obj) || Array.isArray(obj) || !!hasUpdateSymbol(obj);
+    };
+    function isSerializable(obj) {
+        if (typeReflections.isPrimitive(obj)) {
+            return true;
+        }
+        if (hasUpdateSymbol(obj)) {
+            return false;
+        }
+        return typeReflections.isBuiltIn(obj) && !typeReflections.isPlainObject(obj);
+    }
+    var Object_Keys;
+    try {
+        Object.keys(1);
+        Object_Keys = Object.keys;
+    } catch (e) {
+        Object_Keys = function (obj) {
+            if (typeReflections.isPrimitive(obj)) {
+                return [];
+            } else {
+                return Object.keys(obj);
+            }
+        };
+    }
+    function makeSerializer(methodName, symbolsToCheck) {
+        return function serializer(value, MapType) {
+            if (isSerializable(value)) {
+                return value;
+            }
+            var firstSerialize;
+            if (MapType && !serializeMap) {
+                serializeMap = {
+                    unwrap: new MapType(),
+                    serialize: new MapType()
+                };
+                firstSerialize = true;
+            }
+            var serialized;
+            if (typeReflections.isValueLike(value)) {
+                serialized = this[methodName](getSetReflections.getValue(value));
+            } else {
+                var isListLike = typeReflections.isIteratorLike(value) || typeReflections.isMoreListLikeThanMapLike(value);
+                serialized = isListLike ? [] : {};
+                if (serializeMap) {
+                    if (serializeMap[methodName].has(value)) {
+                        return serializeMap[methodName].get(value);
+                    } else {
+                        serializeMap[methodName].set(value, serialized);
+                    }
+                }
+                for (var i = 0, len = symbolsToCheck.length; i < len; i++) {
+                    var serializer = value[symbolsToCheck[i]];
+                    if (serializer) {
+                        var result = serializer.call(value, serialized);
+                        if (firstSerialize) {
+                            serializeMap = null;
+                        }
+                        return result;
+                    }
+                }
+                if (typeof obj === 'function') {
+                    if (serializeMap) {
+                        serializeMap[methodName].set(value, value);
+                    }
+                    serialized = value;
+                } else if (isListLike) {
+                    this.eachIndex(value, function (childValue, index) {
+                        serialized[index] = this[methodName](childValue);
+                    }, this);
+                } else {
+                    this.eachKey(value, function (childValue, prop) {
+                        serialized[prop] = this[methodName](childValue);
+                    }, this);
+                }
+            }
+            if (firstSerialize) {
+                serializeMap = null;
+            }
+            return serialized;
+        };
+    }
+    var makeMap;
+    if (typeof Map !== 'undefined') {
+        makeMap = function (keys) {
+            var map = new Map();
+            shapeReflections.eachIndex(keys, function (key) {
+                map.set(key, true);
+            });
+            return map;
+        };
+    } else {
+        makeMap = function (keys) {
+            var map = {};
+            keys.forEach(function (key) {
+                map[key] = true;
+            });
+            return {
+                get: function (key) {
+                    return map[key];
+                },
+                set: function (key, value) {
+                    map[key] = value;
+                },
+                keys: function () {
+                    return keys;
+                }
+            };
+        };
+    }
+    var fastHasOwnKey = function (obj) {
+        var hasOwnKey = obj[canSymbol.for('can.hasOwnKey')];
+        if (hasOwnKey) {
+            return hasOwnKey.bind(obj);
+        } else {
+            var map = makeMap(shapeReflections.getOwnEnumerableKeys(obj));
+            return function (key) {
+                return map.get(key);
+            };
+        }
+    };
+    function addPatch(patches, patch) {
+        var lastPatch = patches[patches.length - 1];
+        if (lastPatch) {
+            if (lastPatch.deleteCount === lastPatch.insert.length && patch.index - lastPatch.index === lastPatch.deleteCount) {
+                lastPatch.insert.push.apply(lastPatch.insert, patch.insert);
+                lastPatch.deleteCount += patch.deleteCount;
+                return;
+            }
+        }
+        patches.push(patch);
+    }
+    function updateDeepList(target, source, isAssign) {
+        var sourceArray = this.toArray(source);
+        var patches = [], lastIndex = -1;
+        this.eachIndex(target, function (curVal, index) {
+            lastIndex = index;
+            if (index >= sourceArray.length) {
+                if (!isAssign) {
+                    addPatch(patches, {
+                        index: index,
+                        deleteCount: sourceArray.length - index + 1,
+                        insert: []
+                    });
+                }
+                return false;
+            }
+            var newVal = sourceArray[index];
+            if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) {
+                addPatch(patches, {
+                    index: index,
+                    deleteCount: 1,
+                    insert: [newVal]
+                });
+            } else {
+                this.updateDeep(curVal, newVal);
+            }
+        }, this);
+        if (sourceArray.length > lastIndex) {
+            addPatch(patches, {
+                index: lastIndex + 1,
+                deleteCount: 0,
+                insert: sourceArray.slice(lastIndex + 1)
+            });
+        }
+        for (var i = 0, patchLen = patches.length; i < patchLen; i++) {
+            var patch = patches[i];
+            getSetReflections.splice(target, patch.index, patch.deleteCount, patch.insert);
+        }
+        return target;
+    }
+    shapeReflections = {
+        each: function (obj, callback, context) {
+            if (typeReflections.isIteratorLike(obj) || typeReflections.isMoreListLikeThanMapLike(obj)) {
+                return this.eachIndex(obj, callback, context);
+            } else {
+                return this.eachKey(obj, callback, context);
+            }
+        },
+        eachIndex: function (list, callback, context) {
+            if (Array.isArray(list)) {
+                return this.eachListLike(list, callback, context);
+            } else {
+                var iter, iterator = list[canSymbol.iterator];
+                if (typeReflections.isIteratorLike(list)) {
+                    iter = list;
+                } else if (iterator) {
+                    iter = iterator.call(list);
+                }
+                if (iter) {
+                    var res, index = 0;
+                    while (!(res = iter.next()).done) {
+                        if (callback.call(context || list, res.value, index++, list) === false) {
+                            break;
+                        }
+                    }
+                } else {
+                    this.eachListLike(list, callback, context);
+                }
+            }
+            return list;
+        },
+        eachListLike: function (list, callback, context) {
+            var index = -1;
+            var length = list.length;
+            if (length === undefined) {
+                var size = list[sizeSymbol];
+                if (size) {
+                    length = size.call(list);
+                } else {
+                    throw new Error('can-reflect: unable to iterate.');
+                }
+            }
+            while (++index < length) {
+                var item = list[index];
+                if (callback.call(context || item, item, index, list) === false) {
+                    break;
+                }
+            }
+            return list;
+        },
+        toArray: function (obj) {
+            var arr = [];
+            this.each(obj, function (value) {
+                arr.push(value);
+            });
+            return arr;
+        },
+        eachKey: function (obj, callback, context) {
+            if (obj) {
+                var enumerableKeys = this.getOwnEnumerableKeys(obj);
+                var getKeyValue = obj[getKeyValueSymbol] || shiftedGetKeyValue;
+                return this.eachIndex(enumerableKeys, function (key) {
+                    var value = getKeyValue.call(obj, key);
+                    return callback.call(context || obj, value, key, obj);
+                });
+            }
+            return obj;
+        },
+        'hasOwnKey': function (obj, key) {
+            var hasOwnKey = obj[canSymbol.for('can.hasOwnKey')];
+            if (hasOwnKey) {
+                return hasOwnKey.call(obj, key);
+            }
+            var getOwnKeys = obj[canSymbol.for('can.getOwnKeys')];
+            if (getOwnKeys) {
+                var found = false;
+                this.eachIndex(getOwnKeys.call(obj), function (objKey) {
+                    if (objKey === key) {
+                        found = true;
+                        return false;
+                    }
+                });
+                return found;
+            }
+            return obj.hasOwnProperty(key);
+        },
+        getOwnEnumerableKeys: function (obj) {
+            var getOwnEnumerableKeys = obj[canSymbol.for('can.getOwnEnumerableKeys')];
+            if (getOwnEnumerableKeys) {
+                return getOwnEnumerableKeys.call(obj);
+            }
+            if (obj[canSymbol.for('can.getOwnKeys')] && obj[canSymbol.for('can.getOwnKeyDescriptor')]) {
+                var keys = [];
+                this.eachIndex(this.getOwnKeys(obj), function (key) {
+                    var descriptor = this.getOwnKeyDescriptor(obj, key);
+                    if (descriptor.enumerable) {
+                        keys.push(key);
+                    }
+                }, this);
+                return keys;
+            } else {
+                return Object_Keys(obj);
+            }
+        },
+        getOwnKeys: function (obj) {
+            var getOwnKeys = obj[canSymbol.for('can.getOwnKeys')];
+            if (getOwnKeys) {
+                return getOwnKeys.call(obj);
+            } else {
+                return Object.getOwnPropertyNames(obj);
+            }
+        },
+        getOwnKeyDescriptor: function (obj, key) {
+            var getOwnKeyDescriptor = obj[canSymbol.for('can.getOwnKeyDescriptor')];
+            if (getOwnKeyDescriptor) {
+                return getOwnKeyDescriptor.call(obj, key);
+            } else {
+                return Object.getOwnPropertyDescriptor(obj, key);
+            }
+        },
+        unwrap: makeSerializer('unwrap', [canSymbol.for('can.unwrap')]),
+        serialize: makeSerializer('serialize', [
+            canSymbol.for('can.serialize'),
+            canSymbol.for('can.unwrap')
+        ]),
+        assignMap: function (target, source) {
+            var hasOwnKey = fastHasOwnKey(target);
+            var getKeyValue = target[getKeyValueSymbol] || shiftedGetKeyValue;
+            var setKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue;
+            this.eachKey(source, function (value, key) {
+                if (!hasOwnKey(key) || getKeyValue.call(target, key) !== value) {
+                    setKeyValue.call(target, key, value);
+                }
+            });
+            return target;
+        },
+        assignList: function (target, source) {
+            var inserting = this.toArray(source);
+            getSetReflections.splice(target, 0, inserting, inserting);
+            return target;
+        },
+        assign: function (target, source) {
+            if (typeReflections.isIteratorLike(source) || typeReflections.isMoreListLikeThanMapLike(source)) {
+                this.assignList(target, source);
+            } else {
+                this.assignMap(target, source);
+            }
+            return target;
+        },
+        assignDeepMap: function (target, source) {
+            var hasOwnKey = fastHasOwnKey(target);
+            var getKeyValue = target[getKeyValueSymbol] || shiftedGetKeyValue;
+            var setKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue;
+            this.eachKey(source, function (newVal, key) {
+                if (!hasOwnKey(key)) {
+                    getSetReflections.setKeyValue(target, key, newVal);
+                } else {
+                    var curVal = getKeyValue.call(target, key);
+                    if (newVal === curVal) {
+                    } else if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) {
+                        setKeyValue.call(target, key, newVal);
+                    } else {
+                        this.assignDeep(curVal, newVal);
+                    }
+                }
+            }, this);
+            return target;
+        },
+        assignDeepList: function (target, source) {
+            return updateDeepList.call(this, target, source, true);
+        },
+        assignDeep: function (target, source) {
+            var assignDeep = target[canSymbol.for('can.assignDeep')];
+            if (assignDeep) {
+                assignDeep.call(target, source);
+            } else if (typeReflections.isMoreListLikeThanMapLike(source)) {
+                this.assignDeepList(target, source);
+            } else {
+                this.assignDeepMap(target, source);
+            }
+            return target;
+        },
+        updateMap: function (target, source) {
+            var sourceKeyMap = makeMap(this.getOwnEnumerableKeys(source));
+            var sourceGetKeyValue = source[getKeyValueSymbol] || shiftedGetKeyValue;
+            var targetSetKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue;
+            this.eachKey(target, function (curVal, key) {
+                if (!sourceKeyMap.get(key)) {
+                    getSetReflections.deleteKeyValue(target, key);
+                    return;
+                }
+                sourceKeyMap.set(key, false);
+                var newVal = sourceGetKeyValue.call(source, key);
+                if (newVal !== curVal) {
+                    targetSetKeyValue.call(target, key, newVal);
+                }
+            }, this);
+            this.eachIndex(sourceKeyMap.keys(), function (key) {
+                if (sourceKeyMap.get(key)) {
+                    targetSetKeyValue.call(target, key, sourceGetKeyValue.call(source, key));
+                }
+            });
+            return target;
+        },
+        updateList: function (target, source) {
+            var inserting = this.toArray(source);
+            getSetReflections.splice(target, 0, target, inserting);
+            return target;
+        },
+        update: function (target, source) {
+            if (typeReflections.isIteratorLike(source) || typeReflections.isMoreListLikeThanMapLike(source)) {
+                this.updateList(target, source);
+            } else {
+                this.updateMap(target, source);
+            }
+            return target;
+        },
+        updateDeepMap: function (target, source) {
+            var sourceKeyMap = makeMap(this.getOwnEnumerableKeys(source));
+            var sourceGetKeyValue = source[getKeyValueSymbol] || shiftedGetKeyValue;
+            var targetSetKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue;
+            this.eachKey(target, function (curVal, key) {
+                if (!sourceKeyMap.get(key)) {
+                    getSetReflections.deleteKeyValue(target, key);
+                    return;
+                }
+                sourceKeyMap.set(key, false);
+                var newVal = sourceGetKeyValue.call(source, key);
+                if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) {
+                    targetSetKeyValue.call(target, key, newVal);
+                } else {
+                    this.updateDeep(curVal, newVal);
+                }
+            }, this);
+            this.eachIndex(sourceKeyMap.keys(), function (key) {
+                if (sourceKeyMap.get(key)) {
+                    targetSetKeyValue.call(target, key, sourceGetKeyValue.call(source, key));
+                }
+            });
+            return target;
+        },
+        updateDeepList: function (target, source) {
+            return updateDeepList.call(this, target, source);
+        },
+        updateDeep: function (target, source) {
+            var updateDeep = target[canSymbol.for('can.updateDeep')];
+            if (updateDeep) {
+                updateDeep.call(target, source);
+            } else if (typeReflections.isMoreListLikeThanMapLike(source)) {
+                this.updateDeepList(target, source);
+            } else {
+                this.updateDeepMap(target, source);
+            }
+            return target;
+        },
+        'in': function () {
+        },
+        getAllEnumerableKeys: function () {
+        },
+        getAllKeys: function () {
+        },
+        assignSymbols: function (target, source) {
+            this.eachKey(source, function (value, key) {
+                var symbol = typeReflections.isSymbolLike(canSymbol[key]) ? canSymbol[key] : canSymbol.for(key);
+                getSetReflections.setKeyValue(target, symbol, value);
+            });
+            return target;
+        },
+        isSerializable: isSerializable,
+        size: function (obj) {
+            var size = obj[sizeSymbol];
+            var count = 0;
+            if (size) {
+                return size.call(obj);
+            } else if (helpers.hasLength(obj)) {
+                return obj.length;
+            } else if (typeReflections.isListLike(obj)) {
+                this.each(obj, function () {
+                    count++;
+                });
+                return count;
+            } else if (obj) {
+                for (var prop in obj) {
+                    if (obj.hasOwnProperty(prop)) {
+                        count++;
+                    }
+                }
+                return count;
+            } else {
+                return undefined;
+            }
+        },
+        defineInstanceKey: function (cls, key, properties) {
+            var defineInstanceKey = cls[canSymbol.for('can.defineInstanceKey')];
+            if (defineInstanceKey) {
+                return defineInstanceKey.call(cls, key, properties);
+            }
+            var proto = cls.prototype;
+            defineInstanceKey = proto[canSymbol.for('can.defineInstanceKey')];
+            if (defineInstanceKey) {
+                defineInstanceKey.call(proto, key, properties);
+            } else {
+                Object.defineProperty(proto, key, shapeReflections.assign({
+                    configurable: true,
+                    enumerable: !typeReflections.isSymbolLike(key),
+                    writable: true
+                }, properties));
+            }
+        }
+    };
+    shapeReflections.keys = shapeReflections.getOwnEnumerableKeys;
+    module.exports = shapeReflections;
+});
+/*can-reflect@1.7.3#reflections/get-name/get-name*/
+define('can-reflect/reflections/get-name/get-name', [
+    'require',
+    'exports',
+    'module',
+    'can-symbol',
+    'can-reflect/reflections/type/type'
+], function (require, exports, module) {
+    var canSymbol = require('can-symbol');
+    var typeReflections = require('can-reflect/reflections/type/type');
+    var getNameSymbol = canSymbol.for('can.getName');
+    function setName(obj, nameGetter) {
+        if (typeof nameGetter !== 'function') {
+            var value = nameGetter;
+            nameGetter = function () {
+                return value;
+            };
+        }
+        Object.defineProperty(obj, getNameSymbol, { value: nameGetter });
+    }
+    function getName(obj) {
+        var nameGetter = obj[getNameSymbol];
+        if (nameGetter) {
+            return nameGetter.call(obj);
+        }
+        if (typeof obj === 'function') {
+            return obj.name;
+        }
+        if (obj.constructor && obj !== obj.constructor) {
+            var parent = getName(obj.constructor);
+            if (parent) {
+                if (typeReflections.isValueLike(obj)) {
+                    return parent + '<>';
+                }
+                if (typeReflections.isMoreListLikeThanMapLike(obj)) {
+                    return parent + '[]';
+                }
+                if (typeReflections.isMapLike(obj)) {
+                    return parent + '{}';
+                }
+            }
+        }
+        return undefined;
+    }
+    module.exports = {
+        setName: setName,
+        getName: getName
+    };
+});
+/*can-reflect@1.7.3#types/map*/
+define('can-reflect/types/map', [
+    'require',
+    'exports',
+    'module',
+    'can-reflect/reflections/shape/shape',
+    'can-symbol'
+], function (require, exports, module) {
+    var shape = require('can-reflect/reflections/shape/shape');
+    var CanSymbol = require('can-symbol');
+    function keysPolyfill() {
+        var keys = [];
+        var currentIndex = 0;
+        this.forEach(function (val, key) {
+            keys.push(key);
+        });
+        return {
+            next: function () {
+                return {
+                    value: keys[currentIndex],
+                    done: currentIndex++ === keys.length
+                };
+            }
+        };
+    }
+    if (typeof Map !== 'undefined') {
+        shape.assignSymbols(Map.prototype, {
+            'can.getOwnEnumerableKeys': Map.prototype.keys,
+            'can.setKeyValue': Map.prototype.set,
+            'can.getKeyValue': Map.prototype.get,
+            'can.deleteKeyValue': Map.prototype['delete'],
+            'can.hasOwnKey': Map.prototype.has
+        });
+        if (typeof Map.prototype.keys !== 'function') {
+            Map.prototype.keys = Map.prototype[CanSymbol.for('can.getOwnEnumerableKeys')] = keysPolyfill;
+        }
+    }
+    if (typeof WeakMap !== 'undefined') {
+        shape.assignSymbols(WeakMap.prototype, {
+            'can.getOwnEnumerableKeys': function () {
+                throw new Error('can-reflect: WeakMaps do not have enumerable keys.');
+            },
+            'can.setKeyValue': WeakMap.prototype.set,
+            'can.getKeyValue': WeakMap.prototype.get,
+            'can.deleteKeyValue': WeakMap.prototype['delete'],
+            'can.hasOwnKey': WeakMap.prototype.has
+        });
+    }
+});
+/*can-reflect@1.7.3#types/set*/
+define('can-reflect/types/set', [
+    'require',
+    'exports',
+    'module',
+    'can-reflect/reflections/shape/shape',
+    'can-symbol'
+], function (require, exports, module) {
+    var shape = require('can-reflect/reflections/shape/shape');
+    var CanSymbol = require('can-symbol');
+    if (typeof Set !== 'undefined') {
+        shape.assignSymbols(Set.prototype, {
+            'can.isMoreListLikeThanMapLike': true,
+            'can.updateValues': function (index, removing, adding) {
+                if (removing !== adding) {
+                    shape.each(removing, function (value) {
+                        this.delete(value);
+                    }, this);
+                }
+                shape.each(adding, function (value) {
+                    this.add(value);
+                }, this);
+            },
+            'can.size': function () {
+                return this.size;
+            }
+        });
+        if (typeof Set.prototype[CanSymbol.iterator] !== 'function') {
+            Set.prototype[CanSymbol.iterator] = function () {
+                var arr = [];
+                var currentIndex = 0;
+                this.forEach(function (val) {
+                    arr.push(val);
+                });
+                return {
+                    next: function () {
+                        return {
+                            value: arr[currentIndex],
+                            done: currentIndex++ === arr.length
+                        };
+                    }
+                };
+            };
+        }
+    }
+    if (typeof WeakSet !== 'undefined') {
+        shape.assignSymbols(WeakSet.prototype, {
+            'can.isListLike': true,
+            'can.isMoreListLikeThanMapLike': true,
+            'can.updateValues': function (index, removing, adding) {
+                if (removing !== adding) {
+                    shape.each(removing, function (value) {
+                        this.delete(value);
+                    }, this);
+                }
+                shape.each(adding, function (value) {
+                    this.add(value);
+                }, this);
+            },
+            'can.size': function () {
+                throw new Error('can-reflect: WeakSets do not have enumerable keys.');
+            }
+        });
+    }
+});
+/*can-reflect@1.7.3#can-reflect*/
+define('can-reflect', [
+    'require',
+    'exports',
+    'module',
+    'can-reflect/reflections/call/call',
+    'can-reflect/reflections/get-set/get-set',
+    'can-reflect/reflections/observe/observe',
+    'can-reflect/reflections/shape/shape',
+    'can-reflect/reflections/type/type',
+    'can-reflect/reflections/get-name/get-name',
+    'can-namespace',
+    'can-reflect/types/map',
+    'can-reflect/types/set'
+], function (require, exports, module) {
+    var functionReflections = require('can-reflect/reflections/call/call');
+    var getSet = require('can-reflect/reflections/get-set/get-set');
+    var observe = require('can-reflect/reflections/observe/observe');
+    var shape = require('can-reflect/reflections/shape/shape');
+    var type = require('can-reflect/reflections/type/type');
+    var getName = require('can-reflect/reflections/get-name/get-name');
+    var namespace = require('can-namespace');
+    var reflect = {};
+    [
+        functionReflections,
+        getSet,
+        observe,
+        shape,
+        type,
+        getName
+    ].forEach(function (reflections) {
+        for (var prop in reflections) {
+            reflect[prop] = reflections[prop];
+        }
+    });
+    require('can-reflect/types/map');
+    require('can-reflect/types/set');
+    module.exports = namespace.Reflect = reflect;
+});
+/*[global-shim-end]*/
+(function(global) { // jshint ignore:line
+	global._define = global.define;
+	global.define = global.define.orig;
+}
+)(typeof self == "object" && self.Object == Object ? self : window);
\ No newline at end of file