)]}'
{"horizon/karma.conf.js":[{"author":{"_account_id":14124,"name":"Matt Borland","email":"matt.borland@hpe.com","username":"mborland"},"change_message_id":"ab9f9c77cf4dd0da53c2ec3cbc14fa19a05adc73","unresolved":false,"context_lines":[{"line_number":46,"context_line":"      // NOTE: the templates must also be listed in the files section below."},{"line_number":47,"context_line":"      \u0027./**/*.html\u0027: [\u0027ng-html2js\u0027],"},{"line_number":48,"context_line":"      // Used to indicate files requiring coverage reports."},{"line_number":49,"context_line":"      \u0027./**/!(*.spec|*.borrowed-from-underscore).js\u0027: [\u0027coverage\u0027]"},{"line_number":50,"context_line":"    },"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    // Sets up module to process templates."}],"source_content_type":"text/javascript","patch_set":14,"id":"1aa78d24_814e2a94","line":49,"range":{"start_line":49,"start_character":20,"end_line":49,"end_character":47},"updated":"2016-07-05 14:22:21.000000000","message":"Let\u0027s use this as an argument to reintroduce underscore.js into the XStatic libraries. :)\n\nThis is NOT part of my -1, just a note for ourselves.","commit_id":"ee1f4dd302a8b701cdac8270303a49602b3262a3"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"15d1f0489bd01ceb7015f0e14422994e087642a1","unresolved":false,"context_lines":[{"line_number":46,"context_line":"      // NOTE: the templates must also be listed in the files section below."},{"line_number":47,"context_line":"      \u0027./**/*.html\u0027: [\u0027ng-html2js\u0027],"},{"line_number":48,"context_line":"      // Used to indicate files requiring coverage reports."},{"line_number":49,"context_line":"      \u0027./**/!(*.spec|*.borrowed-from-underscore).js\u0027: [\u0027coverage\u0027]"},{"line_number":50,"context_line":"    },"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    // Sets up module to process templates."}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_b62478af","line":49,"updated":"2016-07-08 21:02:01.000000000","message":"Im not a big fan of adding exceptions to the list. This encourages people to break the spec pattern. Which leads me to my next though.\n\nIf we are \"borrowing\" a few functions here and there, might as well import the entire library. I think underscoreJS is useful enough to warrant its own xstatic package.","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"4e5d14b805ee95f9b16b522f65e11a320b4e582a","unresolved":false,"context_lines":[{"line_number":46,"context_line":"      // NOTE: the templates must also be listed in the files section below."},{"line_number":47,"context_line":"      \u0027./**/*.html\u0027: [\u0027ng-html2js\u0027],"},{"line_number":48,"context_line":"      // Used to indicate files requiring coverage reports."},{"line_number":49,"context_line":"      \u0027./**/!(*.spec|*.borrowed-from-underscore).js\u0027: [\u0027coverage\u0027]"},{"line_number":50,"context_line":"    },"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    // Sets up module to process templates."}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_f43d532d","line":49,"in_reply_to":"1aa78d24_b62478af","updated":"2016-07-14 18:54:48.000000000","message":"The conclusion from the Newton midcycle is that underscore/lodash packaging won\u0027t happen earlier than O. So I suggest to leave this as is for now and remove once we have underscore packaged.","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"}],"horizon/static/framework/util/filters/helpers.borrowed-from-underscore.js":[{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"15d1f0489bd01ceb7015f0e14422994e087642a1","unresolved":false,"context_lines":[{"line_number":15,"context_line":" */"},{"line_number":16,"context_line":"(function () {"},{"line_number":17,"context_line":"  \u0027use strict\u0027;"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"  angular"},{"line_number":20,"context_line":"    .module(\u0027horizon.framework.util.filters\u0027)"},{"line_number":21,"context_line":"    .factory(\u0027horizon.framework.util.filters.$memoize\u0027, $memoize);"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_59862066","line":18,"updated":"2016-07-08 21:02:01.000000000","message":"brief description of what memoize does will be good. copy/paste description from http://underscorejs.org/#memoize is ok too.","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"4e5d14b805ee95f9b16b522f65e11a320b4e582a","unresolved":false,"context_lines":[{"line_number":15,"context_line":" */"},{"line_number":16,"context_line":"(function () {"},{"line_number":17,"context_line":"  \u0027use strict\u0027;"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"  angular"},{"line_number":20,"context_line":"    .module(\u0027horizon.framework.util.filters\u0027)"},{"line_number":21,"context_line":"    .factory(\u0027horizon.framework.util.filters.$memoize\u0027, $memoize);"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_b4cf4b28","line":18,"in_reply_to":"1aa78d24_59862066","updated":"2016-07-14 18:54:48.000000000","message":"Done","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":20,"context_line":"    .module(\u0027horizon.framework.util.filters\u0027)"},{"line_number":21,"context_line":"    .factory(\u0027horizon.framework.util.filters.$memoize\u0027, $memoize);"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"  /* Memoizes a given function by caching the computed result. Useful for"},{"line_number":24,"context_line":"  speeding up slow-running computations. If passed an optional hashFunction, it"},{"line_number":25,"context_line":"  will be used to compute the hash key for storing the result, based on the"},{"line_number":26,"context_line":"  arguments to the original function. The default hashFunction just uses the"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_faba1e22","line":23,"updated":"2016-07-20 00:04:53.000000000","message":"this should \"loosely\" follow the ngdoc format","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":20,"context_line":"    .module(\u0027horizon.framework.util.filters\u0027)"},{"line_number":21,"context_line":"    .factory(\u0027horizon.framework.util.filters.$memoize\u0027, $memoize);"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"  /* Memoizes a given function by caching the computed result. Useful for"},{"line_number":24,"context_line":"  speeding up slow-running computations. If passed an optional hashFunction, it"},{"line_number":25,"context_line":"  will be used to compute the hash key for storing the result, based on the"},{"line_number":26,"context_line":"  arguments to the original function. The default hashFunction just uses the"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_1d2d31fe","line":23,"in_reply_to":"dada55a8_faba1e22","updated":"2016-07-20 23:46:45.000000000","message":"Done","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    return function(func, hasher) {"},{"line_number":32,"context_line":"      var memoize \u003d function(key) {"},{"line_number":33,"context_line":"        var cache \u003d memoize.cache;"},{"line_number":34,"context_line":"        var address \u003d \u0027\u0027 + (hasher ? hasher.apply(this, arguments) : key);"},{"line_number":35,"context_line":"        if (!cache.hasOwnProperty(address)) {"},{"line_number":36,"context_line":"          cache[address] \u003d func.apply(this, arguments);"},{"line_number":37,"context_line":"        }"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_fa917e9a","line":34,"updated":"2016-07-20 00:04:53.000000000","message":"where is arguments defined? am i missing something here?","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    return function(func, hasher) {"},{"line_number":32,"context_line":"      var memoize \u003d function(key) {"},{"line_number":33,"context_line":"        var cache \u003d memoize.cache;"},{"line_number":34,"context_line":"        var address \u003d \u0027\u0027 + (hasher ? hasher.apply(this, arguments) : key);"},{"line_number":35,"context_line":"        if (!cache.hasOwnProperty(address)) {"},{"line_number":36,"context_line":"          cache[address] \u003d func.apply(this, arguments);"},{"line_number":37,"context_line":"        }"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_3f8adf1b","line":34,"in_reply_to":"dada55a8_fa917e9a","updated":"2016-07-20 23:46:45.000000000","message":"a JS keyword here.","commit_id":"86ba12e416851b4512634762792112dcee696788"}],"horizon/static/framework/widgets/table/hz-cell.directive.js":[{"author":{"_account_id":14124,"name":"Matt Borland","email":"matt.borland@hpe.com","username":"mborland"},"change_message_id":"580037589c36fc47ab7df3ce7a2edc933e3226ed","unresolved":false,"context_lines":[{"line_number":101,"context_line":"            // call horizon framework filter function if provided"},{"line_number":102,"context_line":"            if (angular.isFunction(filter)) {"},{"line_number":103,"context_line":"              html \u003d filter(item[column.id]);"},{"line_number":104,"context_line":"              // call angular filters"},{"line_number":105,"context_line":"            } else {"},{"line_number":106,"context_line":"              html \u003d $filter(filter)(item[column.id]);"},{"line_number":107,"context_line":"            }"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_dce8f2e4","line":104,"range":{"start_line":104,"start_character":12,"end_line":104,"end_character":37},"updated":"2016-06-29 15:18:04.000000000","message":"This shouldn\u0027t be indented, but moved into the \u0027else\u0027 clause.","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"a52b58068042cdcf11adf2a11136e94229d303f1","unresolved":false,"context_lines":[{"line_number":101,"context_line":"            // call horizon framework filter function if provided"},{"line_number":102,"context_line":"            if (angular.isFunction(filter)) {"},{"line_number":103,"context_line":"              html \u003d filter(item[column.id]);"},{"line_number":104,"context_line":"              // call angular filters"},{"line_number":105,"context_line":"            } else {"},{"line_number":106,"context_line":"              html \u003d $filter(filter)(item[column.id]);"},{"line_number":107,"context_line":"            }"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_375028d4","line":104,"range":{"start_line":104,"start_character":12,"end_line":104,"end_character":37},"in_reply_to":"3aaa91ec_dce8f2e4","updated":"2016-06-29 17:10:44.000000000","message":"Done","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"}],"horizon/static/framework/widgets/transfer-table/extend-object.filter.js":[{"author":{"_account_id":14124,"name":"Matt Borland","email":"matt.borland@hpe.com","username":"mborland"},"change_message_id":"ab9f9c77cf4dd0da53c2ec3cbc14fa19a05adc73","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    .module(\u0027horizon.framework.widgets.transfer-table\u0027)"},{"line_number":22,"context_line":"    .filter(\u0027extendObj\u0027, extendObj);"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"  extendObj.$inject \u003d [\u0027horizon.framework.util.filters.$memoize\u0027];"},{"line_number":25,"context_line":"  function extendObj($memoize) {"},{"line_number":26,"context_line":"    return $memoize($extendObj, $hasher);"},{"line_number":27,"context_line":""}],"source_content_type":"text/javascript","patch_set":14,"id":"1aa78d24_61085e2d","line":24,"updated":"2016-07-05 14:22:21.000000000","message":"Can we have some documentation about what this filter is supposed to do?","commit_id":"ee1f4dd302a8b701cdac8270303a49602b3262a3"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"c08d6280b623875c9bec187821bca896ea040e53","unresolved":false,"context_lines":[{"line_number":21,"context_line":"    .module(\u0027horizon.framework.widgets.transfer-table\u0027)"},{"line_number":22,"context_line":"    .filter(\u0027extendObj\u0027, extendObj);"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"  extendObj.$inject \u003d [\u0027horizon.framework.util.filters.$memoize\u0027];"},{"line_number":25,"context_line":"  function extendObj($memoize) {"},{"line_number":26,"context_line":"    return $memoize($extendObj, $hasher);"},{"line_number":27,"context_line":""}],"source_content_type":"text/javascript","patch_set":14,"id":"1aa78d24_13aa8b70","line":24,"in_reply_to":"1aa78d24_61085e2d","updated":"2016-07-05 14:58:21.000000000","message":"Done","commit_id":"ee1f4dd302a8b701cdac8270303a49602b3262a3"},{"author":{"_account_id":14124,"name":"Matt Borland","email":"matt.borland@hpe.com","username":"mborland"},"change_message_id":"ab9f9c77cf4dd0da53c2ec3cbc14fa19a05adc73","unresolved":false,"context_lines":[{"line_number":28,"context_line":"    function $hasher(obj, extension, bypass) {"},{"line_number":29,"context_line":"      function hashObject(o) {"},{"line_number":30,"context_line":"        var keys \u003d Object.keys(o).sort();"},{"line_number":31,"context_line":"        return keys.map(function(key) {"},{"line_number":32,"context_line":"          return key + \u0027_\u0027 + o[key];"},{"line_number":33,"context_line":"        });"},{"line_number":34,"context_line":"      }"}],"source_content_type":"text/javascript","patch_set":14,"id":"1aa78d24_bc0d4939","line":31,"range":{"start_line":31,"start_character":24,"end_line":31,"end_character":32},"updated":"2016-07-05 14:22:21.000000000","message":"name the function for better debugging","commit_id":"ee1f4dd302a8b701cdac8270303a49602b3262a3"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"c08d6280b623875c9bec187821bca896ea040e53","unresolved":false,"context_lines":[{"line_number":28,"context_line":"    function $hasher(obj, extension, bypass) {"},{"line_number":29,"context_line":"      function hashObject(o) {"},{"line_number":30,"context_line":"        var keys \u003d Object.keys(o).sort();"},{"line_number":31,"context_line":"        return keys.map(function(key) {"},{"line_number":32,"context_line":"          return key + \u0027_\u0027 + o[key];"},{"line_number":33,"context_line":"        });"},{"line_number":34,"context_line":"      }"}],"source_content_type":"text/javascript","patch_set":14,"id":"1aa78d24_fc2191b5","line":31,"range":{"start_line":31,"start_character":24,"end_line":31,"end_character":32},"in_reply_to":"1aa78d24_bc0d4939","updated":"2016-07-05 14:58:21.000000000","message":"Done","commit_id":"ee1f4dd302a8b701cdac8270303a49602b3262a3"}],"horizon/static/framework/widgets/transfer-table/filter-available.js":[{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"15d1f0489bd01ceb7015f0e14422994e087642a1","unresolved":false,"context_lines":[{"line_number":27,"context_line":"   * @description"},{"line_number":28,"context_line":"   * Sifts a list of objects (first argument) removing from the resulting output"},{"line_number":29,"context_line":"   * objects which ids are present in a dictionary passed as a second argument"},{"line_number":30,"context_line":"   * to the filter."},{"line_number":31,"context_line":"   * By default an object id is the object[\u0027id\u0027] value, but the default key name"},{"line_number":32,"context_line":"   * can be overridden with the third argument."},{"line_number":33,"context_line":"   * The filter works nicely when used inside ng-repeat directive and does not"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_76d4d046","line":30,"updated":"2016-07-08 21:02:01.000000000","message":"Recommended. Consider rewording to something like:\n\"Returns a filtered list of objects given a list and a dictionary. The filtered list contain objects whose ids are present in the dictionary.\"","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"4e5d14b805ee95f9b16b522f65e11a320b4e582a","unresolved":false,"context_lines":[{"line_number":27,"context_line":"   * @description"},{"line_number":28,"context_line":"   * Sifts a list of objects (first argument) removing from the resulting output"},{"line_number":29,"context_line":"   * objects which ids are present in a dictionary passed as a second argument"},{"line_number":30,"context_line":"   * to the filter."},{"line_number":31,"context_line":"   * By default an object id is the object[\u0027id\u0027] value, but the default key name"},{"line_number":32,"context_line":"   * can be overridden with the third argument."},{"line_number":33,"context_line":"   * The filter works nicely when used inside ng-repeat directive and does not"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_6fceaeb8","line":30,"in_reply_to":"1aa78d24_76d4d046","updated":"2016-07-14 18:54:48.000000000","message":"Done","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"15d1f0489bd01ceb7015f0e14422994e087642a1","unresolved":false,"context_lines":[{"line_number":29,"context_line":"   * objects which ids are present in a dictionary passed as a second argument"},{"line_number":30,"context_line":"   * to the filter."},{"line_number":31,"context_line":"   * By default an object id is the object[\u0027id\u0027] value, but the default key name"},{"line_number":32,"context_line":"   * can be overridden with the third argument."},{"line_number":33,"context_line":"   * The filter works nicely when used inside ng-repeat directive and does not"},{"line_number":34,"context_line":"   * lead to an infinite digest loop error, thanks to memoizing its results on"},{"line_number":35,"context_line":"   * both the initial list, keys dictionary and key name."}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_992a482b","line":32,"updated":"2016-07-08 21:02:01.000000000","message":"This paragraph makes no sense to me. how is the object id and default key related? are they the same thing? I think an example of how to use it would be helpful.","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"4e5d14b805ee95f9b16b522f65e11a320b4e582a","unresolved":false,"context_lines":[{"line_number":29,"context_line":"   * objects which ids are present in a dictionary passed as a second argument"},{"line_number":30,"context_line":"   * to the filter."},{"line_number":31,"context_line":"   * By default an object id is the object[\u0027id\u0027] value, but the default key name"},{"line_number":32,"context_line":"   * can be overridden with the third argument."},{"line_number":33,"context_line":"   * The filter works nicely when used inside ng-repeat directive and does not"},{"line_number":34,"context_line":"   * lead to an infinite digest loop error, thanks to memoizing its results on"},{"line_number":35,"context_line":"   * both the initial list, keys dictionary and key name."}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_efdbbe7b","line":32,"in_reply_to":"1aa78d24_992a482b","updated":"2016-07-14 18:54:48.000000000","message":"Changed id to key in above description. Does it make more sense now?","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"15d1f0489bd01ceb7015f0e14422994e087642a1","unresolved":false,"context_lines":[{"line_number":33,"context_line":"   * The filter works nicely when used inside ng-repeat directive and does not"},{"line_number":34,"context_line":"   * lead to an infinite digest loop error, thanks to memoizing its results on"},{"line_number":35,"context_line":"   * both the initial list, keys dictionary and key name."},{"line_number":36,"context_line":"   * Since the filter cache is shared between filter invocations in different"},{"line_number":37,"context_line":"   * contexts, one must ensure that different entities ids (or whatever attribute"},{"line_number":38,"context_line":"   * is used as an id in the filter) are different. Otherwise, if there are, e.g."},{"line_number":39,"context_line":"   * two security groups with ids \u0027test1\u0027 and \u0027test2\u0027 and two key pairs with"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_199c9868","line":36,"updated":"2016-07-08 21:02:01.000000000","message":"Optional. Very verbose paragraph explaining that you should namespace your ids. Consider condensing.","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"4e5d14b805ee95f9b16b522f65e11a320b4e582a","unresolved":false,"context_lines":[{"line_number":33,"context_line":"   * The filter works nicely when used inside ng-repeat directive and does not"},{"line_number":34,"context_line":"   * lead to an infinite digest loop error, thanks to memoizing its results on"},{"line_number":35,"context_line":"   * both the initial list, keys dictionary and key name."},{"line_number":36,"context_line":"   * Since the filter cache is shared between filter invocations in different"},{"line_number":37,"context_line":"   * contexts, one must ensure that different entities ids (or whatever attribute"},{"line_number":38,"context_line":"   * is used as an id in the filter) are different. Otherwise, if there are, e.g."},{"line_number":39,"context_line":"   * two security groups with ids \u0027test1\u0027 and \u0027test2\u0027 and two key pairs with"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_cf91a29c","line":36,"in_reply_to":"1aa78d24_199c9868","updated":"2016-07-14 18:54:48.000000000","message":"I made it a bit shorter, is it okay now?","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"15d1f0489bd01ceb7015f0e14422994e087642a1","unresolved":false,"context_lines":[{"line_number":45,"context_line":"   */"},{"line_number":46,"context_line":"  filterAvailable.$inject \u003d [\u0027horizon.framework.util.filters.$memoize\u0027];"},{"line_number":47,"context_line":"  function filterAvailable($memoize) {"},{"line_number":48,"context_line":"    /* Any Angular filter that returns mutable data should be memoized, because"},{"line_number":49,"context_line":"    otherwise we\u0027ll get the \u0027[$rootScope:infdig] 10 $digest() iterations reached\u0027"},{"line_number":50,"context_line":"    error, see http://stackoverflow.com/a/24213626/4414610"},{"line_number":51,"context_line":"     */"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_59e100d0","line":48,"updated":"2016-07-08 21:02:01.000000000","message":"I think this belongs in the doc section above.","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"4e5d14b805ee95f9b16b522f65e11a320b4e582a","unresolved":false,"context_lines":[{"line_number":45,"context_line":"   */"},{"line_number":46,"context_line":"  filterAvailable.$inject \u003d [\u0027horizon.framework.util.filters.$memoize\u0027];"},{"line_number":47,"context_line":"  function filterAvailable($memoize) {"},{"line_number":48,"context_line":"    /* Any Angular filter that returns mutable data should be memoized, because"},{"line_number":49,"context_line":"    otherwise we\u0027ll get the \u0027[$rootScope:infdig] 10 $digest() iterations reached\u0027"},{"line_number":50,"context_line":"    error, see http://stackoverflow.com/a/24213626/4414610"},{"line_number":51,"context_line":"     */"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_af07f616","line":48,"in_reply_to":"1aa78d24_59e100d0","updated":"2016-07-14 18:54:48.000000000","message":"Done","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":20,"id":"dada55a8_a469ad27","updated":"2016-07-20 00:04:53.000000000","message":"Generally speaking, the file naming scheme is \"\u003cname\u003e.\u003ctype\u003e.js\". In this case it should be available.filter.js.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":20,"id":"dada55a8_5d6b29f1","in_reply_to":"dada55a8_a469ad27","updated":"2016-07-20 23:46:45.000000000","message":"In that case it would be filterAvailable.filter.js, that is why I decided that 2nd \u0027filter\u0027 would be redundant.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":"  /**"},{"line_number":25,"context_line":"   * @ngdoc filter"},{"line_number":26,"context_line":"   * @name filterAvailable"},{"line_number":27,"context_line":"   * @description"},{"line_number":28,"context_line":"   * Returns a filtered list of objects given a list and a dictionary. The"},{"line_number":29,"context_line":"   * filtered list contains objects which keys are NOT present in the dictionary."}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_24677d26","line":26,"updated":"2016-07-20 00:04:53.000000000","message":"Inserting the following will help with reading the doc a bit more.\n\n@param list - list of objects with ids\n@param dictionary - hash of object ids\n@param primaryKey (Optional) - string to use as primary key, defaults to id\n@returns filter list of objects whose keys are NOT present in the dictionary.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":"  /**"},{"line_number":25,"context_line":"   * @ngdoc filter"},{"line_number":26,"context_line":"   * @name filterAvailable"},{"line_number":27,"context_line":"   * @description"},{"line_number":28,"context_line":"   * Returns a filtered list of objects given a list and a dictionary. The"},{"line_number":29,"context_line":"   * filtered list contains objects which keys are NOT present in the dictionary."}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_9d0e4139","line":26,"in_reply_to":"dada55a8_24677d26","updated":"2016-07-20 23:46:45.000000000","message":"Done","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":25,"context_line":"   * @ngdoc filter"},{"line_number":26,"context_line":"   * @name filterAvailable"},{"line_number":27,"context_line":"   * @description"},{"line_number":28,"context_line":"   * Returns a filtered list of objects given a list and a dictionary. The"},{"line_number":29,"context_line":"   * filtered list contains objects which keys are NOT present in the dictionary."},{"line_number":30,"context_line":"   * By default an object key is the object[\u0027id\u0027], but the key attribute name"},{"line_number":31,"context_line":"   * can be overridden with the third argument."},{"line_number":32,"context_line":"   * The filter works nicely when used inside ng-repeat directive and does not"},{"line_number":33,"context_line":"   * lead to an infinite digest loop error, thanks to memoizing its results on"},{"line_number":34,"context_line":"   * both the initial list, keys dictionary and key name. For more details see"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_67397741","line":31,"range":{"start_line":28,"start_character":5,"end_line":31,"end_character":47},"updated":"2016-07-20 00:04:53.000000000","message":"can remove the highlighted lines since we already described in the @param section.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":25,"context_line":"   * @ngdoc filter"},{"line_number":26,"context_line":"   * @name filterAvailable"},{"line_number":27,"context_line":"   * @description"},{"line_number":28,"context_line":"   * Returns a filtered list of objects given a list and a dictionary. The"},{"line_number":29,"context_line":"   * filtered list contains objects which keys are NOT present in the dictionary."},{"line_number":30,"context_line":"   * By default an object key is the object[\u0027id\u0027], but the key attribute name"},{"line_number":31,"context_line":"   * can be overridden with the third argument."},{"line_number":32,"context_line":"   * The filter works nicely when used inside ng-repeat directive and does not"},{"line_number":33,"context_line":"   * lead to an infinite digest loop error, thanks to memoizing its results on"},{"line_number":34,"context_line":"   * both the initial list, keys dictionary and key name. For more details see"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_7d0b8d2a","line":31,"range":{"start_line":28,"start_character":5,"end_line":31,"end_character":47},"in_reply_to":"dada55a8_67397741","updated":"2016-07-20 23:46:45.000000000","message":"Done","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":32,"context_line":"   * The filter works nicely when used inside ng-repeat directive and does not"},{"line_number":33,"context_line":"   * lead to an infinite digest loop error, thanks to memoizing its results on"},{"line_number":34,"context_line":"   * both the initial list, keys dictionary and key name. For more details see"},{"line_number":35,"context_line":"   * http://stackoverflow.com/a/24213626/4414610"},{"line_number":36,"context_line":"   * Since the filter cache is shared between filter invocations in different"},{"line_number":37,"context_line":"   * contexts, one must namespace entities key values. Consider the following"},{"line_number":38,"context_line":"   * example: there are, two security groups with keys \u0027test1\u0027 and \u0027test2\u0027 and"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_4419d187","line":35,"updated":"2016-07-20 00:04:53.000000000","message":"Optional. new paragraph should start with new line so its easier to read.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":32,"context_line":"   * The filter works nicely when used inside ng-repeat directive and does not"},{"line_number":33,"context_line":"   * lead to an infinite digest loop error, thanks to memoizing its results on"},{"line_number":34,"context_line":"   * both the initial list, keys dictionary and key name. For more details see"},{"line_number":35,"context_line":"   * http://stackoverflow.com/a/24213626/4414610"},{"line_number":36,"context_line":"   * Since the filter cache is shared between filter invocations in different"},{"line_number":37,"context_line":"   * contexts, one must namespace entities key values. Consider the following"},{"line_number":38,"context_line":"   * example: there are, two security groups with keys \u0027test1\u0027 and \u0027test2\u0027 and"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_3d159548","line":35,"in_reply_to":"dada55a8_4419d187","updated":"2016-07-20 23:46:45.000000000","message":"Done","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":40,"context_line":"   * the same. Consequently we will get key pairs in a filter output while"},{"line_number":41,"context_line":"   * expecting security groups, or vice versa. To avoid subtle bugs like that"},{"line_number":42,"context_line":"   * entity keys must be namespaced; a good id of a key pair from Launch Instance"},{"line_number":43,"context_line":"   * wizard transfer table would be \u0027li_keypair:\u003ckeypair_name\u003e\u0027."},{"line_number":44,"context_line":"   */"},{"line_number":45,"context_line":"  filterAvailable.$inject \u003d [\u0027horizon.framework.util.filters.$memoize\u0027];"},{"line_number":46,"context_line":"  function filterAvailable($memoize) {"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_843c69e3","line":43,"updated":"2016-07-20 00:04:53.000000000","message":"Having an @example section showing use of 2 arguments in the filter and how providing a 3rd argument overrides the key attribute.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":40,"context_line":"   * the same. Consequently we will get key pairs in a filter output while"},{"line_number":41,"context_line":"   * expecting security groups, or vice versa. To avoid subtle bugs like that"},{"line_number":42,"context_line":"   * entity keys must be namespaced; a good id of a key pair from Launch Instance"},{"line_number":43,"context_line":"   * wizard transfer table would be \u0027li_keypair:\u003ckeypair_name\u003e\u0027."},{"line_number":44,"context_line":"   */"},{"line_number":45,"context_line":"  filterAvailable.$inject \u003d [\u0027horizon.framework.util.filters.$memoize\u0027];"},{"line_number":46,"context_line":"  function filterAvailable($memoize) {"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_b8c35356","line":43,"in_reply_to":"dada55a8_843c69e3","updated":"2016-07-20 23:46:45.000000000","message":"Done","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":42,"context_line":"   * entity keys must be namespaced; a good id of a key pair from Launch Instance"},{"line_number":43,"context_line":"   * wizard transfer table would be \u0027li_keypair:\u003ckeypair_name\u003e\u0027."},{"line_number":44,"context_line":"   */"},{"line_number":45,"context_line":"  filterAvailable.$inject \u003d [\u0027horizon.framework.util.filters.$memoize\u0027];"},{"line_number":46,"context_line":"  function filterAvailable($memoize) {"},{"line_number":47,"context_line":"    return $memoize($filterAvailable, $hasher);"},{"line_number":48,"context_line":""}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_87a62b0e","line":45,"range":{"start_line":45,"start_character":2,"end_line":45,"end_character":72},"updated":"2016-07-20 00:04:53.000000000","message":"move this line above the ngdoc section.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":42,"context_line":"   * entity keys must be namespaced; a good id of a key pair from Launch Instance"},{"line_number":43,"context_line":"   * wizard transfer table would be \u0027li_keypair:\u003ckeypair_name\u003e\u0027."},{"line_number":44,"context_line":"   */"},{"line_number":45,"context_line":"  filterAvailable.$inject \u003d [\u0027horizon.framework.util.filters.$memoize\u0027];"},{"line_number":46,"context_line":"  function filterAvailable($memoize) {"},{"line_number":47,"context_line":"    return $memoize($filterAvailable, $hasher);"},{"line_number":48,"context_line":""}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_5d104959","line":45,"range":{"start_line":45,"start_character":2,"end_line":45,"end_character":72},"in_reply_to":"dada55a8_87a62b0e","updated":"2016-07-20 23:46:45.000000000","message":"Done","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":46,"context_line":"  function filterAvailable($memoize) {"},{"line_number":47,"context_line":"    return $memoize($filterAvailable, $hasher);"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    function $idKeyOrDefault(idKey) {"},{"line_number":50,"context_line":"      return idKey || \u0027id\u0027;"},{"line_number":51,"context_line":"    }"},{"line_number":52,"context_line":""}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_07c6bb47","line":49,"range":{"start_line":49,"start_character":29,"end_line":49,"end_character":34},"updated":"2016-07-20 00:04:53.000000000","message":"idKey actually means which property do you want to make the primary key. By naming it idKey, you are already implying that id is the key. It is true that we are defaulting to id as the primaryKey if none is specified. Renaming \"idKey\" -\u003e \"primaryKey\" will alleviate this confusion.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":46,"context_line":"  function filterAvailable($memoize) {"},{"line_number":47,"context_line":"    return $memoize($filterAvailable, $hasher);"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    function $idKeyOrDefault(idKey) {"},{"line_number":50,"context_line":"      return idKey || \u0027id\u0027;"},{"line_number":51,"context_line":"    }"},{"line_number":52,"context_line":""}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_d83287f1","line":49,"range":{"start_line":49,"start_character":29,"end_line":49,"end_character":34},"in_reply_to":"dada55a8_07c6bb47","updated":"2016-07-20 23:46:45.000000000","message":"Done","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    function $idKeyOrDefault(idKey) {"},{"line_number":50,"context_line":"      return idKey || \u0027id\u0027;"},{"line_number":51,"context_line":"    }"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    function emptyArray(array) {"},{"line_number":54,"context_line":"      return angular.isUndefined(array) || !array.length;"},{"line_number":55,"context_line":"    }"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_e7f8c74b","line":52,"updated":"2016-07-20 00:04:53.000000000","message":"emptyArray and emptyObj belongs in the utility module. Right now it is only used here, but if we use it elsewhere, we should consider moving it to the utility module then.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    function $idKeyOrDefault(idKey) {"},{"line_number":50,"context_line":"      return idKey || \u0027id\u0027;"},{"line_number":51,"context_line":"    }"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    function emptyArray(array) {"},{"line_number":54,"context_line":"      return angular.isUndefined(array) || !array.length;"},{"line_number":55,"context_line":"    }"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_f8f4ab5b","line":52,"in_reply_to":"dada55a8_e7f8c74b","updated":"2016-07-20 23:46:45.000000000","message":"Let\u0027s keep them here, until we really need them elsewhere, YAGNI.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":50,"context_line":"      return idKey || \u0027id\u0027;"},{"line_number":51,"context_line":"    }"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    function emptyArray(array) {"},{"line_number":54,"context_line":"      return angular.isUndefined(array) || !array.length;"},{"line_number":55,"context_line":"    }"},{"line_number":56,"context_line":""}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_e773a713","line":53,"range":{"start_line":53,"start_character":13,"end_line":53,"end_character":23},"updated":"2016-07-20 00:04:53.000000000","message":"Optional. consider renaming to arrayIsEmpty","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":50,"context_line":"      return idKey || \u0027id\u0027;"},{"line_number":51,"context_line":"    }"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    function emptyArray(array) {"},{"line_number":54,"context_line":"      return angular.isUndefined(array) || !array.length;"},{"line_number":55,"context_line":"    }"},{"line_number":56,"context_line":""}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_58e697b0","line":53,"range":{"start_line":53,"start_character":13,"end_line":53,"end_character":23},"in_reply_to":"dada55a8_e773a713","updated":"2016-07-20 23:46:45.000000000","message":"Done","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    }"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    function emptyArray(array) {"},{"line_number":54,"context_line":"      return angular.isUndefined(array) || !array.length;"},{"line_number":55,"context_line":"    }"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    function emptyObj(obj) {"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_e7ff27a8","line":54,"range":{"start_line":54,"start_character":13,"end_line":54,"end_character":32},"updated":"2016-07-20 00:04:53.000000000","message":"Use Array.isArray or angular.isArray instead","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    }"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    function emptyArray(array) {"},{"line_number":54,"context_line":"      return angular.isUndefined(array) || !array.length;"},{"line_number":55,"context_line":"    }"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    function emptyObj(obj) {"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_b85d1317","line":54,"range":{"start_line":54,"start_character":13,"end_line":54,"end_character":32},"in_reply_to":"dada55a8_e7ff27a8","updated":"2016-07-20 23:46:45.000000000","message":"The point here is to test if the `array` is `undefined`, not if the `array` is anything different from an array type. E.g., if it\u0027s a string, then there is not intent to return `false` for it.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":54,"context_line":"      return angular.isUndefined(array) || !array.length;"},{"line_number":55,"context_line":"    }"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    function emptyObj(obj) {"},{"line_number":58,"context_line":"      return angular.isUndefined(obj) || !Object.keys(obj).length;"},{"line_number":59,"context_line":"    }"},{"line_number":60,"context_line":""}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_67a33750","line":57,"range":{"start_line":57,"start_character":13,"end_line":57,"end_character":21},"updated":"2016-07-20 00:04:53.000000000","message":"Optional. consider renaming to objectIsEmpty","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":54,"context_line":"      return angular.isUndefined(array) || !array.length;"},{"line_number":55,"context_line":"    }"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    function emptyObj(obj) {"},{"line_number":58,"context_line":"      return angular.isUndefined(obj) || !Object.keys(obj).length;"},{"line_number":59,"context_line":"    }"},{"line_number":60,"context_line":""}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_f8530b15","line":57,"range":{"start_line":57,"start_character":13,"end_line":57,"end_character":21},"in_reply_to":"dada55a8_67a33750","updated":"2016-07-20 23:46:45.000000000","message":"Done","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    }"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    function emptyObj(obj) {"},{"line_number":58,"context_line":"      return angular.isUndefined(obj) || !Object.keys(obj).length;"},{"line_number":59,"context_line":"    }"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    function $hasher(available, allocatedIds, idKey) {"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_071cfb10","line":58,"range":{"start_line":58,"start_character":13,"end_line":58,"end_character":32},"updated":"2016-07-20 00:04:53.000000000","message":"Use angular.isObject instead","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    }"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    function emptyObj(obj) {"},{"line_number":58,"context_line":"      return angular.isUndefined(obj) || !Object.keys(obj).length;"},{"line_number":59,"context_line":"    }"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    function $hasher(available, allocatedIds, idKey) {"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_98b12f4a","line":58,"range":{"start_line":58,"start_character":13,"end_line":58,"end_character":32},"in_reply_to":"dada55a8_071cfb10","updated":"2016-07-20 23:46:45.000000000","message":"The same idea as for array here.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":58,"context_line":"      return angular.isUndefined(obj) || !Object.keys(obj).length;"},{"line_number":59,"context_line":"    }"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    function $hasher(available, allocatedIds, idKey) {"},{"line_number":62,"context_line":"      if (emptyArray(available)) {"},{"line_number":63,"context_line":"        return \u0027\u0027;"},{"line_number":64,"context_line":"      }"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_27e13fd1","line":61,"range":{"start_line":61,"start_character":46,"end_line":61,"end_character":51},"updated":"2016-07-20 00:04:53.000000000","message":"idKey -\u003e primaryKey","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":58,"context_line":"      return angular.isUndefined(obj) || !Object.keys(obj).length;"},{"line_number":59,"context_line":"    }"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    function $hasher(available, allocatedIds, idKey) {"},{"line_number":62,"context_line":"      if (emptyArray(available)) {"},{"line_number":63,"context_line":"        return \u0027\u0027;"},{"line_number":64,"context_line":"      }"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_58f17700","line":61,"range":{"start_line":61,"start_character":46,"end_line":61,"end_character":51},"in_reply_to":"dada55a8_27e13fd1","updated":"2016-07-20 23:46:45.000000000","message":"Done","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":66,"context_line":"      var key \u003d available.map(function(item) {"},{"line_number":67,"context_line":"        return item[idKey];"},{"line_number":68,"context_line":"      }).join(\u0027_\u0027);"},{"line_number":69,"context_line":"      return key + \u0027_\u0027 + Object.keys(allocatedIds).sort().join(\u0027_\u0027);"},{"line_number":70,"context_line":"    }"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    function $filterAvailable(available, allocatedIds, idKey) {"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_ba142644","line":69,"updated":"2016-07-20 00:04:53.000000000","message":"This kind of hashing concerns me a bit. We are appending the id of available items to the id of allocated items, and using that as the key. If anyone one of those id are out of order, we are creating a new entry in the cache. example:\n\n1_2_3 \u003d [1,2,3]\n1_3_2 \u003d [1,3,2]\n\nWhat happens when I allocate/deallocate items? Do we create new entries in the cache when this happens,, or does this only happen once at load time? I\u0027ll have to test this out locally.\n\nI have already mentioned this some time ago regarding policy caching (which works similarly). We should be cache at a much more atomic level to avoid possible duplicates.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":66,"context_line":"      var key \u003d available.map(function(item) {"},{"line_number":67,"context_line":"        return item[idKey];"},{"line_number":68,"context_line":"      }).join(\u0027_\u0027);"},{"line_number":69,"context_line":"      return key + \u0027_\u0027 + Object.keys(allocatedIds).sort().join(\u0027_\u0027);"},{"line_number":70,"context_line":"    }"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    function $filterAvailable(available, allocatedIds, idKey) {"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_38cda3b7","line":69,"in_reply_to":"dada55a8_ba142644","updated":"2016-07-20 23:46:45.000000000","message":"Nice catch!\n\nAdded .sort() to extracted `available` keys before they are merged to solve possible duplicate issue.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":69,"context_line":"      return key + \u0027_\u0027 + Object.keys(allocatedIds).sort().join(\u0027_\u0027);"},{"line_number":70,"context_line":"    }"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    function $filterAvailable(available, allocatedIds, idKey) {"},{"line_number":73,"context_line":"      if (emptyArray(available)) {"},{"line_number":74,"context_line":"        return [];"},{"line_number":75,"context_line":"      } else if (emptyObj(allocatedIds)) {"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_474b9387","line":72,"range":{"start_line":72,"start_character":41,"end_line":72,"end_character":53},"updated":"2016-07-20 00:04:53.000000000","message":"Since we are allowing other properties to be used as the primary key, we should rename allocatedIds to something like allocatedKeys.","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":69,"context_line":"      return key + \u0027_\u0027 + Object.keys(allocatedIds).sort().join(\u0027_\u0027);"},{"line_number":70,"context_line":"    }"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    function $filterAvailable(available, allocatedIds, idKey) {"},{"line_number":73,"context_line":"      if (emptyArray(available)) {"},{"line_number":74,"context_line":"        return [];"},{"line_number":75,"context_line":"      } else if (emptyObj(allocatedIds)) {"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_18eb7f14","line":72,"range":{"start_line":72,"start_character":41,"end_line":72,"end_character":53},"in_reply_to":"dada55a8_474b9387","updated":"2016-07-20 23:46:45.000000000","message":"Done","commit_id":"86ba12e416851b4512634762792112dcee696788"}],"horizon/static/framework/widgets/transfer-table/filter-available.spec.js":[{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"15d1f0489bd01ceb7015f0e14422994e087642a1","unresolved":false,"context_lines":[{"line_number":29,"context_line":"    var ids \u003d {"},{"line_number":30,"context_line":"      \u0027two\u0027: true"},{"line_number":31,"context_line":"    };"},{"line_number":32,"context_line":"    var filtered \u003d [{"},{"line_number":33,"context_line":"      id: \u0027one\u0027, content: \u0027item1\u0027"},{"line_number":34,"context_line":"    }, {"},{"line_number":35,"context_line":"      id: \u0027three\u0027, content: \u0027item3\u0027"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_f96c2c38","line":32,"updated":"2016-07-08 21:02:01.000000000","message":"hm...this is confusing. I thought that filtered list contains objects whose ids are present in the dictionary? Either the doc is wrong, or this test is wrong (I\u0027m include to think the doc is wrong)?","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"4e5d14b805ee95f9b16b522f65e11a320b4e582a","unresolved":false,"context_lines":[{"line_number":29,"context_line":"    var ids \u003d {"},{"line_number":30,"context_line":"      \u0027two\u0027: true"},{"line_number":31,"context_line":"    };"},{"line_number":32,"context_line":"    var filtered \u003d [{"},{"line_number":33,"context_line":"      id: \u0027one\u0027, content: \u0027item1\u0027"},{"line_number":34,"context_line":"    }, {"},{"line_number":35,"context_line":"      id: \u0027three\u0027, content: \u0027item3\u0027"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_af241660","line":32,"in_reply_to":"1aa78d24_f96c2c38","updated":"2016-07-14 18:54:48.000000000","message":"Doc was correct, maybe a bit obfuscated. Reworded it.","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"}],"horizon/static/framework/widgets/transfer-table/transfer-table.controller.js":[{"author":{"_account_id":14124,"name":"Matt Borland","email":"matt.borland@hpe.com","username":"mborland"},"change_message_id":"580037589c36fc47ab7df3ce7a2edc933e3226ed","unresolved":false,"context_lines":[{"line_number":21,"context_line":"  angular"},{"line_number":22,"context_line":"    .module(\u0027horizon.framework.widgets.transfer-table\u0027)"},{"line_number":23,"context_line":"    .controller(\u0027transferTableController\u0027, TransferTableController)"},{"line_number":24,"context_line":"    .filter(\u0027filterAvailable\u0027, filterAvailable);"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"  TransferTableController.$inject \u003d ["},{"line_number":27,"context_line":"    \u0027$scope\u0027,"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_1ce39aa5","line":24,"range":{"start_line":24,"start_character":5,"end_line":24,"end_character":48},"updated":"2016-06-29 15:18:04.000000000","message":"I guess I\u0027d prefer the filter be broken out explicitly (into its own file) within the module; it\u0027s not as though it is specific to this controller, it\u0027s just attached to the module in this case.","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"a52b58068042cdcf11adf2a11136e94229d303f1","unresolved":false,"context_lines":[{"line_number":21,"context_line":"  angular"},{"line_number":22,"context_line":"    .module(\u0027horizon.framework.widgets.transfer-table\u0027)"},{"line_number":23,"context_line":"    .controller(\u0027transferTableController\u0027, TransferTableController)"},{"line_number":24,"context_line":"    .filter(\u0027filterAvailable\u0027, filterAvailable);"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"  TransferTableController.$inject \u003d ["},{"line_number":27,"context_line":"    \u0027$scope\u0027,"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_f7a18095","line":24,"range":{"start_line":24,"start_character":5,"end_line":24,"end_character":48},"in_reply_to":"3aaa91ec_1ce39aa5","updated":"2016-06-29 17:10:44.000000000","message":"Done","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":14124,"name":"Matt Borland","email":"matt.borland@hpe.com","username":"mborland"},"change_message_id":"580037589c36fc47ab7df3ce7a2edc933e3226ed","unresolved":false,"context_lines":[{"line_number":58,"context_line":"    function $hasher(available, allocatedIds, idKey) {"},{"line_number":59,"context_line":"      available \u003d available || [];"},{"line_number":60,"context_line":"      idKey \u003d $idKeyOrDefault(idKey);"},{"line_number":61,"context_line":"      var key \u003d available.reduce(function(prev, current) {"},{"line_number":62,"context_line":"        return prev + current[idKey];"},{"line_number":63,"context_line":"      }, \u0027\u0027);"},{"line_number":64,"context_line":"      key +\u003d Object.keys(allocatedIds).sort().join(\u0027\u0027);"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_3cc2d6e9","line":61,"updated":"2016-06-29 15:18:04.000000000","message":"name function for debugging","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"a52b58068042cdcf11adf2a11136e94229d303f1","unresolved":false,"context_lines":[{"line_number":58,"context_line":"    function $hasher(available, allocatedIds, idKey) {"},{"line_number":59,"context_line":"      available \u003d available || [];"},{"line_number":60,"context_line":"      idKey \u003d $idKeyOrDefault(idKey);"},{"line_number":61,"context_line":"      var key \u003d available.reduce(function(prev, current) {"},{"line_number":62,"context_line":"        return prev + current[idKey];"},{"line_number":63,"context_line":"      }, \u0027\u0027);"},{"line_number":64,"context_line":"      key +\u003d Object.keys(allocatedIds).sort().join(\u0027\u0027);"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_37edc8b7","line":61,"in_reply_to":"3aaa91ec_3cc2d6e9","updated":"2016-06-29 17:10:44.000000000","message":"Done","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":14124,"name":"Matt Borland","email":"matt.borland@hpe.com","username":"mborland"},"change_message_id":"580037589c36fc47ab7df3ce7a2edc933e3226ed","unresolved":false,"context_lines":[{"line_number":68,"context_line":"    function $filterAvailable(available, allocatedIds, idKey) {"},{"line_number":69,"context_line":"      available \u003d available || [];"},{"line_number":70,"context_line":"      idKey \u003d $idKeyOrDefault(idKey);"},{"line_number":71,"context_line":"      return available.filter(function(item) {"},{"line_number":72,"context_line":"        return !(item[idKey] in allocatedIds);"},{"line_number":73,"context_line":"      });"},{"line_number":74,"context_line":"    }"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_7cb8de75","line":71,"updated":"2016-06-29 15:18:04.000000000","message":"name function","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"a52b58068042cdcf11adf2a11136e94229d303f1","unresolved":false,"context_lines":[{"line_number":68,"context_line":"    function $filterAvailable(available, allocatedIds, idKey) {"},{"line_number":69,"context_line":"      available \u003d available || [];"},{"line_number":70,"context_line":"      idKey \u003d $idKeyOrDefault(idKey);"},{"line_number":71,"context_line":"      return available.filter(function(item) {"},{"line_number":72,"context_line":"        return !(item[idKey] in allocatedIds);"},{"line_number":73,"context_line":"      });"},{"line_number":74,"context_line":"    }"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_972c7c03","line":71,"in_reply_to":"3aaa91ec_7cb8de75","updated":"2016-06-29 17:10:44.000000000","message":"Done","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":14124,"name":"Matt Borland","email":"matt.borland@hpe.com","username":"mborland"},"change_message_id":"580037589c36fc47ab7df3ce7a2edc933e3226ed","unresolved":false,"context_lines":[{"line_number":124,"context_line":"      },"},{"line_number":125,"context_line":"      service: {"},{"line_number":126,"context_line":"        allowed: function() {"},{"line_number":127,"context_line":"          return qExtensions.booleanAsPromise(true);"},{"line_number":128,"context_line":"        },"},{"line_number":129,"context_line":"        perform: function(item) {"},{"line_number":130,"context_line":"          allocate(item);"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_f714e744","line":127,"range":{"start_line":127,"start_character":17,"end_line":127,"end_character":51},"updated":"2016-06-29 15:18:04.000000000","message":"Not a -1, but I\u0027ve wondered...can\u0027t we just return a Promise.resolve(true)?  I seem to recall a small test problem, perhaps that was why.","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":14124,"name":"Matt Borland","email":"matt.borland@hpe.com","username":"mborland"},"change_message_id":"90762c81d17a3bc82228eced762deb9911495660","unresolved":false,"context_lines":[{"line_number":124,"context_line":"      },"},{"line_number":125,"context_line":"      service: {"},{"line_number":126,"context_line":"        allowed: function() {"},{"line_number":127,"context_line":"          return qExtensions.booleanAsPromise(true);"},{"line_number":128,"context_line":"        },"},{"line_number":129,"context_line":"        perform: function(item) {"},{"line_number":130,"context_line":"          allocate(item);"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_82839c55","line":127,"range":{"start_line":127,"start_character":17,"end_line":127,"end_character":51},"in_reply_to":"3aaa91ec_77f4705a","updated":"2016-06-29 17:14:23.000000000","message":"No problem exactly, but if we can/should just return Promise.resolve(true) that seems less dependent, etc.  Not a -1, I use it as well.  :)","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"af367f0184e0630de6b19742dc948c01b84c826a","unresolved":false,"context_lines":[{"line_number":124,"context_line":"      },"},{"line_number":125,"context_line":"      service: {"},{"line_number":126,"context_line":"        allowed: function() {"},{"line_number":127,"context_line":"          return qExtensions.booleanAsPromise(true);"},{"line_number":128,"context_line":"        },"},{"line_number":129,"context_line":"        perform: function(item) {"},{"line_number":130,"context_line":"          allocate(item);"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_9d001d68","line":127,"range":{"start_line":127,"start_character":17,"end_line":127,"end_character":51},"in_reply_to":"3aaa91ec_82839c55","updated":"2016-06-29 17:49:29.000000000","message":"Ha, so it\u0027s just our bad habits :).","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"a52b58068042cdcf11adf2a11136e94229d303f1","unresolved":false,"context_lines":[{"line_number":124,"context_line":"      },"},{"line_number":125,"context_line":"      service: {"},{"line_number":126,"context_line":"        allowed: function() {"},{"line_number":127,"context_line":"          return qExtensions.booleanAsPromise(true);"},{"line_number":128,"context_line":"        },"},{"line_number":129,"context_line":"        perform: function(item) {"},{"line_number":130,"context_line":"          allocate(item);"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_77f4705a","line":127,"range":{"start_line":127,"start_character":17,"end_line":127,"end_character":51},"in_reply_to":"3aaa91ec_f714e744","updated":"2016-06-29 17:10:44.000000000","message":"I\u0027ve learned this pattern from Richard\u0027s code here https://github.com/openstack/horizon/blob/master/openstack_dashboard/dashboards/project/static/dashboard/project/containers/objects-row-actions.service.js#L133 - it\u0027s advantage is that it\u0027s shorter... what is the particular problem with it?","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":14124,"name":"Matt Borland","email":"matt.borland@hpe.com","username":"mborland"},"change_message_id":"ab9f9c77cf4dd0da53c2ec3cbc14fa19a05adc73","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        actionClasses: \u0027fa fa-plus\u0027"},{"line_number":85,"context_line":"      },"},{"line_number":86,"context_line":"      service: {"},{"line_number":87,"context_line":"        allowed: function(item) {"},{"line_number":88,"context_line":"          var allocatable \u003d item \u0026\u0026 !ctrl.allocatedIds[item.id];"},{"line_number":89,"context_line":"          return qExtensions.booleanAsPromise(allocatable);"},{"line_number":90,"context_line":"        },"}],"source_content_type":"text/javascript","patch_set":14,"id":"1aa78d24_bc7269ab","line":87,"range":{"start_line":87,"start_character":17,"end_line":87,"end_character":25},"updated":"2016-07-05 14:22:21.000000000","message":"name functions (all four here)","commit_id":"ee1f4dd302a8b701cdac8270303a49602b3262a3"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"c08d6280b623875c9bec187821bca896ea040e53","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        actionClasses: \u0027fa fa-plus\u0027"},{"line_number":85,"context_line":"      },"},{"line_number":86,"context_line":"      service: {"},{"line_number":87,"context_line":"        allowed: function(item) {"},{"line_number":88,"context_line":"          var allocatable \u003d item \u0026\u0026 !ctrl.allocatedIds[item.id];"},{"line_number":89,"context_line":"          return qExtensions.booleanAsPromise(allocatable);"},{"line_number":90,"context_line":"        },"}],"source_content_type":"text/javascript","patch_set":14,"id":"1aa78d24_fc5a314f","line":87,"range":{"start_line":87,"start_character":17,"end_line":87,"end_character":25},"in_reply_to":"1aa78d24_bc7269ab","updated":"2016-07-05 14:58:21.000000000","message":"Done","commit_id":"ee1f4dd302a8b701cdac8270303a49602b3262a3"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"15d1f0489bd01ceb7015f0e14422994e087642a1","unresolved":false,"context_lines":[{"line_number":78,"context_line":"    var ctrl \u003d this;"},{"line_number":79,"context_line":"    ctrl.allocate \u003d allocate;"},{"line_number":80,"context_line":"    ctrl.deallocate \u003d deallocate;"},{"line_number":81,"context_line":"    ctrl.itemActions \u003d [{"},{"line_number":82,"context_line":"      template: {"},{"line_number":83,"context_line":"        text: \u0027\u0027,"},{"line_number":84,"context_line":"        actionClasses: \u0027fa fa-plus\u0027"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_79eddc8d","line":81,"updated":"2016-07-08 21:02:01.000000000","message":"I would prefer to see this place in transfer-table.actions.js as a service and using the extensible service. This huge block of code also breaks JP style guidelines, we should briefly declare things up here, not an entire list of actions.","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"4e5d14b805ee95f9b16b522f65e11a320b4e582a","unresolved":false,"context_lines":[{"line_number":78,"context_line":"    var ctrl \u003d this;"},{"line_number":79,"context_line":"    ctrl.allocate \u003d allocate;"},{"line_number":80,"context_line":"    ctrl.deallocate \u003d deallocate;"},{"line_number":81,"context_line":"    ctrl.itemActions \u003d [{"},{"line_number":82,"context_line":"      template: {"},{"line_number":83,"context_line":"        text: \u0027\u0027,"},{"line_number":84,"context_line":"        actionClasses: \u0027fa fa-plus\u0027"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_0f1c4ac0","line":81,"in_reply_to":"1aa78d24_79eddc8d","updated":"2016-07-14 18:54:48.000000000","message":"I\u0027d rather avoid moving it to a separate service, because then I\u0027ll have to rewrite large part of controller, removing ctrl.allocatedIds from it.\n\nMoved actions definitions to a function below.","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    //////////"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    function getItemActions() {"},{"line_number":104,"context_line":"      return [{"},{"line_number":105,"context_line":"        template: {"},{"line_number":106,"context_line":"          text: \u0027\u0027,"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_442711b6","line":103,"updated":"2016-07-20 00:04:53.000000000","message":"review this","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    //////////"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    function getItemActions() {"},{"line_number":104,"context_line":"      return [{"},{"line_number":105,"context_line":"        template: {"},{"line_number":106,"context_line":"          text: \u0027\u0027,"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_3d38f53c","line":103,"in_reply_to":"dada55a8_442711b6","updated":"2016-07-20 23:46:45.000000000","message":"?","commit_id":"86ba12e416851b4512634762792112dcee696788"}],"horizon/static/framework/widgets/transfer-table/transfer-table.directive.js":[{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"15d1f0489bd01ceb7015f0e14422994e087642a1","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    //////////////////////"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    function link(scope, element, attrs, ctrl, transclude) {"},{"line_number":64,"context_line":"      function extractClonableTable(element) {"},{"line_number":65,"context_line":"        var table \u003d element.filter(\u0027hz-dynamic-table\u0027);"},{"line_number":66,"context_line":"        if (!table.length) {"},{"line_number":67,"context_line":"          table \u003d element.filter(\u0027table\u0027);"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_39aa341a","line":64,"updated":"2016-07-08 21:02:01.000000000","message":"Optional. Ideally place at the bottom so that when developers read, they are reading the transfer table logic first.","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"4e5d14b805ee95f9b16b522f65e11a320b4e582a","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    //////////////////////"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    function link(scope, element, attrs, ctrl, transclude) {"},{"line_number":64,"context_line":"      function extractClonableTable(element) {"},{"line_number":65,"context_line":"        var table \u003d element.filter(\u0027hz-dynamic-table\u0027);"},{"line_number":66,"context_line":"        if (!table.length) {"},{"line_number":67,"context_line":"          table \u003d element.filter(\u0027table\u0027);"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_af58968b","line":64,"in_reply_to":"1aa78d24_39aa341a","updated":"2016-07-14 18:54:48.000000000","message":"Done","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        });"},{"line_number":86,"context_line":"      }"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"      function extractClonableTable(element) {"},{"line_number":89,"context_line":"        var table \u003d element.filter(\u0027hz-dynamic-table\u0027);"},{"line_number":90,"context_line":"        if (!table.length) {"},{"line_number":91,"context_line":"          table \u003d element.filter(\u0027table\u0027);"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_0436b9e5","line":88,"updated":"2016-07-20 00:04:53.000000000","message":"what is this function doing?","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        });"},{"line_number":86,"context_line":"      }"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"      function extractClonableTable(element) {"},{"line_number":89,"context_line":"        var table \u003d element.filter(\u0027hz-dynamic-table\u0027);"},{"line_number":90,"context_line":"        if (!table.length) {"},{"line_number":91,"context_line":"          table \u003d element.filter(\u0027table\u0027);"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_1df09166","line":88,"in_reply_to":"dada55a8_0436b9e5","updated":"2016-07-20 23:46:45.000000000","message":"added docstring","commit_id":"86ba12e416851b4512634762792112dcee696788"}],"horizon/static/framework/widgets/transfer-table/transfer-table.module.js":[{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":37,"context_line":"   */"},{"line_number":38,"context_line":"  angular"},{"line_number":39,"context_line":"    .module(\u0027horizon.framework.widgets.transfer-table\u0027, ["},{"line_number":40,"context_line":"      \u0027horizon.framework.util.filters\u0027"},{"line_number":41,"context_line":"    ])"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    /**"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_24513d0f","line":40,"updated":"2016-07-20 00:04:53.000000000","message":"is this needed? arent they all bound at the root level?","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":37,"context_line":"   */"},{"line_number":38,"context_line":"  angular"},{"line_number":39,"context_line":"    .module(\u0027horizon.framework.widgets.transfer-table\u0027, ["},{"line_number":40,"context_line":"      \u0027horizon.framework.util.filters\u0027"},{"line_number":41,"context_line":"    ])"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    /**"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_58cfb728","line":40,"in_reply_to":"dada55a8_24513d0f","updated":"2016-07-20 23:46:45.000000000","message":"Done. Moved requiring this module to available-filter unit-tests (that\u0027s why it was originally put here).","commit_id":"86ba12e416851b4512634762792112dcee696788"}],"openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.controller.js":[{"author":{"_account_id":14124,"name":"Matt Borland","email":"matt.borland@hpe.com","username":"mborland"},"change_message_id":"580037589c36fc47ab7df3ce7a2edc933e3226ed","unresolved":false,"context_lines":[{"line_number":72,"context_line":"      trackId: \u0027id\u0027,"},{"line_number":73,"context_line":"      detailsTemplateUrl: basePath + \u0027keypair/keypair-details.html\u0027,"},{"line_number":74,"context_line":"      columns: ["},{"line_number":75,"context_line":"        {id: \u0027name\u0027, title: \u0027Name\u0027, priority: 1},"},{"line_number":76,"context_line":"        {id: \u0027fingerprint\u0027, title: \u0027Fingerprint\u0027, priority: 2}"},{"line_number":77,"context_line":"      ]"},{"line_number":78,"context_line":"    };"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_577a1b89","line":75,"range":{"start_line":75,"start_character":28,"end_line":75,"end_character":34},"updated":"2016-06-29 15:18:04.000000000","message":"gettext()","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"a52b58068042cdcf11adf2a11136e94229d303f1","unresolved":false,"context_lines":[{"line_number":72,"context_line":"      trackId: \u0027id\u0027,"},{"line_number":73,"context_line":"      detailsTemplateUrl: basePath + \u0027keypair/keypair-details.html\u0027,"},{"line_number":74,"context_line":"      columns: ["},{"line_number":75,"context_line":"        {id: \u0027name\u0027, title: \u0027Name\u0027, priority: 1},"},{"line_number":76,"context_line":"        {id: \u0027fingerprint\u0027, title: \u0027Fingerprint\u0027, priority: 2}"},{"line_number":77,"context_line":"      ]"},{"line_number":78,"context_line":"    };"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_5718541e","line":75,"range":{"start_line":75,"start_character":28,"end_line":75,"end_character":34},"in_reply_to":"3aaa91ec_577a1b89","updated":"2016-06-29 17:10:44.000000000","message":"Done","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":14124,"name":"Matt Borland","email":"matt.borland@hpe.com","username":"mborland"},"change_message_id":"580037589c36fc47ab7df3ce7a2edc933e3226ed","unresolved":false,"context_lines":[{"line_number":73,"context_line":"      detailsTemplateUrl: basePath + \u0027keypair/keypair-details.html\u0027,"},{"line_number":74,"context_line":"      columns: ["},{"line_number":75,"context_line":"        {id: \u0027name\u0027, title: \u0027Name\u0027, priority: 1},"},{"line_number":76,"context_line":"        {id: \u0027fingerprint\u0027, title: \u0027Fingerprint\u0027, priority: 2}"},{"line_number":77,"context_line":"      ]"},{"line_number":78,"context_line":"    };"},{"line_number":79,"context_line":""}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_f76987bf","line":76,"range":{"start_line":76,"start_character":35,"end_line":76,"end_character":48},"updated":"2016-06-29 15:18:04.000000000","message":"gettext()","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"a52b58068042cdcf11adf2a11136e94229d303f1","unresolved":false,"context_lines":[{"line_number":73,"context_line":"      detailsTemplateUrl: basePath + \u0027keypair/keypair-details.html\u0027,"},{"line_number":74,"context_line":"      columns: ["},{"line_number":75,"context_line":"        {id: \u0027name\u0027, title: \u0027Name\u0027, priority: 1},"},{"line_number":76,"context_line":"        {id: \u0027fingerprint\u0027, title: \u0027Fingerprint\u0027, priority: 2}"},{"line_number":77,"context_line":"      ]"},{"line_number":78,"context_line":"    };"},{"line_number":79,"context_line":""}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_3715c8e4","line":76,"range":{"start_line":76,"start_character":35,"end_line":76,"end_character":48},"in_reply_to":"3aaa91ec_f76987bf","updated":"2016-06-29 17:10:44.000000000","message":"Done","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":14124,"name":"Matt Borland","email":"matt.borland@hpe.com","username":"mborland"},"change_message_id":"580037589c36fc47ab7df3ce7a2edc933e3226ed","unresolved":false,"context_lines":[{"line_number":78,"context_line":"    };"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    ctrl.allocatedTableConfig \u003d Object.create(ctrl.availableTableConfig);"},{"line_number":81,"context_line":"    ctrl.allocatedTableConfig.noItemsMessage \u003d \u0027Select a key pair from \u0027 +"},{"line_number":82,"context_line":"      \u0027the available key pairs below.\u0027;"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    ctrl.tableLimits \u003d {"},{"line_number":85,"context_line":"      maxAllocation: 1"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_b7a25ffa","line":82,"range":{"start_line":81,"start_character":47,"end_line":82,"end_character":38},"updated":"2016-06-29 15:18:04.000000000","message":"gettext()","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"a52b58068042cdcf11adf2a11136e94229d303f1","unresolved":false,"context_lines":[{"line_number":78,"context_line":"    };"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    ctrl.allocatedTableConfig \u003d Object.create(ctrl.availableTableConfig);"},{"line_number":81,"context_line":"    ctrl.allocatedTableConfig.noItemsMessage \u003d \u0027Select a key pair from \u0027 +"},{"line_number":82,"context_line":"      \u0027the available key pairs below.\u0027;"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    ctrl.tableLimits \u003d {"},{"line_number":85,"context_line":"      maxAllocation: 1"}],"source_content_type":"text/javascript","patch_set":7,"id":"3aaa91ec_97d47c20","line":82,"range":{"start_line":81,"start_character":47,"end_line":82,"end_character":38},"in_reply_to":"3aaa91ec_b7a25ffa","updated":"2016-06-29 17:10:44.000000000","message":"Done","commit_id":"aa7a1d346deb908bd1187e7df33282bee5e51978"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"15d1f0489bd01ceb7015f0e14422994e087642a1","unresolved":false,"context_lines":[{"line_number":65,"context_line":"      allocated: launchInstanceModel.newInstanceSpec.key_pair"},{"line_number":66,"context_line":"    };"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    ctrl.availableTableConfig \u003d {"},{"line_number":69,"context_line":"      selectAll: false,"},{"line_number":70,"context_line":"      trackId: \u0027id\u0027,"},{"line_number":71,"context_line":"      detailsTemplateUrl: basePath + \u0027keypair/keypair-details.html\u0027,"}],"source_content_type":"text/javascript","patch_set":19,"id":"1aa78d24_b93aa4e5","line":68,"updated":"2016-07-08 21:02:01.000000000","message":"the table config and filter facets should ideally live in its own file as a service and uses the extensible service. I understand keypair is very small, but if we hardcode it here, it does make it that much harder to customize via plugins.","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"f52a30f74c8059759ead1a09160f6ee27493047b","unresolved":false,"context_lines":[{"line_number":65,"context_line":"      allocated: launchInstanceModel.newInstanceSpec.key_pair"},{"line_number":66,"context_line":"    };"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    ctrl.availableTableConfig \u003d {"},{"line_number":69,"context_line":"      selectAll: false,"},{"line_number":70,"context_line":"      trackId: \u0027id\u0027,"},{"line_number":71,"context_line":"      detailsTemplateUrl: basePath + \u0027keypair/keypair-details.html\u0027,"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_847d8970","line":68,"updated":"2016-07-20 00:04:53.000000000","message":"Recommendation. Suggestions for code organization per JPs style guide. Try to keep the controller properties concise, anything more than one line should probably be done later in the code.\n\n\n  ctrl.availableTableConfig \u003d getTableConfig();\n  .....\n\n  function getTableConfig() {\n    return { /*your config object*/ }\n  }","commit_id":"86ba12e416851b4512634762792112dcee696788"},{"author":{"_account_id":8040,"name":"Timur Sufiev","email":"tsufiev@gmail.com","username":"tsufiev"},"change_message_id":"aa3ee0a49390aa95a61f6317bfcd6a338c1d2e6d","unresolved":false,"context_lines":[{"line_number":65,"context_line":"      allocated: launchInstanceModel.newInstanceSpec.key_pair"},{"line_number":66,"context_line":"    };"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    ctrl.availableTableConfig \u003d {"},{"line_number":69,"context_line":"      selectAll: false,"},{"line_number":70,"context_line":"      trackId: \u0027id\u0027,"},{"line_number":71,"context_line":"      detailsTemplateUrl: basePath + \u0027keypair/keypair-details.html\u0027,"}],"source_content_type":"text/javascript","patch_set":20,"id":"dada55a8_3db9157a","line":68,"in_reply_to":"dada55a8_847d8970","updated":"2016-07-20 23:46:45.000000000","message":"I would prefer to keep it this way, since it\u0027s only 6 lines long and moving the config object into a function may reduce code readability comparing to what we have now.","commit_id":"86ba12e416851b4512634762792112dcee696788"}],"openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/keypair/keypair.html":[{"author":{"_account_id":7665,"name":"Travis Tripp","email":"os.travis.tripp@gmail.com","username":"travis.tripp"},"change_message_id":"90599fb772af6eb7fd8c88bd7669b9386060f7b0","unresolved":false,"context_lines":[{"line_number":29,"context_line":""},{"line_number":30,"context_line":"  \u003ctransfer-table tr-model\u003d\"ctrl.tableData\""},{"line_number":31,"context_line":"                  limits\u003d\"ctrl.tableLimits\"\u003e"},{"line_number":32,"context_line":"    \u003callocated validate-number-min\u003d\"ctrl.isKeypairRequired\" ng-model\u003d\"ctrl.tableData.allocated.length\"\u003e"},{"line_number":33,"context_line":"      \u003chz-dynamic-table"},{"line_number":34,"context_line":"        config\u003d\"ctrl.allocatedTableConfig\""},{"line_number":35,"context_line":"        items\u003d\"ctrl.tableData.allocated\""}],"source_content_type":"text/html","patch_set":8,"id":"3aaa91ec_2b3c40c7","line":32,"updated":"2016-06-29 19:28:39.000000000","message":"I\u0027m going to put this on here just to ensure you are aware of it and have seen if using it would simplify this whole patch even further.  Transfer table has a \"clone\" feature [0]. Can this patch use that and not need to do some of the other things in this patch?\n\nhttps://review.openstack.org/#/c/211345/","commit_id":"8f9bc42c2b5768b13daf2f68a35bf54681fb3c69"},{"author":{"_account_id":9576,"name":"Thai Tran","email":"tqtran@us.ibm.com","username":"tqtran"},"change_message_id":"15d1f0489bd01ceb7015f0e14422994e087642a1","unresolved":false,"context_lines":[{"line_number":28,"context_line":"  \u003c/button\u003e"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"  \u003ctransfer-table tr-model\u003d\"ctrl.tableData\" limits\u003d\"ctrl.tableLimits\" clone-content\u003e"},{"line_number":31,"context_line":"    \u003chz-dynamic-table"},{"line_number":32,"context_line":"        config\u003d\"$isAvailableTable ? ctrl.availableTableConfig : ctrl.allocatedTableConfig\""},{"line_number":33,"context_line":"        items\u003d\"$isAvailableTable ? ($sourceItems | filterAvailable:trCtrl.allocatedIds) : $sourceItems\""},{"line_number":34,"context_line":"        item-actions\u003d\"trCtrl.itemActions\""}],"source_content_type":"text/html","patch_set":19,"id":"1aa78d24_f90b8c29","line":31,"updated":"2016-07-08 21:02:01.000000000","message":"lovely!","commit_id":"7855079db33ead6eb4c83d7b4d90cb3fb5731c31"}]}
