/**
 * Creates a property with the name of the key provided to the target
 * prototype. Whenever a binding with that name is set, the `set` method of
 * that property is called and we can hook into the internals. This way we can also
 * handle event emitters.
 */ function attachPropertyHook ( scope , target , key , name ) { const wrapper = `__${ name }Fn` ; Object . defineProperty ( target . prototype , key , { enumerable : true , configurable : true , get : function ( ) { return this [ `_${ name }` ] ; } , set : function ( value ) { if ( this [ wrapper ] === undefined ) { this [ wrapper ] = value ; return ; } if ( ! ( value && value . emit && value . subscribe ) ) { throw new TypeError ( `Expected '${ key }' to be an 'EventEmitter', got '${ typeof value }'.` ) ; } this [ `_${ name }` ] = value ; value . subscribe ( e => { scope . $apply ( ( ) => { this [ wrapper ] ( { $event : e } ) ; } ) ; } ) ; } } ) ; } export function bind ( scope , target , directive ) { const annotations = target . __annotations__ ; const component = annotations . component || annotations . directive ; ( component . outputs || [ ] ) . forEach ( key => { const mapping = key . split ( /:[ ]*/ ) ; const name = mapping [ 1 ] || mapping [ 0 ] ; attachPropertyHook ( scope , target , key , name ) ; directive . bindToController [ mapping [ 0 ] ] = `&${ name }` ; } ) ; Object . keys ( annotations . outputs || { } ) . forEach ( key => { const name = annotations . outputs [ key ] ; attachPropertyHook ( scope , target , key , name ) ; directive . bindToController [ key ] = `&${ name }` ; } ) ; }