diff --git a/Gemfile b/Gemfile index 222c0c1a1c..af4a606437 100644 --- a/Gemfile +++ b/Gemfile @@ -111,10 +111,9 @@ gem 'momentjs-rails' # gem 'turbo-sprockets-rails3' gem 'foundation-rails', '= 5.5.2.1' -gem 'foundation_rails_helper', github: 'willrjmarshall/foundation_rails_helper', branch: 'rails3' gem 'jquery-migrate-rails' -gem 'jquery-rails', '3.0.4' +gem 'jquery-rails', '3.1.5' gem 'jquery-ui-rails', '~> 4.0.0' gem 'select2-rails', '~> 3.4.7' diff --git a/Gemfile.lock b/Gemfile.lock index f645aca60e..a2f479853c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -56,16 +56,6 @@ GIT rails-i18n spree_core (>= 1.1) -GIT - remote: https://github.com/willrjmarshall/foundation_rails_helper.git - revision: 4d5d53fdc4b1fb71e66524d298c5c635de82cfbb - branch: rails3 - specs: - foundation_rails_helper (0.4) - actionpack (>= 3.0) - activemodel (>= 3.0) - railties (>= 3.0) - PATH remote: engines/catalog specs: @@ -194,7 +184,7 @@ GEM sass (>= 3.3.0, < 3.5) compass-import-once (1.0.5) sass (>= 3.2, < 3.5) - compass-rails (3.1.0) + compass-rails (4.0.0) compass (~> 1.0.0) sass-rails (< 5.1) sprockets (< 4.0) @@ -210,7 +200,7 @@ GEM activerecord (>= 3.2.0, < 5.0) fog (~> 1.0) rails (>= 3.2.0, < 5.0) - ddtrace (0.33.1) + ddtrace (0.34.0) msgpack debugger-linecache (1.2.0) deface (1.0.2) @@ -251,7 +241,7 @@ GEM faraday (1.0.0) multipart-post (>= 1.2, < 3) ffaker (1.32.1) - ffi (1.11.3) + ffi (1.12.2) figaro (1.1.1) thor (~> 0.14) fission (0.5.0) @@ -434,7 +424,7 @@ GEM ipaddress (0.8.3) jaro_winkler (1.5.4) jquery-migrate-rails (1.2.1) - jquery-rails (3.0.4) + jquery-rails (3.1.5) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) jquery-ui-rails (4.0.5) @@ -498,7 +488,7 @@ GEM parallel (1.19.1) paranoia (2.4.2) activerecord (>= 4.0, < 6.1) - parser (2.7.0.4) + parser (2.7.0.5) ast (~> 2.4.0) paypal-sdk-core (0.2.10) multi_json (~> 1.0) @@ -519,7 +509,7 @@ GEM rabl (0.8.4) activesupport (>= 2.3.14) rack (1.5.5) - rack-mini-profiler (2.0.0) + rack-mini-profiler (2.0.1) rack (>= 1.2.0) rack-protection (1.5.5) rack @@ -553,7 +543,7 @@ GEM activerecord (>= 3.0) polyamorous (~> 0.6.0) rb-fsevent (0.10.3) - rb-inotify (0.10.0) + rb-inotify (0.10.1) ffi (~> 1.0) rbvmomi (2.2.0) builder (~> 3.0) @@ -596,15 +586,16 @@ GEM rspec-retry (0.6.2) rspec-core (> 3.3) rspec-support (3.9.2) - rubocop (0.80.1) + rubocop (0.81.0) jaro_winkler (~> 1.5.1) parallel (~> 1.10) parser (>= 2.7.0.1) rainbow (>= 2.2.2, < 4.0) rexml ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 1.7) - rubocop-rails (2.4.2) + unicode-display_width (>= 1.4.0, < 2.0) + rubocop-rails (2.5.0) + activesupport rack (>= 1.1) rubocop (>= 0.72.0) ruby-progressbar (1.10.1) @@ -662,8 +653,8 @@ GEM tzinfo (0.3.56) uglifier (4.2.0) execjs (>= 0.3.0, < 3) - unicode-display_width (1.6.1) - unicorn (5.5.3) + unicode-display_width (1.7.0) + unicorn (5.5.4) kgio (~> 2.6) raindrops (~> 0.7) unicorn-rails (2.2.1) @@ -733,7 +724,6 @@ DEPENDENCIES foreigner foundation-icons-sass-rails foundation-rails (= 5.5.2.1) - foundation_rails_helper! fuubar (~> 2.4.1) geocoder gmaps4rails @@ -742,7 +732,7 @@ DEPENDENCIES i18n-js (~> 3.6.0) immigrant jquery-migrate-rails - jquery-rails (= 3.0.4) + jquery-rails (= 3.1.5) jquery-ui-rails (~> 4.0.0) json_spec (~> 1.1.4) jwt (~> 2.2) diff --git a/README.md b/README.md index 9459c689d5..16a97f2709 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ We use [BrowserStack](https://www.browserstack.com/) as a manual testing tool. B Copyright (c) 2012 - 2020 Open Food Foundation, released under the AGPL licence. [survey]: https://docs.google.com/a/eaterprises.com.au/forms/d/1zxR5vSiU9CigJ9cEaC8-eJLgYid8CR8er7PPH9Mc-30/edit# -[slack-invite]: https://join.slack.com/t/openfoodnetwork/shared_invite/enQtNzY3NDEwNzM2MDM0LWFmNGRhNDUwYzNmNWNkYmFkMzgxNDg1OTg1ODNjNWY4Y2FhNDIwNmE4ZWI0OThiMGNmZjFkODczNGZiYTJmNWI +[slack-invite]: https://join.slack.com/t/openfoodnetwork/shared_invite/zt-9sjkjdlu-r02kUMP1zbrTgUhZhYPF~A [contributor-guide]: https://ofn-user-guide.gitbook.io/ofn-contributor-guide/who-are-we [ofn-install]: https://github.com/openfoodfoundation/ofn-install [super-admin-guide]: https://ofn-user-guide.gitbook.io/ofn-super-admin-guide diff --git a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee index 6107760307..46a6598e4f 100644 --- a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee +++ b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee @@ -1,7 +1,7 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $http, $q, StatusMessage, Columns, SortOptions, Dereferencer, Orders, LineItems, Enterprises, OrderCycles, VariantUnitManager, RequestMonitor) -> $scope.initialized = false $scope.RequestMonitor = RequestMonitor - $scope.filteredLineItems = [] + $scope.line_items = LineItems.all $scope.confirmDelete = true $scope.startDate = moment().startOf('day').subtract(7, 'days').format('YYYY-MM-DD') $scope.endDate = moment().startOf('day').format('YYYY-MM-DD') @@ -15,50 +15,77 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $scope.confirmRefresh = -> LineItems.allSaved() || confirm(t("unsaved_changes_warning")) + $scope.resetFilters = -> + $scope.distributorFilter = '' + $scope.supplierFilter = '' + $scope.orderCycleFilter = '' + $scope.quickSearch = '' + $scope.resetSelectFilters = -> - $scope.distributorFilter = 0 - $scope.supplierFilter = 0 - $scope.orderCycleFilter = 0 - $scope.quickSearch = "" + $scope.resetFilters() + $scope.refreshData() $scope.refreshData = -> - unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == 0 - $scope.startDate = moment(OrderCycles.byID[$scope.orderCycleFilter].orders_open_at).format('YYYY-MM-DD') - $scope.endDate = moment(OrderCycles.byID[$scope.orderCycleFilter].orders_close_at).startOf('day').format('YYYY-MM-DD') + unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == '' + $scope.setOrderCycleDateRange() - formatted_start_date = moment($scope.startDate).format() - formatted_end_date = moment($scope.endDate).add(1,'day').format() + $scope.formattedStartDate = moment($scope.startDate).format() + $scope.formattedEndDate = moment($scope.endDate).add(1,'day').format() + return unless moment($scope.formattedStartDate).isValid() and moment($scope.formattedEndDate).isValid() + + $scope.loadOrders() + $scope.loadLineItems() + + unless $scope.initialized + $scope.loadAssociatedData() + + $scope.dereferenceLoadedData() + + $scope.setOrderCycleDateRange = -> + start_date = OrderCycles.byID[$scope.orderCycleFilter].orders_open_at + end_date = OrderCycles.byID[$scope.orderCycleFilter].orders_close_at + format = "YYYY-MM-DD HH:mm:ss Z" + $scope.startDate = moment(start_date, format).format('YYYY-MM-DD') + $scope.endDate = moment(end_date, format).startOf('day').format('YYYY-MM-DD') + + $scope.loadOrders = -> RequestMonitor.load $scope.orders = Orders.index( "q[state_not_eq]": "canceled", "q[completed_at_not_null]": "true", - "q[completed_at_gteq]": formatted_start_date, - "q[completed_at_lt]": formatted_end_date + "q[distributor_id_eq]": $scope.distributorFilter, + "q[order_cycle_id_eq]": $scope.orderCycleFilter, + "q[completed_at_gteq]": $scope.formattedStartDate, + "q[completed_at_lt]": $scope.formattedEndDate ) - RequestMonitor.load $scope.lineItems = LineItems.index( - "q[order][state_not_eq]": "canceled", - "q[order][completed_at_not_null]": "true", - "q[order][completed_at_gteq]": formatted_start_date, - "q[order][completed_at_lt]": formatted_end_date + $scope.loadLineItems = -> + RequestMonitor.load LineItems.index( + "q[order_state_not_eq]": "canceled", + "q[order_completed_at_not_null]": "true", + "q[order_distributor_id_eq]": $scope.distributorFilter, + "q[variant_product_supplier_id_eq]": $scope.supplierFilter, + "q[order_order_cycle_id_eq]": $scope.orderCycleFilter, + "q[order_completed_at_gteq]": $scope.formattedStartDate, + "q[order_completed_at_lt]": $scope.formattedEndDate ) - unless $scope.initialized - RequestMonitor.load $scope.distributors = Enterprises.index(action: "visible", ams_prefix: "basic", "q[sells_in][]": ["own", "any"]) - RequestMonitor.load $scope.orderCycles = OrderCycles.index(ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{moment().subtract(90,'days').format()}") - RequestMonitor.load $scope.suppliers = Enterprises.index(action: "visible", ams_prefix: "basic", "q[is_primary_producer_eq]": "true") + $scope.loadAssociatedData = -> + RequestMonitor.load $scope.distributors = Enterprises.index(action: "visible", ams_prefix: "basic", "q[sells_in][]": ["own", "any"]) + RequestMonitor.load $scope.orderCycles = OrderCycles.index(ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{moment().subtract(90,'days').format()}") + RequestMonitor.load $scope.suppliers = Enterprises.index(action: "visible", ams_prefix: "basic", "q[is_primary_producer_eq]": "true") - RequestMonitor.load $q.all([$scope.orders.$promise, $scope.distributors.$promise, $scope.orderCycles.$promise, $scope.suppliers.$promise, $scope.lineItems.$promise]).then -> + $scope.dereferenceLoadedData = -> + RequestMonitor.load $q.all([$scope.orders.$promise, $scope.distributors.$promise, $scope.orderCycles.$promise, $scope.suppliers.$promise, $scope.line_items.$promise]).then -> Dereferencer.dereferenceAttr $scope.orders, "distributor", Enterprises.byID Dereferencer.dereferenceAttr $scope.orders, "order_cycle", OrderCycles.byID - Dereferencer.dereferenceAttr $scope.lineItems, "supplier", Enterprises.byID - Dereferencer.dereferenceAttr $scope.lineItems, "order", Orders.byID + Dereferencer.dereferenceAttr $scope.line_items, "supplier", Enterprises.byID + Dereferencer.dereferenceAttr $scope.line_items, "order", Orders.byID $scope.bulk_order_form.$setPristine() StatusMessage.clear() + unless $scope.initialized $scope.initialized = true - $timeout -> - $scope.resetSelectFilters() $scope.$watch 'bulk_order_form.$dirty', (newVal, oldVal) -> if newVal == true @@ -77,13 +104,12 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $scope.deleteLineItem = (lineItem) -> if ($scope.confirmDelete && confirm(t "are_you_sure")) || !$scope.confirmDelete - LineItems.delete lineItem, => - $scope.lineItems.splice $scope.lineItems.indexOf(lineItem), 1 + LineItems.delete lineItem - $scope.deleteLineItems = (lineItems) -> + $scope.deleteLineItems = (lineItemsToDelete) -> existingState = $scope.confirmDelete $scope.confirmDelete = false - $scope.deleteLineItem lineItem for lineItem in lineItems when lineItem.checked + $scope.deleteLineItem lineItem for lineItem in lineItemsToDelete when lineItem.checked $scope.confirmDelete = existingState $scope.allBoxesChecked = -> @@ -154,4 +180,5 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, lineItem.final_weight_volume = LineItems.pristineByID[lineItem.id].final_weight_volume * lineItem.quantity / LineItems.pristineByID[lineItem.id].quantity $scope.weightAdjustedPrice(lineItem) + $scope.resetFilters() $scope.refreshData() diff --git a/app/assets/javascripts/admin/payments/services/stripe_elements.js.coffee b/app/assets/javascripts/admin/payments/services/stripe_elements.js.coffee index 9ecf2b1db1..d5c20e8668 100644 --- a/app/assets/javascripts/admin/payments/services/stripe_elements.js.coffee +++ b/app/assets/javascripts/admin/payments/services/stripe_elements.js.coffee @@ -14,9 +14,10 @@ angular.module("admin.payments").factory 'AdminStripeElements', ($rootScope, Sta @stripe.createToken(@card, cardData).then (response) => if(response.error) StatusMessage.display 'error', response.error.message + console.error(JSON.stringify(response.error)) else secrets.token = response.token.id - secrets.cc_type = @mapCC(response.token.card.brand) + secrets.cc_type = @mapTokenApiCardBrand(response.token.card.brand) secrets.card = response.token.card submit() @@ -29,15 +30,16 @@ angular.module("admin.payments").factory 'AdminStripeElements', ($rootScope, Sta @stripe.createPaymentMethod({ type: 'card', card: @card }, @card, cardData).then (response) => if(response.error) StatusMessage.display 'error', response.error.message + console.error(JSON.stringify(response.error)) else secrets.token = response.paymentMethod.id - secrets.cc_type = response.paymentMethod.card.brand + secrets.cc_type = @mapPaymentMethodsApiCardBrand(response.paymentMethod.card.brand) secrets.card = response.paymentMethod.card submit() - # Maps the brand returned by Stripe to that required by activemerchant - mapCC: (ccType) -> - switch ccType + # Maps the brand returned by Stripe's tokenAPI to that required by activemerchant + mapTokenApiCardBrand: (cardBrand) -> + switch cardBrand when 'MasterCard' then return 'master' when 'Visa' then return 'visa' when 'American Express' then return 'american_express' @@ -45,6 +47,14 @@ angular.module("admin.payments").factory 'AdminStripeElements', ($rootScope, Sta when 'JCB' then return 'jcb' when 'Diners Club' then return 'diners_club' + # Maps the brand returned by Stripe's paymentMethodsAPI to that required by activemerchant + mapPaymentMethodsApiCardBrand: (cardBrand) -> + switch cardBrand + when 'mastercard' then return 'master' + when 'amex' then return 'american_express' + when 'diners' then return 'diners_club' + else return cardBrand # a few brands are equal, for example, visa + # It doesn't matter if any of these are nil, all are optional. makeCardData: (secrets) -> {'name': secrets.name, diff --git a/app/assets/javascripts/admin/resources/resources/line_item_resource.js.coffee b/app/assets/javascripts/admin/resources/resources/line_item_resource.js.coffee index 2ec5703c82..28b92bac21 100644 --- a/app/assets/javascripts/admin/resources/resources/line_item_resource.js.coffee +++ b/app/assets/javascripts/admin/resources/resources/line_item_resource.js.coffee @@ -2,7 +2,6 @@ angular.module("admin.resources").factory 'LineItemResource', ($resource) -> $resource('/admin/bulk_line_items/:id.json', {}, { 'index': method: 'GET' - isArray: true 'update': method: 'PUT' transformRequest: (data, headersGetter) => diff --git a/app/assets/javascripts/admin/resources/services/line_items.js.coffee b/app/assets/javascripts/admin/resources/services/line_items.js.coffee index 7c96caecd8..fb92e51890 100644 --- a/app/assets/javascripts/admin/resources/services/line_items.js.coffee +++ b/app/assets/javascripts/admin/resources/services/line_items.js.coffee @@ -1,20 +1,27 @@ angular.module("admin.resources").factory 'LineItems', ($q, LineItemResource) -> new class LineItems + all: [] byID: {} pristineByID: {} + pagination: {} index: (params={}, callback=null) -> - LineItemResource.index params, (data) => + request = LineItemResource.index params, (data) => @load(data) (callback || angular.noop)(data) + @all.$promise = request.$promise + @all resetData: -> + @all.length = 0 @byID = {} @pristineByID = {} - load: (lineItems) -> + load: (data) -> + angular.extend(@pagination, data.pagination) @resetData() - for lineItem in lineItems + for lineItem in data.line_items + @all.push lineItem @byID[lineItem.id] = lineItem @pristineByID[lineItem.id] = angular.copy(lineItem) @@ -25,8 +32,9 @@ angular.module("admin.resources").factory 'LineItems', ($q, LineItemResource) -> save: (lineItem) -> deferred = $q.defer() + lineItemResource = new LineItemResource(lineItem) lineItem.errors = {} - lineItem.$update({id: lineItem.id}) + lineItemResource.$update({id: lineItem.id}) .then( (data) => @pristineByID[lineItem.id] = angular.copy(lineItem) deferred.resolve(data) @@ -54,8 +62,10 @@ angular.module("admin.resources").factory 'LineItems', ($q, LineItemResource) -> delete: (lineItem, callback=null) -> deferred = $q.defer() - lineItem.$delete({id: lineItem.id}) + lineItemResource = new LineItemResource(lineItem) + lineItemResource.$delete({id: lineItem.id}) .then( (data) => + @all.splice(@all.indexOf(lineItem),1) delete @byID[lineItem.id] delete @pristineByID[lineItem.id] (callback || angular.noop)(data) diff --git a/app/assets/javascripts/darkswarm/all.js.coffee b/app/assets/javascripts/darkswarm/all.js.coffee index b62eb915af..aa0fafa058 100644 --- a/app/assets/javascripts/darkswarm/all.js.coffee +++ b/app/assets/javascripts/darkswarm/all.js.coffee @@ -9,6 +9,8 @@ #= require angular-animate #= require angular-resource #= require lodash.underscore.js +# bluebird.js is a dependency of angular-google-maps.js 2.0.0 +#= require bluebird.js #= require angular-scroll.min.js #= require angular-google-maps.min.js #= require ../shared/mm-foundation-tpls-0.9.0-20180826174721.min.js diff --git a/app/assets/javascripts/darkswarm/controllers/page_selection_ctrl.js.coffee b/app/assets/javascripts/darkswarm/controllers/page_selection_ctrl.js.coffee new file mode 100644 index 0000000000..9f4cbe2c1b --- /dev/null +++ b/app/assets/javascripts/darkswarm/controllers/page_selection_ctrl.js.coffee @@ -0,0 +1,17 @@ +Darkswarm.controller "PageSelectionCtrl", ($scope, $location) -> + $scope.selectedPage = -> + # The path looks like `/contact` for the URL `https://ofn.org/shop#/contact`. + # We remove the slash at the beginning. + page = $location.path()[1..] + + return $scope.whitelist[0] unless page + + # If the path points to an unrelated path like `/login`, stay where we were. + return $scope.lastPage unless page in $scope.whitelist + + $scope.lastPage = page + page + + $scope.whitelistPages = (pages) -> + $scope.whitelist = pages + $scope.lastPage = pages[0] diff --git a/app/assets/javascripts/darkswarm/darkswarm.js.coffee b/app/assets/javascripts/darkswarm/darkswarm.js.coffee index 01a93a3dd1..d26b884045 100644 --- a/app/assets/javascripts/darkswarm/darkswarm.js.coffee +++ b/app/assets/javascripts/darkswarm/darkswarm.js.coffee @@ -7,7 +7,7 @@ window.Darkswarm = angular.module("Darkswarm", [ 'templates', 'ngSanitize', 'ngAnimate', - 'google-maps', + 'uiGmapgoogle-maps', 'duScroll', 'angularFileUpload', 'angularSlideables' diff --git a/app/assets/javascripts/darkswarm/directives/map_osm_tiles.js.coffee b/app/assets/javascripts/darkswarm/directives/map_osm_tiles.js.coffee index deb7186d95..394236ce61 100644 --- a/app/assets/javascripts/darkswarm/directives/map_osm_tiles.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/map_osm_tiles.js.coffee @@ -1,6 +1,6 @@ Darkswarm.directive 'mapOsmTiles', ($timeout) -> restrict: 'E' - require: '^googleMap' + require: '^uiGmapGoogleMap' scope: {} link: (scope, elem, attrs, ctrl) -> $timeout => diff --git a/app/assets/javascripts/darkswarm/directives/map_search.js.coffee b/app/assets/javascripts/darkswarm/directives/map_search.js.coffee index af82766d62..322fa4bb28 100644 --- a/app/assets/javascripts/darkswarm/directives/map_search.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/map_search.js.coffee @@ -1,7 +1,7 @@ Darkswarm.directive 'mapSearch', ($timeout, Search) -> # Install a basic search field in a map restrict: 'E' - require: ['^googleMap', 'ngModel'] + require: ['^uiGmapGoogleMap', 'ngModel'] replace: true template: '' scope: {} diff --git a/app/assets/javascripts/darkswarm/services/enterprises.js.coffee b/app/assets/javascripts/darkswarm/services/enterprises.js.coffee index d3b7deec3e..b7b43ca040 100644 --- a/app/assets/javascripts/darkswarm/services/enterprises.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprises.js.coffee @@ -50,7 +50,7 @@ Darkswarm.factory 'Enterprises', (enterprises, CurrentHub, Taxons, Dereferencer, false calculateDistance: (query, firstMatching) -> - if query?.length > 0 + if query?.length > 0 and Geo.OK if firstMatching? @setDistanceFrom firstMatching else diff --git a/app/assets/javascripts/darkswarm/services/geo.js.erb.coffee b/app/assets/javascripts/darkswarm/services/geo.js.erb.coffee index f0e60be529..ee5961be36 100644 --- a/app/assets/javascripts/darkswarm/services/geo.js.erb.coffee +++ b/app/assets/javascripts/darkswarm/services/geo.js.erb.coffee @@ -1,6 +1,6 @@ Darkswarm.service "Geo", -> new class Geo - OK: google.maps.GeocoderStatus.OK + OK: google?.maps?.GeocoderStatus?.OK # Usage: # Geo.geocode address, (results, status) -> diff --git a/app/assets/javascripts/darkswarm/services/stripe_elements.js.coffee b/app/assets/javascripts/darkswarm/services/stripe_elements.js.coffee index acd220f092..46a6babf0d 100644 --- a/app/assets/javascripts/darkswarm/services/stripe_elements.js.coffee +++ b/app/assets/javascripts/darkswarm/services/stripe_elements.js.coffee @@ -15,9 +15,11 @@ Darkswarm.factory 'StripeElements', ($rootScope, Loading, RailsFlashLoader) -> if(response.error) Loading.clear() RailsFlashLoader.loadFlash({error: t("error") + ": #{response.error.message}"}) + @triggerAngularDigest() + console.error(JSON.stringify(response.error)) else secrets.token = response.token.id - secrets.cc_type = @mapCC(response.token.card.brand) + secrets.cc_type = @mapTokenApiCardBrand(response.token.card.brand) secrets.card = response.token.card submit() @@ -32,15 +34,21 @@ Darkswarm.factory 'StripeElements', ($rootScope, Loading, RailsFlashLoader) -> if(response.error) Loading.clear() RailsFlashLoader.loadFlash({error: t("error") + ": #{response.error.message}"}) + @triggerAngularDigest() + console.error(JSON.stringify(response.error)) else secrets.token = response.paymentMethod.id - secrets.cc_type = response.paymentMethod.card.brand + secrets.cc_type = @mapPaymentMethodsApiCardBrand(response.paymentMethod.card.brand) secrets.card = response.paymentMethod.card submit() - # Maps the brand returned by Stripe to that required by activemerchant - mapCC: (ccType) -> - switch ccType + triggerAngularDigest: -> + # $evalAsync is improved way of triggering a digest without calling $apply + $rootScope.$evalAsync() + + # Maps the brand returned by Stripe's tokenAPI to that required by activemerchant + mapTokenApiCardBrand: (cardBrand) -> + switch cardBrand when 'MasterCard' then return 'master' when 'Visa' then return 'visa' when 'American Express' then return 'american_express' @@ -48,6 +56,14 @@ Darkswarm.factory 'StripeElements', ($rootScope, Loading, RailsFlashLoader) -> when 'JCB' then return 'jcb' when 'Diners Club' then return 'diners_club' + # Maps the brand returned by Stripe's paymentMethodsAPI to that required by activemerchant + mapPaymentMethodsApiCardBrand: (cardBrand) -> + switch cardBrand + when 'mastercard' then return 'master' + when 'amex' then return 'american_express' + when 'diners' then return 'diners_club' + else return cardBrand # a few brands are equal, for example, visa + # It doesn't matter if any of these are nil, all are optional. makeCardData: (secrets) -> {'name': secrets.name, diff --git a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss index fd08599222..80c2bfe09a 100644 --- a/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-navigation.css.scss @@ -1,77 +1,13 @@ @import "typography"; -.darkswarm navigation { - display: block; - background: $white; - - distributor.details { - box-sizing: border-box; - display: block; - min-height: 150px; - padding: 30px 0 20px 0; - position: relative; - - select { - width: 200px; - } - - img { - display: block; - height: 100px; - width: 100px; - margin-right: 12px; - } - - location { - @include headingFont; - } - @media all and (max-width: 768px) { - location, location + small { - display: block; - } - } - - #distributor_title h3 { - margin-top: 0; - padding-top: 0.45em; - - @media all and (max-width: 768px) { - margin-bottom: 8px; - } - } - } -} - ordercycle { float: right; - background: $teal-400; - color: $white; + background: $grey-050; + color: $grey-800; width: 100%; border-radius: 0.5em 0.5em 0 0; - position: absolute; - right: 1em; - padding: 1em; - margin-top: 3em; - height: 7.6em; - - &.requires-selection { - background-color: $red-700; - - .order-cycle-select { - border: 1px solid $red-500; - - .select-label { - background-color: rgba($red-500, 0.5); - } - - select { - background-color: $white; - background-image: url('/assets/black-caret.svg'); - color: $grey-500; - font-style: italic; - } - } - } + margin-top: 1em; + padding: 1em 1.25em 0; p { max-width: 400px; @@ -97,14 +33,10 @@ ordercycle { } } - @media all and (max-width: 768px) { + @media all and (max-width: 480px) { padding: 0.5em 1em 0.75em; } - form.custom { - text-align: center; - } - .order-cycle-select { border: 1px solid $teal-300; display: inline-block; @@ -164,9 +96,44 @@ ordercycle { closing { @include headingFont; - color: $white; + color: $grey-800; font-size: 1.25rem; display: block; + padding: 0.5em 0; + + span { + @media all and (max-width: 768px) { + font-size: 0.875em; + } + } + } +} + +shop ordercycle { + background: $teal-400; + color: $white; + + &.requires-selection { + background-color: $red-700; + + .order-cycle-select { + border: 1px solid $red-500; + + .select-label { + background-color: rgba($red-500, 0.5); + } + + select { + background-color: $white; + background-image: url('/assets/black-caret.svg'); + color: $grey-500; + font-style: italic; + } + } + } + + closing { + color: $white; padding: 0 0 12px; @media all and (max-width: 1024px) { @@ -181,11 +148,25 @@ ordercycle { float: none; padding: 0 0 10px; } + } - span { - @media all and (max-width: 768px) { - font-size: 0.875em; - } + form.custom { + text-align: center; + } +} + +shop navigation ordercycle { + margin-top: 3em; + padding: 1em; + height: 7.6em; + position: absolute; + right: 1em; +} + +.sub-header { + form { + p { + margin-bottom: 0.75em; } } } diff --git a/app/assets/stylesheets/darkswarm/_shop-popovers.css.scss b/app/assets/stylesheets/darkswarm/_shop-popovers.css.scss index c1a4c8ffe3..d233284767 100644 --- a/app/assets/stylesheets/darkswarm/_shop-popovers.css.scss +++ b/app/assets/stylesheets/darkswarm/_shop-popovers.css.scss @@ -1,31 +1,6 @@ @import "mixins"; @import "branding"; -// .darkswarm -// product - -ordercycle { - .joyride-tip-guide { - background-color: $clr-brick; - - .joyride-nub.right { - border-color: $clr-brick !important; - border-top-color: transparent !important; - border-right-color: transparent !important; - border-bottom-color: transparent !important; - } - - p { - margin: 0; - font-weight: 700; - } - - @media all and (max-width: 768px) { - z-index: 10; - } - } -} - // Pop over // Foundation overrides .joyride-tip-guide.price_breakdown { diff --git a/app/assets/stylesheets/darkswarm/active_table_search.css.scss b/app/assets/stylesheets/darkswarm/active_table_search.css.scss index 4159126538..b934116cdc 100644 --- a/app/assets/stylesheets/darkswarm/active_table_search.css.scss +++ b/app/assets/stylesheets/darkswarm/active_table_search.css.scss @@ -27,7 +27,7 @@ } products .filter-box { - background: #f7f7f7; + background: $grey-050; } .filter-box { diff --git a/app/assets/stylesheets/darkswarm/branding.css.scss b/app/assets/stylesheets/darkswarm/branding.css.scss index 55401e0f24..b8ab72349c 100644 --- a/app/assets/stylesheets/darkswarm/branding.css.scss +++ b/app/assets/stylesheets/darkswarm/branding.css.scss @@ -1,5 +1,7 @@ $ofn-brand: #f27052; +$distributor-header-shadow: 0 1px 0 rgba(0, 0, 0, 0.05), 0 8px 6px -6px rgba(0, 0, 0, 0.2); + // e.g. australia, uk, norway specific color $ofn-grey: #808184; @@ -39,6 +41,8 @@ $light-grey-transparency: rgba(0, 0, 0, .1); $black: #000; $white: #fff; +$grey-050: #f7f7f7; + $grey-400: #bbb; $grey-500: #999; $grey-600: #777; diff --git a/app/assets/stylesheets/darkswarm/checkout.css.scss b/app/assets/stylesheets/darkswarm/checkout.css.scss index 458fd24d5e..2e1a2a528c 100644 --- a/app/assets/stylesheets/darkswarm/checkout.css.scss +++ b/app/assets/stylesheets/darkswarm/checkout.css.scss @@ -44,7 +44,7 @@ checkout { h5 { margin: 0; padding: 0.65em; - background: #f7f7f7; + background: $grey-050; .label { font-size: 1em; @@ -109,9 +109,4 @@ checkout { } } } - - .error { - color: #c82020; - } } - diff --git a/app/assets/stylesheets/darkswarm/distributor_header.css.scss b/app/assets/stylesheets/darkswarm/distributor_header.css.scss new file mode 100644 index 0000000000..8e3fdc2a9b --- /dev/null +++ b/app/assets/stylesheets/darkswarm/distributor_header.css.scss @@ -0,0 +1,52 @@ +@import 'typography'; + +section { + :not(shop) navigation { + box-shadow: $distributor-header-shadow; + } +} + +.darkswarm navigation { + display: block; + background: $white; + position: relative; + z-index: 2; + + .details { + box-sizing: border-box; + display: block; + min-height: 150px; + padding: 30px 0 0; + position: relative; + + select { + width: 200px; + } + + img { + display: block; + height: 100px; + width: 100px; + margin-right: 12px; + } + + location { + @include headingFont; + } + + @media all and (max-width: 768px) { + location, location + small { + display: block; + } + } + + #distributor_title h3 { + margin-top: 0; + padding-top: 0.45em; + + @media all and (max-width: 768px) { + margin-bottom: 8px; + } + } + } +} diff --git a/app/assets/stylesheets/darkswarm/shop_tabs.css.scss b/app/assets/stylesheets/darkswarm/shop_tabs.css.scss index 40007e2b6a..7eaf76afeb 100644 --- a/app/assets/stylesheets/darkswarm/shop_tabs.css.scss +++ b/app/assets/stylesheets/darkswarm/shop_tabs.css.scss @@ -3,11 +3,11 @@ @import "branding"; // Tabs styling -.tabset-ctrl#shop-tabs { +#shop-tabs { .tab-buttons { color: $dark-grey; - box-shadow: 0 1px 0 rgba(0,0,0,0.05), 0 8px 6px -6px rgba(0, 0, 0, 0.2); + box-shadow: $distributor-header-shadow; .columns { display: flex; @@ -23,7 +23,7 @@ } } - .tab { + .page { text-align: center; border-top: 4px solid transparent; display: inline-block; @@ -46,7 +46,7 @@ padding: 1em 2em; border: none; - &:hover, &:focus, &:active { + &:hover, &:active { color: $teal-500; } @@ -75,7 +75,7 @@ // content revealed in accordion - .tab-view { + .page-view { margin-bottom: 5em; background: none; border: none; diff --git a/app/controllers/admin/bulk_line_items_controller.rb b/app/controllers/admin/bulk_line_items_controller.rb index dba7bd9bef..5437be7c45 100644 --- a/app/controllers/admin/bulk_line_items_controller.rb +++ b/app/controllers/admin/bulk_line_items_controller.rb @@ -4,18 +4,17 @@ module Admin # def index order_params = params[:q].andand.delete :order + orders = order_permissions.editable_orders.ransack(order_params).result - order_permissions = ::Permissions::Order.new(spree_current_user) - orders = order_permissions. - editable_orders.ransack(order_params).result - - line_items = order_permissions. + @line_items = order_permissions. editable_line_items.where(order_id: orders). includes(variant: { option_values: :option_type }). ransack(params[:q]).result. reorder('spree_line_items.order_id ASC, spree_line_items.id ASC') - render_as_json line_items + @line_items = @line_items.page(page).per(params[:per_page]) if using_pagination? + + render json: { line_items: serialized_line_items, pagination: pagination_data } end # PUT /admin/bulk_line_items/:id.json @@ -65,6 +64,12 @@ module Admin Api::Admin::LineItemSerializer end + def serialized_line_items + ActiveModel::ArraySerializer.new( + @line_items, each_serializer: serializer(nil) + ) + end + def authorize_update! authorize! :update, order authorize! :read, order @@ -77,5 +82,28 @@ module Admin def line_item_params params.require(:line_item).permit(:price, :quantity, :final_weight_volume) end + + def order_permissions + ::Permissions::Order.new(spree_current_user) + end + + def using_pagination? + params[:per_page] + end + + def pagination_data + return unless using_pagination? + + { + results: @line_items.total_count, + pages: @line_items.num_pages, + page: page.to_i, + per_page: params[:per_page].to_i + } + end + + def page + params[:page] || 1 + end end end diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index 6198497e98..332d939f27 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -32,6 +32,12 @@ module Admin end end + def edit + @object = Enterprise.where(permalink: params[:id]). + includes(users: [:ship_address, :bill_address]).first + super + end + def welcome render layout: "spree/layouts/bare_admin" end @@ -172,12 +178,14 @@ module Admin end def load_methods_and_fees + enterprise_payment_methods = @enterprise.payment_methods.to_a + enterprise_shipping_methods = @enterprise.shipping_methods.to_a # rubocop:disable Style/TernaryParentheses @payment_methods = Spree::PaymentMethod.managed_by(spree_current_user).sort_by! do |pm| - [(@enterprise.payment_methods.include? pm) ? 0 : 1, pm.name] + [(enterprise_payment_methods.include? pm) ? 0 : 1, pm.name] end @shipping_methods = Spree::ShippingMethod.managed_by(spree_current_user).sort_by! do |sm| - [(@enterprise.shipping_methods.include? sm) ? 0 : 1, sm.name] + [(enterprise_shipping_methods.include? sm) ? 0 : 1, sm.name] end # rubocop:enable Style/TernaryParentheses diff --git a/app/controllers/api/customers_controller.rb b/app/controllers/api/customers_controller.rb index 2d72513982..99c5834578 100644 --- a/app/controllers/api/customers_controller.rb +++ b/app/controllers/api/customers_controller.rb @@ -1,5 +1,5 @@ module Api - class CustomersController < BaseController + class CustomersController < Api::BaseController skip_authorization_check only: :index def index diff --git a/app/controllers/api/enterprise_attachment_controller.rb b/app/controllers/api/enterprise_attachment_controller.rb index fe8f47469b..645a5c092c 100644 --- a/app/controllers/api/enterprise_attachment_controller.rb +++ b/app/controllers/api/enterprise_attachment_controller.rb @@ -1,7 +1,7 @@ require 'api/admin/enterprise_serializer' module Api - class EnterpriseAttachmentController < BaseController + class EnterpriseAttachmentController < Api::BaseController class MissingImplementationError < StandardError; end class UnknownEnterpriseAuthorizationActionError < StandardError; end diff --git a/app/controllers/api/enterprise_fees_controller.rb b/app/controllers/api/enterprise_fees_controller.rb index 9d0fda0d05..c966efa7cc 100644 --- a/app/controllers/api/enterprise_fees_controller.rb +++ b/app/controllers/api/enterprise_fees_controller.rb @@ -1,5 +1,5 @@ module Api - class EnterpriseFeesController < BaseController + class EnterpriseFeesController < Api::BaseController respond_to :json def destroy diff --git a/app/controllers/api/logos_controller.rb b/app/controllers/api/logos_controller.rb index f3e7934724..0c4b4c2f45 100644 --- a/app/controllers/api/logos_controller.rb +++ b/app/controllers/api/logos_controller.rb @@ -1,5 +1,5 @@ module Api - class LogosController < EnterpriseAttachmentController + class LogosController < Api::EnterpriseAttachmentController private def attachment_name diff --git a/app/controllers/api/order_cycles_controller.rb b/app/controllers/api/order_cycles_controller.rb index 9e598caa1c..59138ec917 100644 --- a/app/controllers/api/order_cycles_controller.rb +++ b/app/controllers/api/order_cycles_controller.rb @@ -1,5 +1,5 @@ module Api - class OrderCyclesController < BaseController + class OrderCyclesController < Api::BaseController include EnterprisesHelper respond_to :json diff --git a/app/controllers/api/orders_controller.rb b/app/controllers/api/orders_controller.rb index 3be0910f10..c011db44ec 100644 --- a/app/controllers/api/orders_controller.rb +++ b/app/controllers/api/orders_controller.rb @@ -1,5 +1,5 @@ module Api - class OrdersController < BaseController + class OrdersController < Api::BaseController def show authorize! :read, order render json: order, serializer: Api::OrderDetailedSerializer, current_order: order diff --git a/app/controllers/api/product_images_controller.rb b/app/controllers/api/product_images_controller.rb index a8706f6458..e7551aeea7 100644 --- a/app/controllers/api/product_images_controller.rb +++ b/app/controllers/api/product_images_controller.rb @@ -1,5 +1,5 @@ module Api - class ProductImagesController < BaseController + class ProductImagesController < Api::BaseController respond_to :json def update_product_image diff --git a/app/controllers/api/promo_images_controller.rb b/app/controllers/api/promo_images_controller.rb index 0e79ebdb93..9cdb799931 100644 --- a/app/controllers/api/promo_images_controller.rb +++ b/app/controllers/api/promo_images_controller.rb @@ -1,5 +1,5 @@ module Api - class PromoImagesController < EnterpriseAttachmentController + class PromoImagesController < Api::EnterpriseAttachmentController private def attachment_name diff --git a/app/controllers/base_controller.rb b/app/controllers/base_controller.rb index b01b5b002e..dab3eb6752 100644 --- a/app/controllers/base_controller.rb +++ b/app/controllers/base_controller.rb @@ -29,17 +29,19 @@ class BaseController < ApplicationController return end - @order_cycles = OrderCycle.with_distributor(@distributor).active - .order(@distributor.preferred_shopfront_order_cycle_order) + @order_cycles = Shop::OrderCyclesList.new(@distributor, current_customer).call - applicator = OpenFoodNetwork::TagRuleApplicator.new(@distributor, - "FilterOrderCycles", - current_customer.andand.tag_list) - applicator.filter!(@order_cycles) + set_order_cycle + end - # And default to the only order cycle if there's only the one - if @order_cycles.count == 1 - current_order(true).set_order_cycle! @order_cycles.first - end + # Default to the only order cycle if there's only one + # + # Here we need to use @order_cycles.size not @order_cycles.count + # because OrderCyclesList returns a modified ActiveRecord::Relation + # and these modifications are not seen if it is reloaded with count + def set_order_cycle + return if @order_cycles.size != 1 + + current_order(true).set_order_cycle! @order_cycles.first end end diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 0566ed92f6..d09574cdcf 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -53,9 +53,8 @@ class CheckoutController < Spree::StoreController rescue Spree::Core::GatewayError => e rescue_from_spree_gateway_error(e) rescue StandardError => e - Bugsnag.notify(e) flash[:error] = I18n.t("checkout.failed") - update_failed + update_failed(e) end # Clears the cached order. Required for #current_order to return a new order @@ -165,7 +164,7 @@ class CheckoutController < Spree::StoreController checkout_succeeded redirect_to(order_path(@order)) && return else - flash[:error] = order_workflow_error + flash[:error] = order_error checkout_failed end end @@ -180,7 +179,6 @@ class CheckoutController < Spree::StoreController next if advance_order_state(@order) - flash[:error] = order_workflow_error return update_failed end @@ -205,7 +203,7 @@ class CheckoutController < Spree::StoreController false end - def order_workflow_error + def order_error if @order.errors.present? @order.errors.full_messages.to_sentence else @@ -218,7 +216,7 @@ class CheckoutController < Spree::StoreController checkout_succeeded update_succeeded_response else - update_failed + update_failed(RuntimeError.new("Order not complete after the checkout workflow")) end end @@ -244,7 +242,10 @@ class CheckoutController < Spree::StoreController end end - def update_failed + def update_failed(error = RuntimeError.new(order_error)) + Bugsnag.notify(error) + + flash[:error] = order_error if flash.empty? checkout_failed update_failed_response end diff --git a/app/controllers/enterprises_controller.rb b/app/controllers/enterprises_controller.rb index 1a6de50f66..c3c2004ebc 100644 --- a/app/controllers/enterprises_controller.rb +++ b/app/controllers/enterprises_controller.rb @@ -96,8 +96,8 @@ class EnterprisesController < BaseController end def reset_order_cycle(order, distributor) - order_cycle_options = OrderCycle.active.with_distributor(distributor) - order.order_cycle = order_cycle_options.first if order_cycle_options.count == 1 + order_cycles = Shop::OrderCyclesList.new(distributor, current_customer).call + order.order_cycle = order_cycles.first if order_cycles.size == 1 end def shop_order_cycles diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index f8268cf464..0a39b00d9b 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -5,12 +5,23 @@ class HomeController < BaseController def index if ContentConfig.home_show_stats - @num_distributors = Enterprise.is_distributor.activated.visible.count - @num_producers = Enterprise.is_primary_producer.activated.visible.count - @num_users = Spree::Order.complete.count('DISTINCT user_id') - @num_orders = Spree::Order.complete.count + @num_distributors = cached_count('distributors', Enterprise.is_distributor.activated.visible) + @num_producers = cached_count('producers', Enterprise.is_primary_producer.activated.visible) + @num_orders = cached_count('orders', Spree::Order.complete) + @num_users = cached_count( + 'users', Spree::Order.complete.select('DISTINCT spree_orders.user_id') + ) end end def sell; end + + private + + # Cache the value of the query count for 24 hours + def cached_count(key, query) + Rails.cache.fetch("home_stats_count_#{key}", expires_in: 1.day, race_condition_ttl: 10) do + query.count + end + end end diff --git a/app/controllers/producers_controller.rb b/app/controllers/producers_controller.rb index 0f45546fde..a5f4752c49 100644 --- a/app/controllers/producers_controller.rb +++ b/app/controllers/producers_controller.rb @@ -8,7 +8,7 @@ class ProducersController < BaseController .activated .visible .is_primary_producer - .includes(address: :state) + .includes(address: [:state, :country]) .includes(:properties) .includes(supplied_products: :properties) .all diff --git a/app/controllers/shops_controller.rb b/app/controllers/shops_controller.rb index 611baa11b8..d4f350b47f 100644 --- a/app/controllers/shops_controller.rb +++ b/app/controllers/shops_controller.rb @@ -8,7 +8,7 @@ class ShopsController < BaseController .activated .visible .is_distributor - .includes(address: :state) + .includes(address: [:state, :country]) .includes(:properties) .includes(supplied_products: :properties) .all diff --git a/app/controllers/spree/admin/orders_controller.rb b/app/controllers/spree/admin/orders_controller.rb index 4858b98d7e..2e7701a614 100644 --- a/app/controllers/spree/admin/orders_controller.rb +++ b/app/controllers/spree/admin/orders_controller.rb @@ -113,7 +113,10 @@ module Spree end def load_order - @order = Order.find_by_number!(params[:id], include: :adjustments) if params[:id] + if params[:id] + @order = Order.includes(:adjustments, :shipments, line_items: :adjustments). + find_by_number!(params[:id]) + end authorize! action, @order end @@ -132,7 +135,7 @@ module Spree def load_distribution_choices @shops = Enterprise.is_distributor.managed_by(spree_current_user).by_name - ocs = OrderCycle.managed_by(spree_current_user) + ocs = OrderCycle.includes(:suppliers, :distributors).managed_by(spree_current_user) @order_cycles = ocs.soonest_closing + ocs.soonest_opening + ocs.closed + diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 0e66cde722..2e03e68bc0 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,6 +1,4 @@ module ApplicationHelper - #include FoundationRailsHelper::FlashHelper - def feature?(feature) OpenFoodNetwork::FeatureToggle.enabled? feature end diff --git a/app/helpers/injection_helper.rb b/app/helpers/injection_helper.rb index 9b06121df4..f857cbf2a3 100644 --- a/app/helpers/injection_helper.rb +++ b/app/helpers/injection_helper.rb @@ -3,10 +3,10 @@ require 'open_food_network/enterprise_injection_data' module InjectionHelper include SerializerHelper - def inject_enterprises(enterprises = Enterprise.activated.includes(address: :state).all) + def inject_enterprises(enterprises = nil) inject_json_ams( "enterprises", - enterprises, + enterprises || default_enterprise_query, Api::EnterpriseSerializer, enterprise_injection_data ) @@ -17,7 +17,10 @@ module InjectionHelper inject_json_ams( "groups", - EnterpriseGroup.on_front_page.by_position.select(select_only).includes(address: :state).all, + EnterpriseGroup.on_front_page.by_position.select(select_only). + includes(enterprises: [:shipping_methods, { address: [:state, :country] }], + address: :state). + all, Api::GroupListSerializer ) end @@ -35,13 +38,21 @@ module InjectionHelper inject_json_ams( "enterprises", - Enterprise.activated.visible.select(select_only).includes(address: :state).all, + Enterprise.activated.visible.select(select_only).includes(address: [:state, :country]).all, Api::EnterpriseShopfrontListSerializer ) end def inject_enterprise_and_relatives - inject_json_ams "enterprises", current_distributor.relatives_including_self.activated.includes(address: :state).all, Api::EnterpriseSerializer, enterprise_injection_data + enterprises_and_relatives = current_distributor. + relatives_including_self. + activated. + includes(address: [:state, :country]). + all + + inject_json_ams "enterprises", + enterprises_and_relatives, + Api::EnterpriseSerializer, enterprise_injection_data end def inject_group_enterprises @@ -138,6 +149,10 @@ module InjectionHelper private + def default_enterprise_query + Enterprise.activated.includes(address: [:state, :country]).all + end + def enterprise_injection_data @enterprise_injection_data ||= OpenFoodNetwork::EnterpriseInjectionData.new { data: @enterprise_injection_data } diff --git a/app/helpers/order_cycles_helper.rb b/app/helpers/order_cycles_helper.rb index 8eb32e7d66..d5184a0436 100644 --- a/app/helpers/order_cycles_helper.rb +++ b/app/helpers/order_cycles_helper.rb @@ -47,17 +47,6 @@ module OrderCyclesHelper end end - def order_cycle_options - @order_cycles. - with_distributor(current_distributor). - map { |oc| [order_cycle_close_to_s(oc.orders_close_at), oc.id] } - end - - def order_cycle_close_to_s(orders_close_at) - "%s (%s)" % [orders_close_at.strftime("#{orders_close_at.day.ordinalize} %b"), - distance_of_time_in_words_to_now(orders_close_at)] - end - def active_order_cycle_for_distributor?(_distributor) OrderCycle.active.with_distributor(@distributor).present? end diff --git a/app/helpers/shop_helper.rb b/app/helpers/shop_helper.rb index 29cb11b9bf..5aae96e101 100644 --- a/app/helpers/shop_helper.rb +++ b/app/helpers/shop_helper.rb @@ -35,6 +35,10 @@ module ShopHelper ].select{ |tab| tab[:show] } end + def shop_tab_names + shop_tabs.map { |tab| tab[:name] } + end + def show_home_tab? require_customer? || current_distributor.preferred_shopfront_message.present? end diff --git a/app/helpers/spree/base_helper_decorator.rb b/app/helpers/spree/base_helper_decorator.rb index 67ea0a711d..0125347d58 100644 --- a/app/helpers/spree/base_helper_decorator.rb +++ b/app/helpers/spree/base_helper_decorator.rb @@ -5,5 +5,21 @@ module Spree def variant_options(v, _options = {}) v.options_text end + + # Overriden to eager-load :states + def available_countries + checkout_zone = Zone.find_by_name(Spree::Config[:checkout_zone]) + + countries = if checkout_zone && checkout_zone.kind == 'country' + checkout_zone.country_list + else + Country.includes(:states).all + end + + countries.collect do |country| + country.name = Spree.t(country.iso, scope: 'country_names', default: country.name) + country + end.sort { |a, b| a.name <=> b.name } + end end end diff --git a/app/models/calculator/weight.rb b/app/models/calculator/weight.rb index 60992e3e48..bb1f70c030 100644 --- a/app/models/calculator/weight.rb +++ b/app/models/calculator/weight.rb @@ -53,6 +53,8 @@ module Calculator # Customer ends up getting 350mL (line_item.final_weight_volume) of wine # that represent 2.8 (quantity_implied_in_final_weight_volume) glasses of wine def quantity_implied_in_final_weight_volume(line_item) + return line_item.quantity if line_item.variant.unit_value.to_f.zero? + (1.0 * line_item.final_weight_volume / line_item.variant.unit_value).round(3) end diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index 37637f7564..a663825433 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -32,6 +32,10 @@ Spree::LineItem.class_eval do end } + scope :in_orders, lambda { |orders| + where(order_id: orders) + } + # Find line items that are from order sorted by variant name and unit value scope :sorted_by_name_and_unit_value, -> { joins(variant: :product). diff --git a/app/models/spree/product_set.rb b/app/models/spree/product_set.rb index c1d387c787..5de24ddc52 100644 --- a/app/models/spree/product_set.rb +++ b/app/models/spree/product_set.rb @@ -1,6 +1,6 @@ class Spree::ProductSet < ModelSet def initialize(attributes = {}) - super(Spree::Product, [], attributes, proc { |attrs| attrs[:product_id].blank? }) + super(Spree::Product, [], attributes) end def save @@ -34,11 +34,9 @@ class Spree::ProductSet < ModelSet split_taxon_ids!(attributes) product = find_model(@collection, attributes[:id]) - if product.nil? - @klass.new(attributes).save unless @reject_if.andand.call(attributes) - else - update_product(product, attributes) - end + return if product.nil? + + update_product(product, attributes) end def split_taxon_ids!(attributes) diff --git a/app/models/stock/package.rb b/app/models/stock/package.rb index 75f6b30261..eada3741c1 100644 --- a/app/models/stock/package.rb +++ b/app/models/stock/package.rb @@ -24,8 +24,10 @@ module Stock # # @return [Array] def shipping_methods - super.delete_if do |shipping_method| - !ships_with?(order.distributor, shipping_method) + available_shipping_methods = super.to_a + + available_shipping_methods.keep_if do |shipping_method| + ships_with?(order.distributor.shipping_methods.to_a, shipping_method) end end @@ -33,11 +35,11 @@ module Stock # Checks whether the given distributor provides the specified shipping method # - # @param distributor [Spree::Enterprise] + # @param shipping_methods [Array] # @param shipping_method [Spree::ShippingMethod] # @return [Boolean] - def ships_with?(distributor, shipping_method) - distributor.shipping_methods.include?(shipping_method) + def ships_with?(shipping_methods, shipping_method) + shipping_methods.include?(shipping_method) end end end diff --git a/app/serializers/api/cached_enterprise_serializer.rb b/app/serializers/api/cached_enterprise_serializer.rb index 26a6f351d8..05677720db 100644 --- a/app/serializers/api/cached_enterprise_serializer.rb +++ b/app/serializers/api/cached_enterprise_serializer.rb @@ -107,7 +107,7 @@ module Api end def active - data.active_distributors.andand.include? enterprise + data.active_distributor_ids.andand.include? enterprise.id end # Map svg icons. diff --git a/app/serializers/api/uncached_enterprise_serializer.rb b/app/serializers/api/uncached_enterprise_serializer.rb index bad8808533..1bbae872ba 100644 --- a/app/serializers/api/uncached_enterprise_serializer.rb +++ b/app/serializers/api/uncached_enterprise_serializer.rb @@ -9,7 +9,7 @@ module Api end def active - options[:data].active_distributors.andand.include? object + options[:data].active_distributor_ids.andand.include? object.id end end end diff --git a/app/services/permissions/order.rb b/app/services/permissions/order.rb index 5e95ba92c8..ea5c4c2bfa 100644 --- a/app/services/permissions/order.rb +++ b/app/services/permissions/order.rb @@ -2,24 +2,28 @@ require 'open_food_network/permissions' module Permissions class Order - def initialize(user) + def initialize(user, search_params = nil) @user = user @permissions = OpenFoodNetwork::Permissions.new(@user) + @search_params = search_params end # Find orders that the user can see def visible_orders - Spree::Order. + orders = Spree::Order. with_line_items_variants_and_products_outer. where(visible_orders_where_values) + + filtered_orders(orders) end # Any orders that the user can edit def editable_orders - Spree::Order.where( - managed_orders_where_values. - or(coordinated_orders_where_values) - ) + orders = Spree::Order. + where(managed_orders_where_values. + or(coordinated_orders_where_values)) + + filtered_orders(orders) end def visible_line_items @@ -35,6 +39,18 @@ module Permissions private + attr_reader :search_params + + def filtered_orders(orders) + return orders unless filter_orders? + + orders.complete.not_state(:canceled).search(search_params).result + end + + def filter_orders? + search_params.present? + end + def visible_orders_where_values # Grouping keeps the 2 where clauses from produced_orders_where_values inside parentheses # This way it makes the OR work between the 3 types of orders: diff --git a/app/services/shop/order_cycles_list.rb b/app/services/shop/order_cycles_list.rb new file mode 100644 index 0000000000..d4ee5e07c3 --- /dev/null +++ b/app/services/shop/order_cycles_list.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +# Lists available order cycles for a given customer in a given distributor +module Shop + class OrderCyclesList + def initialize(distributor, customer) + @distributor = distributor + @customer = customer + end + + def call + order_cycles = OrderCycle.with_distributor(@distributor).active + .order(@distributor.preferred_shopfront_order_cycle_order) + + apply_tag_rules!(order_cycles) + end + + private + + # order_cycles is a ActiveRecord::Relation that is modified with reject in the TagRuleApplicator + # If this relation is reloaded (for example by calling count on it), the modifications are lost + def apply_tag_rules!(order_cycles) + applicator = OpenFoodNetwork::TagRuleApplicator.new(@distributor, + "FilterOrderCycles", + @customer.andand.tag_list) + applicator.filter!(order_cycles) + + order_cycles + end + end +end diff --git a/app/services/variants_stock_levels.rb b/app/services/variants_stock_levels.rb index 69dbc49dee..73f6e68278 100644 --- a/app/services/variants_stock_levels.rb +++ b/app/services/variants_stock_levels.rb @@ -1,45 +1,46 @@ # Report the stock levels of: # - all variants in the order # - all requested variant ids +require 'open_food_network/scope_variant_to_hub' + class VariantsStockLevels def call(order, requested_variant_ids) variant_stock_levels = variant_stock_levels(order.line_items) - # Variants are not scoped here and so the stock levels reported are incorrect - # See cart_controller_spec for more details and #3222 order_variant_ids = variant_stock_levels.keys missing_variant_ids = requested_variant_ids - order_variant_ids missing_variant_ids.each do |variant_id| - variant = Spree::Variant.find(variant_id) + variant = scoped_variant(order.distributor, Spree::Variant.find(variant_id)) variant_stock_levels[variant_id] = { quantity: 0, max_quantity: 0, on_hand: variant.on_hand, on_demand: variant.on_demand } end - # The code above is most probably dead code, this bugsnag notification will confirm it - notify_bugsnag(order, requested_variant_ids, order_variant_ids) if missing_variant_ids.present? - variant_stock_levels end private - def notify_bugsnag(order, requested_variant_ids, order_variant_ids) - error_msg = "VariantsStockLevels.call with variants in the request that are not in the order" - Bugsnag.notify(RuntimeError.new(error_msg), - requested_variant_ids: requested_variant_ids.as_json, - order_variant_ids: order_variant_ids.as_json, - order: order.as_json, - line_items: order.line_items.as_json) - end - def variant_stock_levels(line_items) Hash[ line_items.map do |line_item| - [line_item.variant.id, + variant = scoped_variant(line_item.order.distributor, line_item.variant) + + [variant.id, { quantity: line_item.quantity, max_quantity: line_item.max_quantity, - on_hand: line_item.variant.on_hand, - on_demand: line_item.variant.on_demand }] + on_hand: variant.on_hand, + on_demand: variant.on_demand }] end ] end + + def scoped_variant(distributor, variant) + return variant if distributor.blank? + + scoper(distributor).scope(variant) + variant + end + + def scoper(distributor) + @scoper ||= OpenFoodNetwork::ScopeVariantToHub.new(distributor) + end end diff --git a/app/views/checkout/_form.html.haml b/app/views/checkout/_form.html.haml index 901fe64a00..9a705ef4b5 100644 --- a/app/views/checkout/_form.html.haml +++ b/app/views/checkout/_form.html.haml @@ -3,7 +3,7 @@ = inject_available_payment_methods = inject_saved_credit_cards -= f_form_for current_order, += form_for current_order, html: {name: "checkout", id: "checkout_form", novalidate: true, diff --git a/app/views/checkout/_shipping.html.haml b/app/views/checkout/_shipping.html.haml index c137f2cdee..1e50dc33f8 100644 --- a/app/views/checkout/_shipping.html.haml +++ b/app/views/checkout/_shipping.html.haml @@ -52,7 +52,8 @@ .row .small-12.columns - = f.text_area :special_instructions, label: t(:checkout_instructions), size: "60x4", "ng-model" => "order.special_instructions" + %label{ for: 'order_special_instructions'}= t(:checkout_instructions) + = f.text_area :special_instructions, size: "60x4", "ng-model" => "order.special_instructions" .row .small-12.columns.text-right diff --git a/app/views/checkout/edit.html.haml b/app/views/checkout/edit.html.haml index 312b7b5a79..9d85b3e8df 100644 --- a/app/views/checkout/edit.html.haml +++ b/app/views/checkout/edit.html.haml @@ -7,7 +7,6 @@ .darkswarm.footer-pad - content_for :order_cycle_form do - %closing = t :checkout_now %p @@ -15,16 +14,23 @@ %strong = pickup_time current_order_cycle + - content_for :ordercycle_sidebar do + .show-for-large-up.large-4.columns + = render partial: "shopping_shared/order_cycles" + = render partial: "shopping_shared/header" + .sub-header.show-for-medium-down + = render partial: "shopping_shared/order_cycles" + %accordion{"close-others" => "false"} %checkout.row{"ng-controller" => "CheckoutCtrl"} - .small-12.medium-8.large-9.columns + .small-12.medium-8.columns - unless spree_current_user = render partial: "checkout/authentication" %div{"ng-show" => "enabled", "ng-controller" => "AccordionCtrl"} = render partial: "checkout/form" - .small-12.medium-4.large-3.columns + .small-12.medium-4.columns = render partial: "checkout/summary" diff --git a/app/views/enterprises/shop.html.haml b/app/views/enterprises/shop.html.haml index e08625d0df..7f98960b33 100644 --- a/app/views/enterprises/shop.html.haml +++ b/app/views/enterprises/shop.html.haml @@ -38,6 +38,10 @@ - if oc_select_options.count > 1 %option{value: "", disabled: "", selected: ""}= t :shopping_oc_select + - content_for :ordercycle_sidebar do + .show-for-large-up.large-4.columns + = render partial: "shopping_shared/order_cycles" + = render partial: "shopping_shared/header" = render partial: "shopping_shared/tabs" diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 76a83fd734..e8318faef9 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -34,10 +34,10 @@ select: "select(\'map\')"} .map-container %map{"ng-if" => "(isActive(\'/map\') && (mapShowed = true)) || mapShowed"} - %google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"} + %ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"} %map-osm-tiles %map-search - %markers{models: "mapMarkers", fit: "true", + %ui-gmap-markers{models: "mapMarkers", fit: "true", coords: "'self'", icon: "'icon'", click: "'reveal'"} %tab{heading: t(:groups_about), diff --git a/app/views/layouts/_bugsnag_js.html.haml b/app/views/layouts/_bugsnag_js.html.haml new file mode 100644 index 0000000000..b9f3f5a736 --- /dev/null +++ b/app/views/layouts/_bugsnag_js.html.haml @@ -0,0 +1,10 @@ +- bugsnag_js_key = ENV['BUGSNAG_JS_KEY'] || ENV['BUGSNAG_API_KEY'] +- if bugsnag_js_key.present? + %script{src: "//d2wy8f7a9ursnm.cloudfront.net/v6/bugsnag.min.js"} + :javascript + window.bugsnagClient = bugsnag({ + apiKey: "#{bugsnag_js_key}", + beforeSend: function (report) { + report.app.releaseStage = "#{Rails.env}" + } + }); diff --git a/app/views/layouts/darkswarm.html.haml b/app/views/layouts/darkswarm.html.haml index 317f40907d..fa42b8f745 100644 --- a/app/views/layouts/darkswarm.html.haml +++ b/app/views/layouts/darkswarm.html.haml @@ -37,6 +37,7 @@ #footer %loading + = render "layouts/bugsnag_js" %script{:src => "https://js.stripe.com/v3/", :type => "text/javascript"} %script{src: "//maps.googleapis.com/maps/api/js?libraries=places,geometry#{ ENV['GOOGLE_MAPS_API_KEY'] ? '&key=' + ENV['GOOGLE_MAPS_API_KEY'] : ''} "} = javascript_include_tag "darkswarm/all" diff --git a/app/views/map/index.html.haml b/app/views/map/index.html.haml index 48e05d2d0a..294fa45f8e 100644 --- a/app/views/map/index.html.haml +++ b/app/views/map/index.html.haml @@ -6,10 +6,10 @@ .map-container{"fill-vertical" => true} %map{"ng-controller" => "MapCtrl"} - %google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"} + %ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"} %map-osm-tiles %map-search - %markers{models: "OfnMap.enterprises", fit: "true", + %ui-gmap-markers{models: "OfnMap.enterprises", fit: "true", coords: "'self'", icon: "'icon'", click: "'reveal'"} .map-footer diff --git a/app/views/shopping_shared/_header.html.haml b/app/views/shopping_shared/_header.html.haml index 03661a22ea..e718e9247c 100644 --- a/app/views/shopping_shared/_header.html.haml +++ b/app/views/shopping_shared/_header.html.haml @@ -10,5 +10,4 @@ = distributor.name %location= distributor.address.city - .show-for-large-up.large-4.columns - = render partial: "shopping_shared/order_cycles" + = yield :ordercycle_sidebar diff --git a/app/views/shopping_shared/_tabs.html.haml b/app/views/shopping_shared/_tabs.html.haml index 434c5070a2..a703851127 100644 --- a/app/views/shopping_shared/_tabs.html.haml +++ b/app/views/shopping_shared/_tabs.html.haml @@ -3,12 +3,12 @@ - shop_tabs.each do |tab| = render "shopping_shared/tabs/#{tab[:name]}" - .tabset-ctrl#shop-tabs{ navigate: 'true', alwaysopen: 'true', selected: shop_tabs.first[:name], prefix: 'shop', ng: { cloak: true } } + #shop-tabs{ ng: { controller: "PageSelectionCtrl", init: "whitelistPages(#{shop_tab_names.to_json})", cloak: true } } .tab-buttons .row .columns.small-12.large-8 - shop_tabs.each do |tab| - .tab{ id: "tab_#{tab[:name]}", name: tab[:name] } - %a{ href: 'javascript:void(0)' }=tab[:title] + .page{ "ng-class" => "{ selected: selectedPage() == '#{tab[:name]}' }" } + %a{ href: "##{tab[:name]}" }=tab[:title] - .tab-view + .page-view{ ng: {include: "'shop/' + selectedPage() + '.html'" } } diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index 1fc72e9a9b..4eb6a67aa0 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -20,28 +20,28 @@ %label{ :for => 'start_date_filter' } = t("admin.start_date") %br - %input{ :class => "two columns alpha", :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datepicker' => "startDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()' } + %input{ :class => "two columns alpha", :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datepicker' => "startDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()', 'ng-model-options' => '{ debounce: 1000 }' } .date_filter{ :class => "two columns" } %label{ :for => 'end_date_filter' } = t("admin.end_date") %br - %input{ :class => "two columns alpha", :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datepicker' => "endDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()' } + %input{ :class => "two columns alpha", :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datepicker' => "endDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()', 'ng-model-options' => '{ debounce: 1000 }' } .one.column   .filter_select{ :class => "three columns" } %label{ :for => 'supplier_filter' } = t("admin.producer") %br - %input#supplier_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'suppliers', blank: "{ id: 0, name: '#{t(:all)}' }", ng: { model: 'supplierFilter' } } + %input#supplier_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'suppliers', placeholder: "#{t(:all)}", blank: "{ id: '', name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'supplierFilter', change: 'refreshData()' } } .filter_select{ :class => "three columns" } %label{ :for => 'distributor_filter' } = t("admin.shop") %br - %input#distributor_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'distributors', blank: "{ id: 0, name: '#{t(:all)}' }", ng: { model: 'distributorFilter' } } + %input#distributor_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'distributors', placeholder: "#{t(:all)}", blank: "{ id: '', name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'distributorFilter', change: 'refreshData()' } } .filter_select{ :class => "three columns" } %label{ :for => 'order_cycle_filter' } = t("admin.order_cycle") %br - %input#order_cycle_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'orderCycles', blank: "{ id: 0, name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'orderCycleFilter', change: 'refreshData()' } } + %input#order_cycle_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'orderCycles', placeholder: "#{t(:all)}", blank: "{ id: '', name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'orderCycleFilter', change: 'refreshData()' } } .filter_clear{ :class => "two columns omega" } %label{ :for => 'clear_all_filters' } %br @@ -94,7 +94,7 @@ %hr.divider.sixteen.columns.alpha.omega - .controls.sixteen.columns.alpha.omega{ ng: { hide: 'RequestMonitor.loading || lineItems.length == 0' } } + .controls.sixteen.columns.alpha.omega{ ng: { hide: 'RequestMonitor.loading || line_items.length == 0' } } %div.three.columns.alpha %input.fullwidth{ :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } = render 'admin/shared/bulk_actions_dropdown' @@ -157,7 +157,7 @@ = t("admin.orders.bulk_management.ask") %input{ :type => 'checkbox', 'ng-model' => "confirmDelete" } - %tr.line_item{ ng: { repeat: "line_item in filteredLineItems = ( lineItems | filter:quickSearch | selectFilter:supplierFilter:distributorFilter:orderCycleFilter | variantFilter:selectedUnitsProduct:selectedUnitsVariant:sharedResource | orderBy:sorting.predicate:sorting.reverse )", 'class-even' => "'even'", 'class-odd' => "'odd'", attr: { id: "li_{{line_item.id}}" } } } + %tr.line_item{ ng: { repeat: "line_item in filteredLineItems = ( line_items | filter:quickSearch | variantFilter:selectedUnitsProduct:selectedUnitsVariant:sharedResource | orderBy:sorting.predicate:sorting.reverse )", 'class-even' => "'even'", 'class-odd' => "'odd'", attr: { id: "li_{{line_item.id}}" } } } %td.bulk %input{ :type => "checkbox", :name => 'bulk', 'ng-model' => 'line_item.checked', 'ignore-dirty' => true } %td.order_no{ 'ng-show' => 'columns.order_no.visible' } {{ line_item.order.number }} @@ -175,7 +175,7 @@ %span.error{ ng: { bind: 'line_item.errors.quantity' } } %td.max{ 'ng-show' => 'columns.max.visible' } {{ line_item.max_quantity }} %td.final_weight_volume{ 'ng-show' => 'columns.final_weight_volume.visible' } - %input.show-dirty{ :type => 'number', :name => 'final_weight_volume', :id => 'final_weight_volume', ng: { model: "line_item.final_weight_volume", readonly: "unitValueLessThanZero(line_item)", change: "weightAdjustedPrice(line_item)", required: "true", class: '{"update-error": line_item.errors.final_weight_volume}' }, min: 0, 'ng-pattern' => '/[1-9]+/' } + %input.show-dirty{ type: 'number', step: 'any', :name => 'final_weight_volume', :id => 'final_weight_volume', ng: { model: "line_item.final_weight_volume", readonly: "unitValueLessThanZero(line_item)", change: "weightAdjustedPrice(line_item)", required: "true", class: '{"update-error": line_item.errors.final_weight_volume}' }, min: 0, 'ng-pattern' => '/[0-9]*[.]?[0-9]+/' } %span.error{ ng: { bind: 'line_item.errors.final_weight_volume' } } %td.price{ 'ng-show' => 'columns.price.visible' } %input.show-dirty{ :type => 'text', :name => 'price', :id => 'price', :ng => { value: 'line_item.price * line_item.quantity | currency:""', readonly: "true", class: '{"update-error": line_item.errors.price}' } } diff --git a/app/views/spree/admin/orders/index.html.haml b/app/views/spree/admin/orders/index.html.haml index 244b2e8f1c..5359422dd0 100644 --- a/app/views/spree/admin/orders/index.html.haml +++ b/app/views/spree/admin/orders/index.html.haml @@ -84,7 +84,7 @@ %i.error.icon-remove-sign.with-tip{ng: {show: 'rowStatus[order.id] == "error"'}, 'ofn-with-tip' => t('.order_not_updated')} %a.icon_link.with-tip.icon-edit.no-text{'ng-href' => '{{order.edit_path}}', 'data-action' => 'edit', 'ofn-with-tip' => t('.edit')} %div{'ng-if' => 'order.ready_to_ship'} - %button.icon-road.icon_link.with-tip.no-text{'ng-click' => 'shipOrder(order)', 'data-confirm' => t(:are_you_sure), rel: 'nofollow', 'ofn-with-tip' => t('.ship')} + %button.icon-road.icon_link.with-tip.no-text{'ng-click' => 'shipOrder(order)', rel: 'nofollow', 'ofn-with-tip' => t('.ship')} %div{'ng-if' => 'order.ready_to_capture'} %button.icon-capture.icon_link.no-text{'ng-click' => 'capturePayment(order)', rel: 'nofollow', 'ofn-with-tip' => t('.capture')} diff --git a/app/views/spree/admin/orders/invoice.html.haml b/app/views/spree/admin/orders/invoice.html.haml index 982ef43f59..bc2b4dc556 100644 --- a/app/views/spree/admin/orders/invoice.html.haml +++ b/app/views/spree/admin/orders/invoice.html.haml @@ -17,7 +17,7 @@ %td{ :align => "right" } %h4= @order.order_cycle.andand.name %tr{ valign: "top" } - %td{ :align => "left" } + %td{ align: "left", colspan: 3 } %strong= "#{t('.from')}: #{@order.distributor.name}" - if @order.distributor.abn.present? %br @@ -26,31 +26,43 @@ = @order.distributor.address.full_address %br = @order.distributor.contact.email - %td{width: "10%" } + %tr{ valign: "top" } + %td{ colspan: 3 }   - %td{ :align => "right" } - %strong= "#{t('.to')}: #{@order.ship_address.full_name}" + %tr{ valign: "top" } + %td{ align: "left" } + %strong= "#{t('.to')}:" + %br + = @order.bill_address.full_name - if @order.andand.customer.andand.code.present? %br = "#{t('.code')}: #{@order.customer.code}" %br - = @order.ship_address.full_address + = @order.bill_address.full_address %br - if @order.andand.customer.andand.email.present? = "#{@order.customer.email}," = "#{@order.bill_address.phone}" + %td +   + %td{ align: "left", style: "border-left: .1em solid black; padding-left: 1em" } + %strong= "#{t('.shipping')}: #{@order.shipping_method&.name}" + - if @order.shipping_method&.require_ship_address + %br + = @order.ship_address.full_name + %br + = @order.ship_address.full_address + %br + = @order.ship_address.phone + - if @order.special_instructions.present? + %br + %br + %strong= t :customer_instructions + = @order.special_instructions + = render 'spree/admin/orders/invoice_table' -- if @order.special_instructions.present? - %p.callout - %strong - = t :customer_instructions - %p - %em= @order.special_instructions - %p -   - - if @order.distributor.invoice_text.present? %p = @order.distributor.invoice_text diff --git a/app/views/spree/admin/payment_methods/_provider_settings.html.haml b/app/views/spree/admin/payment_methods/_provider_settings.html.haml index 38f2ff06e9..cbf24630b2 100644 --- a/app/views/spree/admin/payment_methods/_provider_settings.html.haml +++ b/app/views/spree/admin/payment_methods/_provider_settings.html.haml @@ -1,4 +1,3 @@ -= @payment_method - case @payment_method - when Spree::Gateway::StripeConnect = render 'stripe_connect' diff --git a/app/views/spree/admin/properties/new.js.erb b/app/views/spree/admin/properties/new.js.erb index d13137c1aa..c508aba3d0 100644 --- a/app/views/spree/admin/properties/new.js.erb +++ b/app/views/spree/admin/properties/new.js.erb @@ -1,2 +1,2 @@ -$("#new_property").html('<%= escape_javascript(render :template => "spree/admin/properties/new", :formats => [:html], :handlers => [:erb]) %>'); +$("#new_property").html('<%= escape_javascript(render :template => "spree/admin/properties/new", :formats => [:html], :handlers => [:haml]) %>'); $("#new_property_link").parent().hide(); diff --git a/app/views/spree/admin/shared/_head.html.haml b/app/views/spree/admin/shared/_head.html.haml index 375830063b..71e3170e59 100644 --- a/app/views/spree/admin/shared/_head.html.haml +++ b/app/views/spree/admin/shared/_head.html.haml @@ -12,6 +12,7 @@ %link{:href => "//fonts.googleapis.com/css?family=Open+Sans:400italic,600italic,400,600&subset=latin,cyrillic,greek,vietnamese", :rel => "stylesheet", :type => "text/css"} = stylesheet_link_tag 'admin/all' += render "layouts/bugsnag_js" = javascript_include_tag 'admin/all' = render "spree/admin/shared/translations" diff --git a/app/views/spree/orders/edit.html.haml b/app/views/spree/orders/edit.html.haml index 56f4e03ef8..f654cfebb1 100644 --- a/app/views/spree/orders/edit.html.haml +++ b/app/views/spree/orders/edit.html.haml @@ -16,8 +16,15 @@ - else = @order.distributor.next_collection_at + - content_for :ordercycle_sidebar do + .show-for-large-up.large-4.columns + = render partial: "shopping_shared/order_cycles" + = render partial: "shopping_shared/header" + .sub-header.show-for-medium-down + = render partial: "shopping_shared/order_cycles" + %fieldset.footer-pad - if @order.line_items.empty? %div.row{"data-hook" => "empty_cart"} diff --git a/app/views/user_passwords/edit.html.haml b/app/views/user_passwords/edit.html.haml index 3042161881..eb1d9df0bc 100644 --- a/app/views/user_passwords/edit.html.haml +++ b/app/views/user_passwords/edit.html.haml @@ -1,4 +1,4 @@ -= f_form_for @spree_user, :as => :spree_user, :url => spree.spree_user_password_path, :method => :put do |f| += form_for @spree_user, :as => :spree_user, :url => spree.spree_user_password_path, :method => :put do |f| = render :partial => 'spree/shared/error_messages', :locals => { :target => @spree_user } %fieldset .row @@ -6,9 +6,11 @@ %legend= t(:change_my_password) .row .small-12.medium-6.large-4.columns.medium-centered.large-centered + %label{ for: 'spree_user_password'}= t(:password) = f.password_field :password .row .small-12.medium-6.large-4.columns.medium-centered.large-centered + %label{ for: 'spree_user_password_confirmation'}= t(:password_confirmation) = f.password_field :password_confirmation = f.hidden_field :reset_password_token .row diff --git a/config/application.yml.example b/config/application.yml.example index 8de7369f42..99b8bf4fe8 100644 --- a/config/application.yml.example +++ b/config/application.yml.example @@ -37,6 +37,9 @@ SMTP_PASSWORD: 'f00d' # MAILS_FROM: hello@example.com # MAIL_BCC: manager@example.com +# Javascript error reporting via Bugsnag. +#BUGSNAG_JS_KEY: "" + # SingleSignOn login for Discourse # # DISCOURSE_SSO_SECRET should be a random string. It must be the same as provided to your Discourse instance. diff --git a/config/locales/ar.yml b/config/locales/ar.yml index d11e100468..b7c5a59b6c 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -19,6 +19,8 @@ ar: shipping_category_id: "نوع الشحن" variant_unit: "وحدة النوع" variant_unit_name: "اسم وحدة النوع" + spree/credit_card: + base: "بطاقة ائتمان" order_cycle: orders_close_at: تاريخ الاغلاق errors: @@ -246,6 +248,8 @@ ar: notes: ملاحظات error: خطأ processing_payment: "معالجة الدفع..." + no_pending_payments: "لا توجد دفعات معلقة" + invalid_payment_state: "حالة الدفع غير صالحة" filter_results: تصفية النتائج quantity: الكمية pick_up: النقل @@ -858,6 +862,11 @@ ar: cancel: "إلغاء" back_to_list: "العودة للقائمة" outgoing: + outgoing: "الصادر" + distributor: "الموزع" + products: "منتجات" + tags: "الاوسمة" + fees: "رسوم" previous: "السابق" save: "حفظ" save_and_back_to_list: "حفظ والعودة إلى القائمة" @@ -1483,6 +1492,7 @@ ar: shopping_oc_closed_description: "يرجى الانتظار حتى تفتح الدورة التالية (أو اتصل بنا مباشرة لمعرفة ما إذا كان يمكننا قبول أي طلبات متأخرة)" shopping_oc_last_closed: "آخر دورة تم إغلاق %{distance_of_time} منذ" shopping_oc_next_open: "تفتح الدورة التالية في %{distance_of_time}" + shopping_oc_select: "اختيار..." shopping_tabs_home: "الصفحة الرئيسية" shopping_tabs_shop: "المتجر" shopping_tabs_about: "حول" @@ -1864,6 +1874,7 @@ ar: headline: "تم الانتهاء !" thanks: "شكرًا لملء تفاصيل %{enterprise}." login: "يمكنك تغيير أو تحديث شركتك في أي مرحلة من خلال تسجيل الدخول إلى شبكة الغذاء المفتوح والذهاب إلى المسؤول." + action: "انتقل إلى واجهة الشركة" back: "عودة" continue: "استمر" action_or: "أو" @@ -2278,6 +2289,7 @@ ar: enterprise_register_success_notice: "تهانينا! اكتمل التسجيل لـ %{enterprise}!" enterprise_bulk_update_success_notice: "تم تحديث المؤسسات بنجاح" enterprise_bulk_update_error: 'فشل التحديث' + enterprise_shop_show_error: "المتجر الذي تبحث عنه غير موجود أو غير نشط . يرجى التحقق من المحلات التجارية الأخرى." order_cycles_create_notice: 'تم إنشاء دورة الطلب الخاصة بك.' order_cycles_update_notice: 'تم تحديث دورة الطلب.' order_cycles_bulk_update_notice: 'تم تحديث دورات الطلب.' @@ -2603,6 +2615,34 @@ ar: few: "حزم" many: "حزم" other: "حزم" + bottle: + zero: "زجاجات" + one: "زجاجة" + two: "زجاجات" + few: "زجاجات" + many: "زجاجات" + other: "زجاجات" + item: + zero: "العناصر" + one: "بند" + two: "العناصر" + few: "العناصر" + many: "العناصر" + other: "المواد" + dozen: + zero: "العشرات" + one: "دزينة" + two: "العشرات" + few: "العشرات" + many: "العشرات" + other: "العشرات" + unit: + zero: "الوحدات" + one: "وحدة" + two: "الوحدات" + few: "الوحدات" + many: "الوحدات" + other: "الوحدات" producers: signup: start_free_profile: "ابدأ بملف تعريف مجاني ، وتوسع عندما تكون جاهزًا!" @@ -2956,7 +2996,8 @@ ar: tax_invoice: "فاتورة ضريبية" code: "الشفرة" from: "من " - to: "إلى" + to: "فاتورة الى" + shipping: "الشحن" form: distribution_fields: title: "توزيع" diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 7f7f1f9476..35a2a9657a 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -19,6 +19,8 @@ ca: shipping_category_id: "Categoria d'enviament" variant_unit: "Unitat de la variant" variant_unit_name: "Nom de la unitat de la variant" + spree/credit_card: + base: "Targeta de crèdit" order_cycle: orders_close_at: Data de tancament errors: @@ -246,6 +248,8 @@ ca: notes: Notes error: Error processing_payment: "S'està processant el pagament..." + no_pending_payments: "No hi ha pagaments pendents" + invalid_payment_state: "Estat de pagament no vàlid" filter_results: Aplicar filtre quantity: Quantitat pick_up: Recollida @@ -862,6 +866,12 @@ ca: cancel: "Cancel·lar" back_to_list: "Tornar a la llista" outgoing: + outgoing: "Sortint" + distributor: "Distribuïdora" + products: "Productes " + tags: "Etiquetes" + delivery_details: "Detalls d'enviament" + fees: "Comissions" previous: "Anterior" save: "Desa" save_and_back_to_list: "Desa i torna a la llista" @@ -1425,7 +1435,7 @@ ca: email_confirm_customer_greeting: "Hola %{name}," email_confirm_customer_intro_html: "Gràcies per comprar a %{distributor}." email_confirm_customer_number_html: "Confirmació de la comanda # %{number} " - email_confirm_customer_details_html: "Aquests són els detalls de la teva comanda de %{distributor} :" + email_confirm_customer_details_html: "Aquests són els detalls de la teva comanda de%{distributor}:" email_confirm_customer_signoff: "Salutacions cordials," email_confirm_shop_greeting: "Hola %{name}," email_confirm_shop_order_html: "Que bé! Tens una nova comanda per %{distributor} ." @@ -1487,6 +1497,7 @@ ca: shopping_oc_closed_description: "Si us plau espera fins que s'obri el pròxim cicle (o posa't en contacte amb nosaltres directament per veure si podem acceptar alguna comanda fora de temps)" shopping_oc_last_closed: "L'últim cicle va tancar fa %{distance_of_time} " shopping_oc_next_open: "El següent cicle s'obre en %{distance_of_time}" + shopping_oc_select: "Selecciona ..." shopping_tabs_home: "Inici" shopping_tabs_shop: "Botiga" shopping_tabs_about: "Sobre" @@ -1860,6 +1871,7 @@ ca: headline: "Acabat!" thanks: "Gràcies per omplir els detalls de%{enterprise}." login: "Pots canviar o actualitzar la teva organització en qualsevol moment accedint a Katuma i anant a Admin." + action: "Vés al panell de control de l'organització" back: "Enrere" continue: "Continua" action_or: "O" @@ -2629,6 +2641,12 @@ ca: tub: one: "tina" other: "cubells" + punnet: + one: "puntet" + other: "capses" + packet: + one: "paquet" + other: "paquets" item: one: "article" other: "articles" @@ -3015,7 +3033,8 @@ ca: tax_invoice: "FACTURA D'IMPOSTOS" code: "Codi" from: "De" - to: "Per a" + to: "Facturar a" + shipping: "Enviament" form: distribution_fields: title: "Distribució" diff --git a/config/locales/de_DE.yml b/config/locales/de_DE.yml index 9025b190f1..bfdacc350e 100644 --- a/config/locales/de_DE.yml +++ b/config/locales/de_DE.yml @@ -19,6 +19,8 @@ de_DE: shipping_category_id: "Versandkategorie" variant_unit: "Varianteneinheit" variant_unit_name: "Name der Varianteneinheit" + spree/credit_card: + base: "Kreditkarte" order_cycle: orders_close_at: Schlussdatum errors: @@ -29,6 +31,10 @@ de_DE: taken: "Es gibt bereits ein Konto für diese E-Mail-Adresse. Bitte versuchen Sie sich einzuloggen oder setzen Sie Ihr Passwort zurück." spree/order: no_card: Es sind keine belastbaren Karten verfügbar. + spree/credit_card: + attributes: + base: + card_expired: "abgelaufen" order_cycle: attributes: orders_close_at: @@ -36,7 +42,7 @@ de_DE: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "muss leer sein, da die Einstellungen des Produzentenbestands verwendet werden" - on_demand_but_count_on_hand_set: "muss bei Bedarf leer sein" + on_demand_but_count_on_hand_set: "muss leer sein falls Produktion auf Nachfrage" limited_stock_but_no_count_on_hand: "muss angegeben werden, da nur begrenzte Lagerbestände erforderlich sind" activemodel: attributes: @@ -46,10 +52,12 @@ de_DE: distributor_ids: "Hubs" producer_ids: "Erzeuger" order_cycle_ids: "Bestellrunden" - enterprise_fee_ids: "Gebühren Namen" + enterprise_fee_ids: "Gebührennamen" shipping_method_ids: "Lieferart" payment_method_ids: "Zahlungsarten" errors: + messages: + inclusion: "ist in der Liste nicht enthalten" models: subscription_validator: attributes: @@ -244,6 +252,8 @@ de_DE: notes: Anmerkungen error: Fehler processing_payment: "Bezahlung wird verarbeitet..." + no_pending_payments: "Keine ausstehenden Zahlungen" + invalid_payment_state: "Ungültiger Zahlungsstatus" filter_results: Ergebnisse filtern quantity: Menge pick_up: Abholen @@ -700,6 +710,11 @@ de_DE: enable_subscriptions_false: "deaktiviert" enable_subscriptions_true: "aktiviert" shopfront_message: "Laden-Nachricht" + shopfront_message_placeholder: > + Eine optionale Nachricht, um Kunden willkommen zu heißen und zu erklären, + wie Sie bei Ihnen einkaufen können. Wenn hier Text eingegeben wird, + wird dieser in einem Home-Tab in Ihrem Shop angezeigt, wenn Kunden zum + ersten Mal ihren Shop besuchen. shopfront_message_link_tooltip: "Link einfügen / bearbeiten" shopfront_message_link_prompt: "Bitte geben Sie eine einzufügende URL ein" shopfront_closed_message: "Laden Geschlossen Nachricht" @@ -854,6 +869,12 @@ de_DE: cancel: "Abbrechen" back_to_list: "Zurück zur Liste" outgoing: + outgoing: "Ausgehend" + distributor: "Verteiler" + products: "Produkte" + tags: "Stichwörter" + delivery_details: "Lieferdetails" + fees: "Gebühren" previous: "Bisherige" save: "Speichern" save_and_back_to_list: "Speichern und zurück zur Liste" @@ -1100,10 +1121,13 @@ de_DE: destroy_attachment_does_not_exist: "Logo existiert nicht" enterprise_promo_image: destroy_attachment_does_not_exist: "Webebild existiert nicht" + orders: + failed_to_update: "Bestellung konnte nicht aktualisiert werden" checkout: already_ordered: cart: "Warenkorb" message_html: "Sie haben bereits eine Bestellung für diesen Bestellzyklus. Überprüfen Sie den %{cart}, um die Artikel zu sehen, die Sie zuvor bestellt haben. Sie können Artikel auch stornieren, solange der Bestellzyklus geöffnet ist." + failed: "Die Bestellung ist fehlgeschlagen. Bitte geben Sie uns Bescheid, damit wir Ihre Bestellung trotzdem bearbeiten können." shops: hubs: show_closed_shops: "Geschlossene Läden anzeigen" @@ -1121,7 +1145,7 @@ de_DE: checkout: "Zur Kasse" already_ordered_products: "Bereits in diesem Bestellzyklus bestellt" register_call: - selling_on_ofn: "Interesse am Open Food Network?" + selling_on_ofn: "Sie möchten selbst im Open Food Network verkaufen?" register: "Hier anmelden" footer: footer_secure: "Sicher und vertrauenswürdig." @@ -1274,6 +1298,7 @@ de_DE: saving_credit_card: Kreditkarte speichern ... card_has_been_removed: "Ihre Karte wurde entfernt (Nummer: %{number})" card_could_not_be_removed: Die Karte konnte nicht entfernt werden + invalid_credit_card: "Ungültige Kreditkarte" ie_warning_headline: "Ihr Browser ist veraltet :-(" ie_warning_text: "Für das beste Open-Food-Network-Erlebnis empfehlen wir dringend, Ihren Browser zu aktualisieren:" ie_warning_chrome: Chrome herunterladen @@ -1361,7 +1386,7 @@ de_DE: checkout_default_bill_address: "Als Standard-Rechnungsadresse speichern" checkout_shipping: Versandinformation checkout_default_ship_address: "Als Standardversandadresse speichern" - checkout_method_free: ?? + checkout_method_free: kostenlos checkout_address_same: Lieferadresse wie Rechnungsadresse? checkout_ready_for: "Bereit am:" checkout_instructions: "Kommentare oder spezielle Anweisungen?" @@ -1475,6 +1500,7 @@ de_DE: shopping_oc_closed_description: "Bitte warten Sie, bis der nächste Zyklus beginnt (oder kontaktieren Sie uns direkt, um zu sehen, ob wir verspätete Bestellungen annehmen können)" shopping_oc_last_closed: "Der letzte Zyklus wurde vor %{distance_of_time} geschlossen" shopping_oc_next_open: "Der nächste Zyklus wird in %{distance_of_time} geöffnet" + shopping_oc_select: "Wählen..." shopping_tabs_home: "Startseite" shopping_tabs_shop: "Laden" shopping_tabs_about: "Über Uns" @@ -1758,13 +1784,13 @@ de_DE: address1_field_placeholder: "z.B. 123 Cranberry-Laufwerk" address1_field_error: "Bitte geben Sie eine Adresse an" address2_field: "Anschrift Zeile 2:" - suburb_field: "Vorort:" + suburb_field: "Ort:" suburb_field_placeholder: "z.B. Northcote" suburb_field_error: "Bitte geben Sie einen Vorort ein" postcode_field: "Postleitzahl:" postcode_field_placeholder: "z.B. 3070" postcode_field_error: "Postleitzahl erforderlich" - state_field: "Zustand:" + state_field: "Bundesland:" state_field_error: "Staat erforderlich" country_field: "Land:" country_field_error: "Bitte wähle ein Land" @@ -1783,8 +1809,8 @@ de_DE: yes_producer: "Ja, ich bin ein Produzent." no_producer: "Nein, ich bin kein Produzent" producer_field_error: "Bitte wählen Sie: Sind Sie ein Produzent?" - yes_producer_help: "Hersteller machen leckere Dinge zu essen und / oder zu trinken. Du bist ein Produzent, wenn du ihn anbaust, erziehst ihn, braue ihn, backe ihn, gähre ihn, melke ihn oder forme ihn." - no_producer_help: "Wenn Sie kein Produzent sind, sind Sie wahrscheinlich jemand, der Lebensmittel verkauft und verteilt. Sie könnten ein Hub, Coop, Einkaufsgruppe, Einzelhändler, Großhändler oder andere sein." + yes_producer_help: "Die Produzenten machen leckere Sachen zum Essen und / oder Trinken. Sie sind ein Produzent, wenn Sie anbauen, brauen, backen, fermentieren, melken oder sonst wie Lebenmittel produzieren." + no_producer_help: "Wenn Sie kein Produzent sind, sind Sie wahrscheinlich jemand, der Lebensmittel verkauft und verteilt. Sie könnten ein Foodhub, eine Coop, eine Einkaufsgruppe, Einzelhändler, ein Hofladen, Großhändler oder vergleichbares sein." create_profile: "Profil erstellen" about: title: "Über Uns" @@ -1848,6 +1874,7 @@ de_DE: headline: "Fertig!" thanks: "Vielen Dank, dass Sie die Details für %{enterprise} ausgefüllt haben." login: "Sie können Ihr Unternehmen jederzeit ändern oder aktualisieren, indem Sie sich bei Open Food Network anmelden und zum Administrator wechseln." + action: "Gehen Sie zum Enterprise Dashboard" back: "Zurück" continue: "Fortsetzen" action_or: "ODER" @@ -1933,6 +1960,7 @@ de_DE: tax_category: "Steuerkategorie" calculator: "Rechner" calculator_values: "Rechnerwerte" + calculator_settings_warning: "Wenn Sie den Gebühren-Typ ändern, müssen Sie zuerst speichern, bevor Sie die Gebühren-Einstellungen bearbeiten können" flat_percent_per_item: "Flache Prozent (pro Artikel)" flat_rate_per_item: "Pauschale (pro Stück)" flat_rate_per_order: "Pauschalpreis pro Bestellung)" @@ -2263,6 +2291,7 @@ de_DE: enterprise_register_success_notice: "Herzliche Glückwünsche! Registrierung für %{enterprise} ist abgeschlossen!" enterprise_bulk_update_success_notice: "Unternehmen wurden erfolgreich aktualisiert" enterprise_bulk_update_error: 'Update fehlgeschlagen' + enterprise_shop_show_error: "Der gesuchte Shop existiert nicht oder ist auf OFN inaktiv. Bitte schauen Sie nach anderen Shops!" order_cycles_create_notice: 'Ihr Bestellzyklus wurde erstellt.' order_cycles_update_notice: 'Ihr Bestellzyklus wurde aktualisiert.' order_cycles_bulk_update_notice: 'Bestellzyklen wurden aktualisiert.' @@ -2417,6 +2446,12 @@ de_DE: severity: Schwere description: Beschreibung resolve: Entschlossenheit + exchange_products: + load_more_variants: "Weitere Varianten laden" + load_all_variants: "Alle Varianten laden" + select_all_variants: "Wählen Sie alle %{total_number_of_variants}-Varianten aus" + variants_loaded: "%{num_of_variants_loaded} von %{total_number_of_variants} Varianten geladen" + loading_variants: "lade Varianten" tag_rules: shipping_method_tagged_top: "Versandarten markiert" shipping_method_tagged_bottom: "sind:" @@ -2499,6 +2534,7 @@ de_DE: customer_placeholder: "Kunde@beispiel.org" valid_email_error: "Bitte geben Sie eine gültige E-Mail-Adresse ein" subscriptions: + error_saving: "Fehler beim Speichern des Abonnements" new: please_select_a_shop: "Bitte wählen Sie einen Laden" insufficient_stock: "Nicht genügend Lagerbestand verfügbar, nur noch %{on_hand} verfügbar" @@ -2575,9 +2611,78 @@ de_DE: have_an_account: "Hast du schon ein Konto?" action_login: "Jetzt einloggen." inflections: + each: + one: "jeder" + other: "pro Stück" + bunch: + one: "Bündel" + other: "Bündel" + pack: + one: "Pack" + other: "Packungen" + box: + one: "Box" + other: "Kisten" bottle: one: "Flasche" other: "Flaschen" + jar: + one: "Krug" + other: "Gläser" + head: + one: "Kopf" + other: "Köpfe" + bag: + one: "Tasche" + other: "Beutel" + loaf: + one: "Laib" + other: "Laibe" + single: + one: "Einzeln" + other: "Einzel" + tub: + one: "Wanne" + other: "Wannen" + punnet: + one: "Körbchen" + other: "Körbchen" + packet: + one: "Paket" + other: "Pakete" + item: + one: "Artikel" + other: "Artikel" + dozen: + one: "Dutzend" + other: "Dutzende" + unit: + one: "Einheit" + other: "Einheiten" + serve: + one: "Portion" + other: "Portionen" + tray: + one: "Schale" + other: "Schalen" + piece: + one: "Stück" + other: "Stücke" + pot: + one: "Topf" + other: "Töpfe" + bundle: + one: "bündeln" + other: "Bündel" + flask: + one: "Flasche" + other: "Flaschen" + basket: + one: "Korb" + other: "Körbe" + sack: + one: "Sack" + other: "Säcke" producers: signup: start_free_profile: "Beginnen Sie mit einem kostenlosen Profil und erweitern Sie es, wenn Sie fertig sind!" @@ -2643,6 +2748,7 @@ de_DE: status: "Status" new: "Neu" start: "Start" + end: "Ende" stop: "Halt" first: "Zuerst" previous: "Bisherige" @@ -2819,6 +2925,8 @@ de_DE: zipcode: Postleitzahl weight: Gewicht (pro kg) error_user_destroy_with_orders: "Benutzer mit abgeschlossenen Bestellungen dürfen nicht gelöscht werden" + cannot_create_payment_without_payment_methods: "Sie können keine Zahlung für eine Bestellung erstellen, ohne dass Zahlungsmethoden definiert sind." + please_define_payment_methods: "Bitte definieren Sie zunächst die Zahlungsmethoden." options: "Optionen" actions: update: "Aktualisieren" @@ -2905,6 +3013,7 @@ de_DE: capture: "Erfassung" ship: "Liefern" edit: "Bearbeiten" + order_not_updated: "Die Bestellung konnte nicht aktualisiert werden" note: "Hinweis" first: "Zuerst" last: "Letzte" @@ -2927,7 +3036,8 @@ de_DE: tax_invoice: "Steuerrechnung" code: "Code" from: "Von" - to: "Zu" + to: "Rechnungsempfänger" + shipping: "Versand" form: distribution_fields: title: "Verteilung" @@ -3125,6 +3235,12 @@ de_DE: used_saved_card: "Verwende eine gespeicherte Karte:" or_enter_new_card: "Oder geben Sie Details für eine neue Karte ein:" remember_this_card: Erinnerst du dich an diese Karte? + stripe_sca: + choose_one: Wähle Sie eine Option + enter_new_card: Geben Sie Details für eine neue Karte ein + used_saved_card: "Verwenden Sie eine gespeicherte Karte:" + or_enter_new_card: "Oder geben Sie Details für eine neue Karte ein:" + remember_this_card: Diese Karte speichern? date_picker: format: '% Y-% m-%d' js_format: 'JJ-MM-TT' diff --git a/config/locales/en.yml b/config/locales/en.yml index 804ccbbcef..039cc3c8eb 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -40,6 +40,8 @@ en: shipping_category_id: "Shipping Category" variant_unit: "Variant Unit" variant_unit_name: "Variant Unit Name" + spree/credit_card: + base: "Credit Card" order_cycle: orders_close_at: Close date errors: @@ -50,6 +52,10 @@ en: taken: "There's already an account for this email. Please login or reset your password." spree/order: no_card: There are no authorised credit cards available to charge + spree/credit_card: + attributes: + base: + card_expired: "has expired" order_cycle: attributes: orders_close_at: @@ -914,6 +920,12 @@ en: cancel: "Cancel" back_to_list: "Back To List" outgoing: + outgoing: "Outgoing" + distributor: "Distributor" + products: "Products" + tags: "Tags" + delivery_details: "Delivery Details" + fees: "Fees" previous: "Previous" save: "Save" save_and_back_to_list: "Save and Back to List" @@ -3189,7 +3201,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using tax_invoice: "TAX INVOICE" code: "Code" from: "From" - to: "To" + to: "Bill to" + shipping: "Shipping" form: distribution_fields: title: "Distribution" diff --git a/config/locales/en_AU.yml b/config/locales/en_AU.yml index 2e6b6d1121..ecc81b40ce 100644 --- a/config/locales/en_AU.yml +++ b/config/locales/en_AU.yml @@ -19,6 +19,8 @@ en_AU: shipping_category_id: "Shipping Category" variant_unit: "Variant Unit" variant_unit_name: "Variant Unit Name" + spree/credit_card: + base: "Credit Card" order_cycle: orders_close_at: Close date errors: @@ -699,6 +701,16 @@ en_AU: enable_subscriptions_false: "Disabled" enable_subscriptions_true: "Enabled" shopfront_message: "\"Home\" message" + shopfront_message_placeholder: > + Create your home page content to welcome customers and explain how people + can shop with you. + + Include details about your delivery and pick up options, how often you + open the shop for orders, and all the details your customers will need + to understand the process of buying from you. + + You can also include links to your newsletter sign up, so that people + can connect with you to hear when your next order cycle opens. shopfront_message_link_tooltip: "Insert / edit link" shopfront_message_link_prompt: "Please enter a URL to insert" shopfront_closed_message: "Shopfront Closed Message" @@ -860,6 +872,11 @@ en_AU: cancel: "Cancel" back_to_list: "Back To List" outgoing: + outgoing: "Outgoing" + distributor: "Distributor" + products: "Products" + tags: "Tags" + fees: "Fees" previous: "Previous" save: "Save" save_and_back_to_list: "Save and Back to List" @@ -2927,7 +2944,6 @@ en_AU: tax_invoice: "TAX INVOICE" code: "Code" from: "From" - to: "To" form: distribution_fields: title: "Distribution" diff --git a/config/locales/en_BE.yml b/config/locales/en_BE.yml index 1e1c139a46..7f6c05a7c3 100644 --- a/config/locales/en_BE.yml +++ b/config/locales/en_BE.yml @@ -19,6 +19,8 @@ en_BE: shipping_category_id: "Shipping Category" variant_unit: "Variant Unit" variant_unit_name: "Variant Unit Name" + spree/credit_card: + base: "Credit Card" order_cycle: orders_close_at: Close date errors: @@ -836,6 +838,11 @@ en_BE: next: "Next" cancel: "Cancel" outgoing: + outgoing: "Outgoing" + distributor: "Distributor" + products: "Products" + tags: "Tags" + fees: "Fees" previous: "Previous" save: "Save" cancel: "Cancel" @@ -2856,7 +2863,6 @@ en_BE: tax_invoice: "TAX INVOICE" code: "Code" from: "From" - to: "To" form: distribution_fields: title: "Distribution" diff --git a/config/locales/en_CA.yml b/config/locales/en_CA.yml index a2b274d610..193b756e57 100644 --- a/config/locales/en_CA.yml +++ b/config/locales/en_CA.yml @@ -19,6 +19,8 @@ en_CA: shipping_category_id: "Shipping Category" variant_unit: "Variant Unit" variant_unit_name: "Variant Unit Name" + spree/credit_card: + base: "Credit Card" order_cycle: orders_close_at: Close date errors: @@ -861,6 +863,11 @@ en_CA: cancel: "Cancel" back_to_list: "Back to List" outgoing: + outgoing: "Outgoing" + distributor: "Distributor" + products: "Products" + tags: "Tags" + fees: "Fees" previous: "Previous" save: "Save" save_and_back_to_list: "Save and Back to List" @@ -871,10 +878,10 @@ en_CA: incoming: "2. Incoming Products" outgoing: "3. Outgoing Products" exchange_form: - pickup_time_tip: Date orders will be ready for pick-up/delivery. Or enter the customer type (e.g. 'wholesale', 'members only'...) if you are setting up multiple shopfronts. + pickup_time_tip: 'This phrase will help buyers select their shop from multiple shops. It will be preceded by the phrase "Orders for". So enter a pick-up date, or buyer group... ' pickup_instructions_placeholder: "Pick-up instructions" pickup_instructions_tip: These instructions are shown to customers after they complete an order - pickup_time_placeholder: "Ready for (ie. Date/Time)" + pickup_time_placeholder: "Order for (ie. Date, or buyer group...)" receival_instructions_placeholder: "Receival instructions" add_fee: 'Add fee' remove: 'Remove' @@ -921,7 +928,7 @@ en_CA: distributors: distributors variants: variants simple_form: - ready_for: Ready for + ready_for: Order for ready_for_placeholder: Date / time customer_instructions: Customer instructions customer_instructions_placeholder: 'Notes:' @@ -1362,7 +1369,7 @@ en_CA: stats_orders: "orders" checkout_title: Checkout checkout_now: Checkout now - checkout_order_ready: Order ready for + checkout_order_ready: Order for checkout_hide: Hide checkout_expand: Expand checkout_headline: "Ok, ready to checkout?" @@ -1374,7 +1381,7 @@ en_CA: checkout_default_ship_address: "Save as default shipping address" checkout_method_free: Free checkout_address_same: Shipping address same as billing address? - checkout_ready_for: "Ready for:" + checkout_ready_for: "Order for: " checkout_instructions: "Any comments or special instructions?" checkout_payment: Payment checkout_send: Place order now @@ -1393,7 +1400,7 @@ en_CA: order_delivery_address: Delivery address order_delivery_time: Delivery time order_special_instructions: "Your notes:" - order_pickup_time: Ready for collection + order_pickup_time: 'Order for:' order_pickup_instructions: Collection Instructions order_produce: Subtotal order_total_price: Total @@ -1462,7 +1469,7 @@ en_CA: email_shipping_delivery_time: "Delivery on:" email_shipping_delivery_address: "Delivery address:" email_shipping_collection_details: Collection details - email_shipping_collection_time: "Ready for collection:" + email_shipping_collection_time: "Order for:" email_shipping_collection_instructions: "Collection instructions:" email_special_instructions: "Your notes:" email_signup_greeting: Hello! @@ -1486,6 +1493,7 @@ en_CA: shopping_oc_closed_description: "Please wait until the next cycle opens (or contact us directly to see if we can accept any late orders)" shopping_oc_last_closed: "The last cycle closed %{distance_of_time} ago" shopping_oc_next_open: "The next cycle opens in %{distance_of_time}" + shopping_oc_select: "Select" shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" @@ -1496,7 +1504,7 @@ en_CA: shopping_groups_part_of: "is part of:" shopping_producers_of_hub: "%{hub}'s producers:" enterprises_next_closing: "Next order closing" - enterprises_ready_for: "Ready for" + enterprises_ready_for: "Order for" enterprises_choose: "Choose from the dropdown:" maps_open: "Open" maps_closed: "Closed" @@ -1647,7 +1655,7 @@ en_CA: orders_fees: Fees... orders_edit_title: Shopping Cart orders_edit_headline: Your shopping cart - orders_edit_time: Order ready for + orders_edit_time: Order for orders_edit_continue: Continue shopping orders_edit_checkout: Checkout orders_form_empty_cart: "Empty cart" @@ -3017,7 +3025,8 @@ en_CA: tax_invoice: "Order Number" code: "Code" from: "From" - to: "To" + to: "Bill to" + shipping: "Shipping" form: distribution_fields: title: "Distribution" diff --git a/config/locales/en_DE.yml b/config/locales/en_DE.yml index 5d71e42c64..8c81c87986 100644 --- a/config/locales/en_DE.yml +++ b/config/locales/en_DE.yml @@ -19,6 +19,8 @@ en_DE: shipping_category_id: "Shipping Category" variant_unit: "Variant Unit" variant_unit_name: "Variant Unit Name" + spree/credit_card: + base: "Credit Card" order_cycle: orders_close_at: Close date errors: @@ -844,6 +846,11 @@ en_DE: next: "Next" cancel: "Cancel" outgoing: + outgoing: "Outgoing" + distributor: "Distributor" + products: "Products" + tags: "Tags" + fees: "Fees" previous: "Previous" save: "Save" cancel: "Cancel" @@ -2872,7 +2879,6 @@ en_DE: tax_invoice: "TAX INVOICE" code: "Code" from: "From" - to: "To" form: distribution_fields: title: "Distribution" diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml index 03dbc99fcf..5665f4422b 100644 --- a/config/locales/en_FR.yml +++ b/config/locales/en_FR.yml @@ -19,6 +19,8 @@ en_FR: shipping_category_id: "Shipping Category" variant_unit: "Variant Unit" variant_unit_name: "Variant Unit Name" + spree/credit_card: + base: "Credit Card" order_cycle: orders_close_at: Close date errors: @@ -29,6 +31,10 @@ en_FR: taken: "There's already an account for this email. Please login or reset your password." spree/order: no_card: There are no authorised credit cards available to charge + spree/credit_card: + attributes: + base: + card_expired: "has expired" order_cycle: attributes: orders_close_at: @@ -861,6 +867,12 @@ en_FR: cancel: "Cancel" back_to_list: "Back To List" outgoing: + outgoing: "Outgoing" + distributor: "Distributor" + products: "Products" + tags: "Tags" + delivery_details: "Delivery Details" + fees: "Fees" previous: "Previous" save: "Save" save_and_back_to_list: "Save and Back to List" @@ -3019,7 +3031,8 @@ en_FR: tax_invoice: "TAX INVOICE" code: "Code" from: "From" - to: "To" + to: "Bill to" + shipping: "Shipping" form: distribution_fields: title: "Distribution" diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml index ff495627d6..dfa17eb46e 100644 --- a/config/locales/en_GB.yml +++ b/config/locales/en_GB.yml @@ -19,6 +19,8 @@ en_GB: shipping_category_id: "Shipping Category" variant_unit: "Variant Unit" variant_unit_name: "Variant Unit Name" + spree/credit_card: + base: "Credit Card" order_cycle: orders_close_at: Close date errors: @@ -861,6 +863,12 @@ en_GB: cancel: "Cancel" back_to_list: "Back To List" outgoing: + outgoing: "Outgoing" + distributor: "Distributor" + products: "Products" + tags: "Tags" + delivery_details: "Delivery Details" + fees: "Fees" previous: "Previous" save: "Save" save_and_back_to_list: "Save and Back to List" @@ -3025,7 +3033,8 @@ en_GB: tax_invoice: "TAX INVOICE" code: "Code" from: "From" - to: "To" + to: "Bill to" + shipping: "Shipping" form: distribution_fields: title: "Distribution" diff --git a/config/locales/en_NZ.yml b/config/locales/en_NZ.yml index 1dd1a01334..15ad362a51 100644 --- a/config/locales/en_NZ.yml +++ b/config/locales/en_NZ.yml @@ -19,6 +19,8 @@ en_NZ: shipping_category_id: "Shipping Category" variant_unit: "Variant Unit" variant_unit_name: "Variant Unit Name" + spree/credit_card: + base: "Credit Card" order_cycle: orders_close_at: Close date errors: @@ -246,6 +248,8 @@ en_NZ: notes: Notes error: Error processing_payment: "Processing payment..." + no_pending_payments: "No pending payments" + invalid_payment_state: "Invalid payment state" filter_results: Filter Results quantity: Quantity pick_up: Pick up @@ -859,6 +863,11 @@ en_NZ: cancel: "Cancel" back_to_list: "Back To List" outgoing: + outgoing: "Outgoing" + distributor: "Distributor" + products: "Products" + tags: "Tags" + fees: "Fees" previous: "Previous" save: "Save" save_and_back_to_list: "Save and Back to List" @@ -1484,6 +1493,7 @@ en_NZ: shopping_oc_closed_description: "Please wait until the next cycle opens (or contact us directly to see if we can accept any late orders)" shopping_oc_last_closed: "The last cycle closed %{distance_of_time} ago" shopping_oc_next_open: "The next cycle opens in %{distance_of_time}" + shopping_oc_select: "Select..." shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" @@ -1857,6 +1867,7 @@ en_NZ: headline: "Finished!" thanks: "Thanks for filling out the details for %{enterprise}." login: "You can change or update your enterprise at any stage by logging into Open Food Network and going to Admin." + action: "Go to Enterprise Dashboard" back: "Back" continue: "Continue" action_or: "OR" @@ -2273,6 +2284,7 @@ en_NZ: enterprise_register_success_notice: "Congratulations! Registration for %{enterprise} is complete!" enterprise_bulk_update_success_notice: "Enterprises updated successfully" enterprise_bulk_update_error: 'Update failed' + enterprise_shop_show_error: "The shop you are looking for doesn't exist or is inactive on OFN. Please check other shops." order_cycles_create_notice: 'Your order cycle has been created.' order_cycles_update_notice: 'Your order cycle has been updated.' order_cycles_bulk_update_notice: 'Order cycles have been updated.' @@ -3014,7 +3026,8 @@ en_NZ: tax_invoice: "TAX INVOICE" code: "Code" from: "From" - to: "To" + to: "Bill to" + shipping: "Shipping" form: distribution_fields: title: "Distribution" diff --git a/config/locales/en_US.yml b/config/locales/en_US.yml index 03a8308f2a..1e04a29f90 100644 --- a/config/locales/en_US.yml +++ b/config/locales/en_US.yml @@ -19,6 +19,8 @@ en_US: shipping_category_id: "Shipping Category" variant_unit: "Variant Unit" variant_unit_name: "Variant Unit Name" + spree/credit_card: + base: "Credit Card" order_cycle: orders_close_at: Close Date errors: @@ -50,6 +52,8 @@ en_US: shipping_method_ids: "Shipping Methods" payment_method_ids: "Payment Methods" errors: + messages: + inclusion: "is not included in the list" models: subscription_validator: attributes: @@ -116,7 +120,9 @@ en_US: email_welcome: "Welcome" email_registered: "is now part of" email_userguide_html: "The User Guide with detailed support for setting up your Producer or Hub is here: %{link}" + userguide: "Open Food Network User Guide" email_admin_html: "You can manage your account by logging into the %{link} or by clicking on the cog in the top right hand side of the homepage, and selecting Administration." + admin_panel: "Admin Panel" email_community_html: "We also have an online forum for community discussion related to OFN software and the unique challenges of running a food enterprise. You are encouraged to join in. We are constantly evolving and your input into this forum will shape what happens next. %{link}" join_community: "Join the community" invite_manager: @@ -242,6 +248,8 @@ en_US: notes: Notes error: Error processing_payment: "Processing payment..." + no_pending_payments: "No pending payments" + invalid_payment_state: "Invalid payment state" filter_results: Filter Results quantity: Quantity pick_up: Pick up @@ -434,9 +442,12 @@ en_US: infinity: "Infinity" to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order." back_to_products_list: "Back to products list" + editing_product: "Editing Product" tabs: + product_details: "Product Details" group_buy_options: "Group Buy Options" images: "Images" + variants: "Variants" product_properties: "Product Properties" product_import: title: Product Import @@ -539,6 +550,7 @@ en_US: title: Inventory description: Use this page to manage inventories for your enterprises. Any product details set here will override those set on the 'Products' page enable_reset?: Enable Stock Reset? + default_stock: "Default stock" inherit?: Inherit? add: Add hide: Hide @@ -598,7 +610,7 @@ en_US: desc_long: About Us desc_long_placeholder: Tell customers about yourself. This information appears on your public profile. business_details: - abn: Tax ID Number or EIN (optional) + abn: Tax ID, DUNS Number, or other business ID abn_placeholder: eg. 123456789 acn: Legal Business Name acn_placeholder: eg. Martin's Produce LLC @@ -693,6 +705,10 @@ en_US: enable_subscriptions_false: "Disabled" enable_subscriptions_true: "Enabled" shopfront_message: "Shopfront Message" + shopfront_message_placeholder: > + An optional message to welcome customers and explain how to shop with + you. If text is entered here it will be displayed in a home tab when + customers first arrive at your shopfront. shopfront_message_link_tooltip: "Insert / edit link" shopfront_message_link_prompt: "Please enter a URL to insert" shopfront_closed_message: "Shopfront Closed Message" @@ -830,20 +846,38 @@ en_US: new: create: "Create" cancel: "Cancel" + back_to_list: "Back To List" edit: advanced_settings: "Advanced Settings" save: "Save" + save_and_next: "Save and Next" next: "Next" cancel: "Cancel" + back_to_list: "Back To List" + save_and_back_to_list: "Save and Back to List" choose_products_from: "Choose Products From:" incoming: save: "Save" + save_and_next: "Save and Next" next: "Next" cancel: "Cancel" + back_to_list: "Back To List" outgoing: + outgoing: "Outgoing" + distributor: "Distributor" + products: "Products" + tags: "Tags" + delivery_details: "Delivery Details" + fees: "Fees" previous: "Previous" save: "Save" + save_and_back_to_list: "Save and Back to List" cancel: "Cancel" + back_to_list: "Back To List" + wizard_progress: + edit: "1. General Settings" + incoming: "2. Incoming Products" + outgoing: "3. Outgoing Products" exchange_form: pickup_time_tip: When orders from this OC will be ready for the customer pickup_instructions_placeholder: "Pick-up instructions" @@ -1081,10 +1115,13 @@ en_US: destroy_attachment_does_not_exist: "Logo does not exist" enterprise_promo_image: destroy_attachment_does_not_exist: "Promo image does not exist" + orders: + failed_to_update: "Failed to update order" checkout: already_ordered: cart: "cart" message_html: "You have an order for this order cycle already. Check the %{cart} to see the items you ordered before. You can also cancel items as long as the order cycle is open." + failed: "The checkout failed. Please let us know so that we can process your order." shops: hubs: show_closed_shops: "Show closed shops" @@ -1143,11 +1180,11 @@ en_US: invoice_column_price_without_taxes: "Total price (Excl. tax)" invoice_column_tax_rate: "Tax rate" invoice_tax_total: "Tax total:" - tax_invoice: "TAX INVOICE" + tax_invoice: "INVOICE" tax_total: "Total tax (%{rate}):" total_excl_tax: "Total (Excl. tax):" total_incl_tax: "Total (Incl. tax):" - abn: "Tax ID Number or EIN (optional)" + abn: "Tax ID, DUNS Number, or other business ID" acn: "Legal Business Name" invoice_issued_on: "Invoice issued on:" order_number: "Invoice number:" @@ -1255,6 +1292,7 @@ en_US: saving_credit_card: Saving credit card... card_has_been_removed: "Your card has been removed (number: %{number})" card_could_not_be_removed: Sorry, the card could not be removed + invalid_credit_card: "Invalid credit card" ie_warning_headline: "Your browser is out of date :-(" ie_warning_text: "For the best Open Food Network experience, we strongly recommend upgrading your browser:" ie_warning_chrome: Download Chrome @@ -1456,6 +1494,7 @@ en_US: shopping_oc_closed_description: "Please wait until the next cycle opens (or contact us directly to see if we can accept any late orders)" shopping_oc_last_closed: "The last cycle closed %{distance_of_time} ago" shopping_oc_next_open: "The next cycle opens in %{distance_of_time}" + shopping_oc_select: "Select..." shopping_tabs_home: "Home" shopping_tabs_shop: "Shop" shopping_tabs_about: "About" @@ -1778,7 +1817,7 @@ en_US: enterprise_long_desc: "Long Description" enterprise_long_desc_placeholder: "This is your opportunity to tell the story of your enterprise - what makes you different and wonderful? We'd suggest keeping your description to under 600 characters or 150 words." enterprise_long_desc_length: "%{num} characters / up to 600 recommended" - enterprise_abn: "Tax ID Number or EIN (optional)" + enterprise_abn: "Tax ID, DUNS Number, or other business ID" enterprise_abn_placeholder: "eg. 123456789" enterprise_acn: "Legal Business Name" enterprise_acn_placeholder: "eg. Justins Produce LLC" @@ -1829,6 +1868,7 @@ en_US: headline: "Finished!" thanks: "Thanks for filling out the details for %{enterprise}." login: "You can change or update your enterprise at any stage by logging into Open Food Network and going to Admin." + action: "Go to Enterprise Dashboard" back: "Back" continue: "Continue" action_or: "OR" @@ -1914,6 +1954,7 @@ en_US: tax_category: "Tax Category" calculator: "Calculator" calculator_values: "Calculator values" + calculator_settings_warning: "If you are changing the calculator type, you must save first before you can edit the calculator settings" flat_percent_per_item: "Flat Percent (per item)" flat_rate_per_item: "Flat Rate (per item)" flat_rate_per_order: "Flat Rate (per order)" @@ -2244,6 +2285,7 @@ en_US: enterprise_register_success_notice: "Congratulations! Registration for %{enterprise} is complete!" enterprise_bulk_update_success_notice: "Enterprises updated successfully" enterprise_bulk_update_error: 'Update failed' + enterprise_shop_show_error: "The shop you are looking for doesn't exist or is inactive on OFN. Please check other shops." order_cycles_create_notice: 'Your order cycle has been created.' order_cycles_update_notice: 'Your order cycle has been updated.' order_cycles_bulk_update_notice: 'Order cycles have been updated.' @@ -2395,6 +2437,12 @@ en_US: severity: Severity description: Description resolve: Resolve + exchange_products: + load_more_variants: "Load More Variants" + load_all_variants: "Load All Variants" + select_all_variants: "Select All %{total_number_of_variants} Variants" + variants_loaded: "%{num_of_variants_loaded} of %{total_number_of_variants} Variants Loaded" + loading_variants: "Loading Variants" tag_rules: shipping_method_tagged_top: "Shipping methods tagged" shipping_method_tagged_bottom: "are:" @@ -2477,6 +2525,7 @@ en_US: customer_placeholder: "customer@example.org" valid_email_error: "Please enter a valid email address" subscriptions: + error_saving: "Error saving subscription" new: please_select_a_shop: "Please select a shop" insufficient_stock: "Insufficient stock available, only %{on_hand} remaining" @@ -2552,6 +2601,76 @@ en_US: signup_or_login: "Start By signing up (or logging in)" have_an_account: "Already have an account?" action_login: "Log in now." + inflections: + each: + one: "each" + other: "each" + bunch: + one: "bunch" + other: "bunches" + pack: + one: "pack" + other: "packs" + box: + one: "box" + other: "boxes" + bottle: + one: "bottle" + other: "bottles" + jar: + one: "jar" + other: "jars" + head: + one: "head" + other: "heads" + bag: + one: "bag" + other: "bags" + loaf: + one: "loaf" + other: "loaves" + single: + one: "single" + other: "singles" + tub: + one: "tub" + other: "tubs" + packet: + one: "packet" + other: "packets" + item: + one: "item" + other: "items" + dozen: + one: "dozen" + other: "dozens" + unit: + one: "unit" + other: "units" + serve: + one: "serve" + other: "serves" + tray: + one: "tray" + other: "trays" + piece: + one: "piece" + other: "pieces" + pot: + one: "pot" + other: "pots" + bundle: + one: "bundle" + other: "bundles" + flask: + one: "flask" + other: "flasks" + basket: + one: "basket" + other: "baskets" + sack: + one: "sack" + other: "sacks" producers: signup: start_free_profile: "Start with a free profile, and expand when you're ready!" @@ -2777,6 +2896,12 @@ en_US: minimal_amount: "Minimal Amount" normal_amount: "Normal Amount" discount_amount: "Discount Amount" + no_images_found: "No Images Found" + new_image: "New Image" + filename: "Filename" + alt_text: "Alternative Text" + thumbnail: "Thumbnail" + back_to_images_list: "Back To Images List" email: Email account_updated: "Account updated!" email_updated: "The account will be updated once the new email is confirmed." @@ -2788,6 +2913,9 @@ en_US: zipcode: Zipcode weight: Weight (per lb) error_user_destroy_with_orders: "Users with completed orders may not be deleted" + cannot_create_payment_without_payment_methods: "You cannot create a payment for an order without any payment methods defined." + please_define_payment_methods: "Please define some payment methods first." + options: "Options" actions: update: "Update" errors: @@ -2819,27 +2947,53 @@ en_US: product_properties: index: inherits_properties_checkbox_hint: "Inherit properties from %{supplier}? (unless overridden above)" + add_product_properties: "Add Product Properties" + select_from_prototype: "Select From Prototype" properties: index: properties: "Properties" + new_property: "New Property" name: "Name" + presentation: "Presentation" + new: + new_property: "New Property" + edit: + editing_property: "Editing Property" + back_to_properties_list: "Back To Properties List" form: name: "Name" + presentation: "Presentation" return_authorizations: index: + new_return_authorization: "New Return Authorization" return_authorizations: "Return Authorizations" back_to_orders_list: "Back To Orders List" + rma_number: "RMA Number" status: "Status" amount: "Amount" cannot_create_returns: "Cannot create returns as this order has no shipped units." continue: "Continue" new: + new_return_authorization: "New Return Authorization" + back_to_return_authorizations_list: "Back To Return Authorization List" continue: "Continue" edit: + receive: "receive" are_you_sure: "Are you sure?" + return_authorization: "Return Authorization" form: product: "Product" + quantity_shipped: "Quantity Shipped" + quantity_returned: "Quantity Returned" + return_quantity: "Return Quantity" amount: "Amount" + rma_value: "RMA Value" + reason: "Reason" + stock_location: "Stock Location" + states: + authorized: "Authorized" + received: "Received" + canceled: "Canceled" orders: index: listing_orders: "Listing Orders" @@ -2847,6 +3001,7 @@ en_US: capture: "Capture" ship: "Ship" edit: "Edit" + order_not_updated: "The order could not be updated" note: "Note" first: "First" last: "Last" @@ -2866,10 +3021,11 @@ en_US: email: "Customer E-mail" invoice: issued_on: "Issued on" - tax_invoice: "TAX INVOICE" + tax_invoice: "INVOICE" code: "Code" from: "From" - to: "To" + to: "Bill to" + shipping: "Shipping" form: distribution_fields: title: "Distribution" @@ -3030,12 +3186,22 @@ en_US: index: sku: "SKU" price: "Price" + options: "Options" no_results: "No results" + to_add_variants_you_must_first_define: "To add variants, you must first define" option_types: "Option Types" + option_values: "Option Values" + and: "and" + new_variant: "New Variant" + show_active: "Show Active" + show_deleted: "Show Deleted" + new: + new_variant: "New Variant" form: sku: "SKU" price: "Price" display_as: "Display As" + display_name: "Display Name" autocomplete: producer_name: "Producer" unit: "Unit" @@ -3181,3 +3347,19 @@ en_US: allow_charges?: "Allow Charges?" localized_number: invalid_format: has an invalid format. Please enter a number. + api: + invalid_api_key: "Invalid API key (%{key}) specified." + unauthorized: "You are not authorized to perform that action." + invalid_resource: "Invalid resource. Please fix errors and try again." + resource_not_found: "The resource you were looking for could not be found." + access: "API Access" + key: "Key" + clear_key: "Clear key" + regenerate_key: "Regenerate Key" + no_key: "No key" + generate_key: "Generate API key" + key_generated: "Key generated" + key_cleared: "Key cleared" + shipment: + cannot_ready: "Cannot ready shipment." + invalid_taxonomy_id: "Invalid taxonomy id." diff --git a/config/locales/en_ZA.yml b/config/locales/en_ZA.yml index 8db0c3d44f..71e4279ab3 100644 --- a/config/locales/en_ZA.yml +++ b/config/locales/en_ZA.yml @@ -19,6 +19,8 @@ en_ZA: shipping_category_id: "Shipping Category" variant_unit: "Variant Unit" variant_unit_name: "Variant Unit Name" + spree/credit_card: + base: "Credit Card" order_cycle: orders_close_at: Close date errors: @@ -840,6 +842,11 @@ en_ZA: next: "Next" cancel: "Cancel" outgoing: + outgoing: "Outgoing" + distributor: "Distributor" + products: "Products" + tags: "Tags" + fees: "Fees" previous: "Previous" save: "Save" cancel: "Cancel" @@ -2870,7 +2877,6 @@ en_ZA: tax_invoice: "TAX INVOICE" code: "Code" from: "From" - to: "To" form: distribution_fields: title: "Distribution" diff --git a/config/locales/es.yml b/config/locales/es.yml index ca35023d67..ab12b1328f 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -19,6 +19,8 @@ es: shipping_category_id: "Categoría de envío" variant_unit: "Unidad Variante" variant_unit_name: "Nombre de la unidad de la variante" + spree/credit_card: + base: "Tarjeta de crédito" order_cycle: orders_close_at: Fecha de cierre errors: @@ -845,6 +847,11 @@ es: next: "Siguiente" cancel: "Cancelar" outgoing: + outgoing: "Saliente" + distributor: "Distribuidora" + products: "Productos" + tags: "Tags" + fees: "Comisiones" previous: "Anterior" save: "Guardar" cancel: "Cancelar" @@ -2877,7 +2884,6 @@ es: tax_invoice: "FACTURA DE IMPUESTOS" code: "Código" from: "De" - to: "A" form: distribution_fields: title: "Distribución" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index a7e45ee93e..7566b07d58 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -19,6 +19,8 @@ fr: shipping_category_id: "Condition de transport" variant_unit: "Unité" variant_unit_name: "Unité de la variante" + spree/credit_card: + base: "Carte de crédit" order_cycle: orders_close_at: Date de fermeture errors: @@ -29,6 +31,10 @@ fr: taken: "Un compte existe déjà pour cet e-mail. Connectez-vous ou demandez un nouveau mot de passe." spree/order: no_card: Aucune carte de paiement autorisée disponible + spree/credit_card: + attributes: + base: + card_expired: "a expiré" order_cycle: attributes: orders_close_at: @@ -863,6 +869,12 @@ fr: cancel: "Annuler" back_to_list: "Retour à la liste" outgoing: + outgoing: "Produits sortants (mis en vente par/via un ou plusieurs hubs)" + distributor: "Distributeur" + products: "Produits" + tags: "Tags" + delivery_details: "Détails de livraison" + fees: "Commissions" previous: "Précédent" save: "Sauvegarder" save_and_back_to_list: "Sauvegarder et revenir à la liste" @@ -1498,7 +1510,7 @@ fr: shopping_contact_social: "Suivre" shopping_groups_part_of: "fait partie de:" shopping_producers_of_hub: "Les producteurs de %{hub}:" - enterprises_next_closing: "Clôture des commandes pour ce cycle" + enterprises_next_closing: "Clôture des commandes" enterprises_ready_for: "Prêt pour" enterprises_choose: "Choisissez votre option:" maps_open: "Ouvert" @@ -3049,7 +3061,8 @@ fr: tax_invoice: "FACTURE" code: "Code" from: "De" - to: "A" + to: "Facturer à" + shipping: "Envoi" form: distribution_fields: title: "Distribution" diff --git a/config/locales/fr_BE.yml b/config/locales/fr_BE.yml index b780477f15..8ca1872694 100644 --- a/config/locales/fr_BE.yml +++ b/config/locales/fr_BE.yml @@ -19,6 +19,8 @@ fr_BE: shipping_category_id: "Catégorie de livraison" variant_unit: "Unité de variante" variant_unit_name: "Nom de la variante" + spree/credit_card: + base: "Carte de crédit" order_cycle: orders_close_at: Date de fermeture errors: @@ -861,6 +863,11 @@ fr_BE: cancel: "Annuler" back_to_list: "Retour à la liste." outgoing: + outgoing: "Produits sortants (mis en vente par/via un ou plusieurs comptoir·s)" + distributor: "Distributeur·trice" + products: "Produits" + tags: "Tags" + fees: "Commission" previous: "Précédent" save: "Sauvergarder" save_and_back_to_list: "Sauver et retour à la liste" @@ -1131,7 +1138,7 @@ fr_BE: checkout: "Passer la commande" already_ordered_products: "Déjà commandé dans ce cycle de vente" register_call: - selling_on_ofn: "Intéressé à participer à Open Food Network?" + selling_on_ofn: "Intéressé·e à vendre sur Open Food Network?" register: "Démarrez ici" footer: footer_secure: "Fiable et sécurisé." @@ -2949,7 +2956,6 @@ fr_BE: tax_invoice: "FACTURE" code: "Code" from: "De" - to: "A" form: distribution_fields: title: "Distribution" diff --git a/config/locales/fr_CA.yml b/config/locales/fr_CA.yml index 17c75fdde7..cf300ce168 100644 --- a/config/locales/fr_CA.yml +++ b/config/locales/fr_CA.yml @@ -19,6 +19,8 @@ fr_CA: shipping_category_id: "Condition de transport" variant_unit: "Unité" variant_unit_name: "Unité de la variante" + spree/credit_card: + base: "Carte de crédit" order_cycle: orders_close_at: Date de fermeture errors: @@ -247,6 +249,7 @@ fr_CA: notes: Commentaires error: Erreur processing_payment: "Paiement en cours..." + no_pending_payments: "Aucun paiement en attente." filter_results: Filtrer les résultats quantity: Quantité pick_up: Retrait @@ -862,6 +865,11 @@ fr_CA: cancel: "Annuler" back_to_list: "Retour à la liste" outgoing: + outgoing: "Produits sortants (mis en vente par/via un ou plusieurs hubs)" + distributor: "Hub-distributeur" + products: "Produits" + tags: "Tags" + fees: "Commissions" previous: "Précédent" save: "Enregistrer" save_and_back_to_list: "Sauvegarder et suivant" @@ -3028,7 +3036,6 @@ fr_CA: tax_invoice: "FACTURE" code: "Code" from: "De" - to: "A" form: distribution_fields: title: "Distribution" diff --git a/config/locales/it.yml b/config/locales/it.yml index d4452aba36..67f67b0a28 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -19,6 +19,8 @@ it: shipping_category_id: "Categoria di spedizione" variant_unit: "Unità Variante" variant_unit_name: "Nome Unità Variante" + spree/credit_card: + base: "Carta di Credito" order_cycle: orders_close_at: Data chiusura errors: @@ -791,13 +793,13 @@ it: producer_shop_description_text2: Un Negozio produttore è solo per i tuoi prodotti. Se vuoi vendere prodotti altrui, seleziona "Hub produttore". producer_hub: Hub produttore producer_hub_text: Vendi prodotti tuoi e di altri - producer_hub_description_text: La tua azienda è un pilastro del nostro sistema di cibo locale. Puoi vendere i tuoi prodotti, ma anche prodotti di tuoi produttori fidati attraverso la tua vetrina di Open Food Network. + producer_hub_description_text: La tua azienda è un pilastro della nostra filiera del cibo. Puoi vendere i tuoi prodotti, ma anche prodotti di tuoi produttori fidati attraverso la tua vetrina di Open Food Network. profile: Solo Profilo get_listing: Ottieni un listino profile_description_text: Le persone ti possono trovare e contattare su OFN. La tua azienda sarà visibile sulla mappa e potrà essere trovata nelle ricerche degli utenti. hub_shop: Isola logistica hub_shop_text: Vendi prodotti di altri - hub_shop_description_text: La tua azienda è la spina dorsale del vostro sistema alimentare locale. Puoi aggregare i prodotti di altre aziende e venderli attraverso il tuo negozio su Open Food Network. + hub_shop_description_text: La tua azienda è la spina dorsale della vostra filiera locale del cibo. Puoi aggregare i prodotti di altre aziende e venderli attraverso il tuo negozio su Open Food Network. choose_option: Per favore seleziona una delle opzioni. change_now: Modifica ora enterprise_user_index: @@ -862,6 +864,11 @@ it: cancel: "Annulla" back_to_list: "Indietro alla lista" outgoing: + outgoing: "In uscita" + distributor: "Distributore" + products: "Prodotti" + tags: "Tag" + fees: "Tariffe" previous: "Precedente" save: "Salva" save_and_back_to_list: "Salva e torna alla lista" @@ -1114,6 +1121,7 @@ it: already_ordered: cart: "carrello" message_html: "Hai già un ordine per questo ciclo d'ordine. Controlla%{cart} per vedere gli articoli ordinati in precedenza. Puoi anche cancellare gli articoli finché il ciclo dell'ordine è aperto." + failed: "Checkout fallito. Contattaci per poter processare il tuo ordine." shops: hubs: show_closed_shops: "Mostra i negozi chiusi" @@ -1341,7 +1349,7 @@ it: brandstory_part3: "Così costruiamo un mercato online che riequilibra le parti. E' trasparente, così crea raporti reali. E' open source, così è di tutti. Si adatta dalla scala regionale a quella nazionale, così le persone lo adottano in tutto il mondo." brandstory_part4: "Funziona ovunque. Cambia ogni cosa." brandstory_part5_strong: "Noi lo chiamiamo Open Food Network." - brandstory_part6: "Noi tutti amiamo il cibo. Adesso possiamo amare anche il nostro sistema cibo." + brandstory_part6: "Noi tutti amiamo il cibo. Adesso possiamo amare anche la nostra filiera del cibo." learn_body: "Esplora modelli, storie e risorse per aiutarti e sviluppare la tua azienda o la tua organizzazione in modo equo. Cerca corsi, eventi e altre opportunità per imparare da chi è come te." learn_cta: "Prendi ispirazione" connect_body: "Cerca la nostra intera lista di produttori, hub e gruppi per trovare chi è vicino a te. Aggiungi alla lista di OFN la tua azienda o organizzazionie così i clienti potranno trovarti. Unisciti alla comunità per avere consigli e risolvere problemi insieme." @@ -1355,7 +1363,7 @@ it: system_step3_text: "Attendi per la tua consegna, o visita il tuo produttore o distributore per una connessione più personale con il tuo cibo. Comprare cibo così variegato come lo intende natura." cta_headline: "La spesa che rende il mondo un posto migliore." cta_label: "Sono Pronto" - stats_headline: "Stiamo creando un nuovo sistema del cibo." + stats_headline: "Stiamo creando una nuova filiera del cibo." stats_producers: "produttori" stats_shops: "negozi" stats_shoppers: "clienti" @@ -1393,7 +1401,7 @@ it: order_delivery_address: Indirizzo di consegna order_delivery_time: Tempo di consegna order_special_instructions: "Tue note:" - order_pickup_time: Pronto per la raccolta + order_pickup_time: Pronto per il ritiro order_pickup_instructions: Istruzioni per la raccolta order_produce: Produrre order_total_price: Totale @@ -1462,7 +1470,7 @@ it: email_shipping_delivery_time: "Consegna il" email_shipping_delivery_address: "Indirizzo di consegna" email_shipping_collection_details: Dettagli della raccolta - email_shipping_collection_time: "Pronto per la raccolta:" + email_shipping_collection_time: "Pronto per il ritiro:" email_shipping_collection_instructions: "Istruzioni per la raccolta:" email_special_instructions: "Tue note:" email_signup_greeting: Ciao! @@ -1486,6 +1494,7 @@ it: shopping_oc_closed_description: "Per favore aspetta l'apertura del prossimo ciclo (o contattaci direttamente per sapere se possiamo accettare ordini fuori tempo)" shopping_oc_last_closed: "L'ultimo ciclo è chiuso %{distance_of_time} fa" shopping_oc_next_open: "Il prossimo ciclo aprirà tra %{distance_of_time}" + shopping_oc_select: "Seleziona..." shopping_tabs_home: "Home" shopping_tabs_shop: "Negozio" shopping_tabs_about: "Descrizione" @@ -1859,6 +1868,7 @@ it: headline: "Finito!" thanks: "Grazie per aver riempito i dettagli per %{enterprise}." login: "Puoi cambiare o aggiornare la tua azienda ad ogni passo accedendo a Open Food Network e andando su Amministrazione." + action: "Vai alla dashboard aziendale" back: "Indietro" continue: "Continua" action_or: "O" @@ -1944,6 +1954,7 @@ it: tax_category: "Categoria di imposta" calculator: "Calcolatore" calculator_values: "Valori del calcolatore" + calculator_settings_warning: "Se stai modificando il tipo di calcolatore, devi prima salvare prima di editare i setting del calcolatore" flat_percent_per_item: "Percentuale (per prodotto)" flat_rate_per_item: "Tariffa fissa (per articolo)" flat_rate_per_order: "Tariffa fissa (per gentile richiesta)" @@ -2274,6 +2285,7 @@ it: enterprise_register_success_notice: "Congratulazioni! L registrazione di %{enterprise} è completa!" enterprise_bulk_update_success_notice: "Aziende aggiornate con successo" enterprise_bulk_update_error: 'Aggiornamento fallito' + enterprise_shop_show_error: "Il negozio che stai cercando non esiste o risulta inattivo su OFN. Prego visita altri shop." order_cycles_create_notice: 'Il tuo ciclo di richieste è stato creato.' order_cycles_update_notice: 'Il tuo ciclo di richieste è stato aggiornato' order_cycles_bulk_update_notice: 'I cicli di richieste sono stati aggiornati.' @@ -2347,7 +2359,7 @@ it: alimentare locale attraverso Open Food Network sarà sempre gratuito.. hub_shop: Isola logistica hub_shop_text1: > - La tua azienda è la spina dorsale del vostro sistema alimentare locale. + La tua azienda è la spina dorsale della vostra filiera alimentare locale. Puoi aggregare i prodotti di altre aziende e venderli attraverso il tuo negozio su Open Food Network. hub_shop_text2: > @@ -2431,6 +2443,8 @@ it: exchange_products: load_more_variants: "Carica più Varianti" load_all_variants: "Carica tutte le Varianti" + select_all_variants: "Seleziona tutto %{total_number_of_variants} varianti" + variants_loaded: "%{num_of_variants_loaded} di %{total_number_of_variants} varianti caricate" loading_variants: "Caricamento Varianti" tag_rules: shipping_method_tagged_top: "Metodi di consegna taggati" @@ -2591,9 +2605,78 @@ it: have_an_account: "Hai già un account?" action_login: "Accedi ora." inflections: + each: + one: "ogni" + other: "ogni" bunch: one: "mazzo" other: "grappoli" + pack: + one: "imballare" + other: "confezioni" + box: + one: "scatola" + other: "scatole" + bottle: + one: "bottiglia" + other: "bottiglie" + jar: + one: "vaso" + other: "barattoli" + head: + one: "testa" + other: "teste" + bag: + one: "Borsa" + other: "borse" + loaf: + one: "pagnotta" + other: "pagnotte" + single: + one: "singolo" + other: "singoli" + tub: + one: "vasca" + other: "vasche" + punnet: + one: "cestino" + other: "cestini" + packet: + one: "pacchetto" + other: "pacchetti" + item: + one: "articolo" + other: "elementi" + dozen: + one: "dozzina" + other: "dozzine" + unit: + one: "unità" + other: "unità" + serve: + one: "servire" + other: "porzioni" + tray: + one: "vassoio" + other: "vassoi" + piece: + one: "pezzo" + other: "pezzi" + pot: + one: "pentola" + other: "vasi" + bundle: + one: "fascio" + other: "gruppi" + flask: + one: "borraccia" + other: "fiaschi" + basket: + one: "cestino" + other: "cesti" + sack: + one: "sacco" + other: "sacchi" producers: signup: start_free_profile: "Inizia con un profilo gratuito e migliora quando sei pronto!" @@ -2836,6 +2919,8 @@ it: zipcode: CAP weight: Peso (kg) error_user_destroy_with_orders: "Gli utenti con ordini completi non dovrebbero essere cancellati" + cannot_create_payment_without_payment_methods: "Non è possibile creare un pagamento per un ordine senza alcun metodo di pagamento definito." + please_define_payment_methods: "Definisci prima alcuni metodi di pagamento." options: "Opzioni" actions: update: "Aggiorna" @@ -2922,6 +3007,7 @@ it: capture: "Cattura" ship: "Spedizione" edit: "Modifica" + order_not_updated: "L'ordine non può essere aggiornato" note: "Nota" first: "Primo" last: "Ultimo" @@ -2944,7 +3030,6 @@ it: tax_invoice: "FATTURA DELLE TASSE" code: "Codice" from: "Da" - to: "A" form: distribution_fields: title: "Distribuzione" diff --git a/config/locales/nb.yml b/config/locales/nb.yml index d5849fe3ab..471207ccca 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -19,6 +19,8 @@ nb: shipping_category_id: "Leveringskategori" variant_unit: "Variant Enhet" variant_unit_name: "Enhetsnavn Variant" + spree/credit_card: + base: "Kredittkort" order_cycle: orders_close_at: Lukkedato errors: @@ -861,6 +863,11 @@ nb: cancel: "Avbryt" back_to_list: "Tilbake til Listen" outgoing: + outgoing: "Utgående" + distributor: "Distributør" + products: "Produkter" + tags: "Merkelapper" + fees: "Avgifter" previous: "Tidligere" save: "Lagre" save_and_back_to_list: "Lagre og Tilbake til Listen" @@ -3018,7 +3025,6 @@ nb: tax_invoice: "AVGIFTSFAKTURA" code: "Kode" from: "Fra" - to: "Til" form: distribution_fields: title: "Distribusjon" diff --git a/config/locales/nl_BE.yml b/config/locales/nl_BE.yml index 7ac172e701..d6d40e6fdc 100644 --- a/config/locales/nl_BE.yml +++ b/config/locales/nl_BE.yml @@ -3,7 +3,7 @@ nl_BE: activerecord: attributes: enterprise_fee: - fee_type: Sprookjesachtig type + fee_type: Soort commissie spree/order: payment_state: Status Betaling shipment_state: Status Verzending @@ -19,6 +19,8 @@ nl_BE: shipping_category_id: "Verzendcategorie" variant_unit: "Eénheid" variant_unit_name: "Variant Unit Name" + spree/credit_card: + base: "Kredietkaart" order_cycle: orders_close_at: Sluitingsdatum errors: @@ -839,6 +841,11 @@ nl_BE: next: "Volgende" cancel: "Annuleren" outgoing: + outgoing: "Uitgaande" + distributor: "Distributeur" + products: "Producten" + tags: "Tags" + fees: "Vergoedingen" previous: "Voorgaande" save: "Save" cancel: "Annuleren" @@ -2865,7 +2872,6 @@ nl_BE: tax_invoice: "FACTUUR" code: "Code" from: "Van" - to: "tot" form: distribution_fields: title: "Distributie" diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 40e8f28f91..b5444331ec 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -17,6 +17,8 @@ pt: primary_taxon: "Categoria de Produto" supplier: "Fornecedor" variant_unit: "Unidade da Variante" + spree/credit_card: + base: "Cartão de Crédito" order_cycle: orders_close_at: Data de fecho errors: @@ -826,6 +828,11 @@ pt: next: "Seguinte" cancel: "Cancelar" outgoing: + outgoing: "Saída" + distributor: "Distribuidor" + products: "Produtos" + tags: "Etiquetas" + fees: "Taxas" previous: "Anterior" save: "Guardar" cancel: "Cancelar" @@ -2811,7 +2818,6 @@ pt: tax_invoice: "FACTURA FISCAL" code: "Código" from: "De" - to: "Para" form: distribution_fields: title: "Distribuição" diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index a77ee7cecd..d5dbc46d8d 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -175,7 +175,7 @@ pt_BR: home: "OFB" title: Open Food Brasil welcome_to: 'Bem-vindo a' - site_meta_description: "A gente começa pela base. Com agricultores e produtores preparados para contar suas histórias com orgulho e verdade. Com distribuidores prontos para conectar pessoas com produtos de forma justa e honesta. Com os compradores que acreditam que melhores decisões de compras semanais podem..." + site_meta_description: "A nossa proposta é conectar agricultoras/es, produtoras/es e consumidoras/es que estão próximos entre si. Buscamos, assim, potencializar a circulação e a comercialização de produtos agroecológicos, orgânicos e artesanais em circuitos curtos, bem como criar novas formas de relação, orientadas pela troca, diálogo e confiança." search_by_name: Procurar por nome ou localidade producers_join: Produtores nacionais estão convidados a se unirem à Open Food Brasil. charges_sales_tax: Cobra imposto sobre bens e serviços? @@ -583,7 +583,7 @@ pt_BR: actions_delete: "Deletar selecionado" loading: "Carregando pedidos" no_results: "Nenhum pedido encontrado. " - group_buy_unit_size: "Tamanho de unidade para compras de Grupo" + group_buy_unit_size: "Tamanho da Unidade para Grupo de Compras" total_qtt_ordered: "Quantidade total do pedido" max_qtt_ordered: "Quantidade máxima do pedido" current_fulfilled_units: "Unidades completadas no momento" @@ -598,7 +598,7 @@ pt_BR: title: Iniciativas new_enterprise: Nova iniciativa producer?: "Produtor?" - package: Embalagem + package: Tipo de Perfil status: Status manage: Administrar form: @@ -806,7 +806,7 @@ pt_BR: manage: Administrar manage_link: Configurações producer?: "Produtor?" - package: "Embalagem" + package: "Tipo de Perfil" status: "Status" new_form: owner: Proprietário @@ -861,6 +861,12 @@ pt_BR: cancel: "Cancelar" back_to_list: "Voltar Para a Lista" outgoing: + outgoing: "Saída" + distributor: "Distribuidor" + products: "Produtos" + tags: "Etiqueta" + delivery_details: "Sobre a Entrega" + fees: "Taxas" previous: "Anterior" save: "Salvar" save_and_back_to_list: "Salvar e Voltar para a Lista" @@ -1333,28 +1339,28 @@ pt_BR: cookies_policy_link: "política de cookies" cookies_accept_button: "Aceitar Cookies" home_shop: Compre Agora - brandstory_headline: "Alimentos, com liberdade" - brandstory_intro: "Às vezes, a melhor maneira de consertar o sistema é construir um novo..." - brandstory_part1: "Começamos do início. Com agricultores e produtores preparados para contar com orgulho suas verdadeiras histórias. Com distribuidores prontos para conectar pessoas com produtos de forma justa e honesta. Com consumidores que acreditam que melhores decisões de compras podem mudar seriamente o mundo." - brandstory_part2: "Então precisamos de uma forma para tornar isto real. Uma maneira para empoderar todos os que produzem, vendem e compram alimentos. Uma maneira de contar história e lidar com a logística. Uma maneira de transformar suas compras em mudanças positivas para a sociedade." - brandstory_part3: "Assim construímos um mercado de alimentos mais justo e transparente, por isso criamos relacionamentos reais. Nosso código é aberto, por isso é de todos. Nos multiplicamos por diversas regiões e países, com pessoas criando seus próprios mercados pelo mundo." - brandstory_part4: "É acessível a todos, em qualquer lugar do mundo." - brandstory_part5_strong: "Somos a Open Food Brasil." - brandstory_part6: "Todos amamos comida. Agora a gente também pode amar nosso maneira de consumir. " + brandstory_headline: "Comida de verdade, com autonomia " + brandstory_intro: "Comer é um ato político! Por trás de todo alimento há pessoas, processos e histórias. " + brandstory_part1: "A nossa proposta é conectar agricultoras/es, produtoras/es e consumidoras/es que estão próximos entre si. Buscamos, assim, potencializar a circulação e a comercialização de produtos agroecológicos, orgânicos e artesanais em circuitos curtos, bem como criar novas formas de relação, orientadas pela troca, diálogo e confiança." + brandstory_part2: "Para tornar essa ideia real, trouxemos a plataforma Open Food Network para o Brasil. Nosso código (a receita do site) é aberto e seu desenvolvimento é orientado globalmente pelas/os interessadas/os e baseado em uma cultura de autonomia e transparência." + brandstory_part3: "Uma maneira de incentivar a colaboração entre quem produz, vende e compra. Uma maneira de contar histórias e lidar com a logística. Uma maneira de transformar seu consumo de alimentos em mudanças positivas para a sociedade." + brandstory_part4: "Colabore com essa (des)construção!" + brandstory_part5_strong: "Open Food Brasil" + brandstory_part6: "–" learn_body: "Explore modelos, histórias e recursos para te dar suporte para desenvolver seu próprio negócio ou organização justa de alimentos. Encontre treinamento, eventos e outras oportunidades para aprender com quem faz parte do seu setor. " learn_cta: "Inspire-se" connect_body: "Procure em nossa lista de produtores, distribuidores e cooperativas para encontrar um comércio justo perto de você. Registre seu negócio ou organização na Open Food Brasil para que os consumidores possam te encontrar. Junte-se à comunidade para trocar experiências e resolver problemas." connect_cta: "Explore" - system_headline: "Compras - é assim que funciona:" + system_headline: "Como comprar:" system_step1: "1. Busca" system_step1_text: "Dentre os diversos mercados independentes, escolha o de sua preferência. Procure por região, tipo de alimentos, alimentos locais e sazonais e escolha o método de recebimento que pode ser receber em casa ou retirar no local. " system_step2: "2. Compra" - system_step2_text: "Conheça as histórias por trás da sua comida e as pessoas que as produzem! Transforme suas compras com alimentos locais acessíveis." + system_step2_text: "Conheça as pessoas e as histórias por trás da sua comida. Transforme sua relação com o alimento!" system_step3: "3. Retirada / Entrega" - system_step3_text: "Você escolhe a melhor forma de receber o seu alimentar, aguarde pela sua entrega, ou visite seus produtores ou centrais para uma conexão mais pessoal com seus alimentos." + system_step3_text: "Escolha a forma de recebimento do seu pedido: você pode receber em casa ou retirar no local, assim pode encontrar e conhecer as pessoas envolvidas e estreitar sua relação com as/os agricultoras/es ou as/os mediadoras/es da circulação de produtos. " cta_headline: "Compras que fazem do mundo um lugar melhor." cta_label: "Estou pronto" - stats_headline: "Estamos criando um novo sistema alimentar" + stats_headline: "Estamos trabalhando para relocalizar os sistemas agroalimentares" stats_producers: "produtores de alimentos" stats_shops: "lojas de alimentos" stats_shoppers: "consumidores de alimentos" @@ -1569,7 +1575,7 @@ pt_BR: groups_signup_motivation9: 'Se você precisa de recursos, nós te conectamos a uma rede global de parceiros. ' groups_signup_pricing: Conta de Grupos groups_signup_studies: Estudos de Caso - groups_signup_contact: Pronto para discutir? + groups_signup_contact: Pronto para conversar? groups_signup_contact_text: "Entre em contato para descobrir o que a OFB pode fazer por você" groups_signup_detail: "Aqui está o detalhe. " login_invalid: "E-mail ou senha inválidos" @@ -1628,7 +1634,7 @@ pt_BR: sell_hubs_detail: "Crie um perfil para a sua iniciativa ou organização na Open Food Brasil. A qualquer momento você poderá fazer um upgrade para um mercado de multi-produtores. " sell_groups_detail: "Organize um lista personalizada de negócios (cultivos, cooperativas, comércios, etc.) para sua região ou organização. " sell_user_guide: "Saiba mais acessando nosso guia. " - sell_listing_price: "A listagem no OFN é gratuita. A abertura e administração de uma loja no OFN custa US $ 500 em vendas mensais. Se você vender mais, poderá escolher sua contribuição da comunidade entre 1% e 3% das vendas. Para mais detalhes sobre preços, visite a seção Plataforma do Software através do link Sobre no menu superior." + sell_listing_price: "A OFB está em sua versão beta. Por acreditarmos que a plataforma pode colaborar com a circulação e a comercialização de comida de verdade no período de quarentena imposto pela atual pandemia, sua utilização permanecerá gratuita nos próximos meses." sell_embed: "Também podemos incorporar uma loja da Open Food Brasil em seu próprio site personalizado ou criar um site específico para a sua região. " sell_ask_services: "Pergunte-nos sobre nossos serviços." shops_title: Lojas @@ -1901,7 +1907,7 @@ pt_BR: successfully_updated: '%{resource} foi atualizado com sucesso!' running_balance: "Balanço corrente" outstanding_balance: "Saldo devedor" - admin_enterprise_relationships: "Permissões corporativas" + admin_enterprise_relationships: "Permissões da Iniciativa" admin_enterprise_relationships_everything: "Tudo" admin_enterprise_relationships_permits: "permite" admin_enterprise_relationships_seach_placeholder: "Buscar" @@ -2133,7 +2139,7 @@ pt_BR: report_header_producer: Produtor report_header_producer_suburb: Subúrbio do produtor report_header_unit: Unidade - report_header_group_buy_unit_quantity: Quantidade de unidade de compra em grupo + report_header_group_buy_unit_quantity: Quantidade da Unidade para Grupo de Compras report_header_cost: Custo report_header_shipping_cost: ' Custo de envio' report_header_curr_cost_per_unit: Custo unitário atual @@ -2229,7 +2235,7 @@ pt_BR: adrdress: "Endereço" contact: "Contato" social: "Social" - business_details: "Detalhes do negócio" + business_details: "Detalhes da iniciativa" properties: "Propriedades" shipping: "Envio" shipping_methods: "Métodos de envio" @@ -2271,7 +2277,7 @@ pt_BR: mas não possuem métodos de envio e pagamento válidos. Até que você configure eles, os consumidores não poderão fazer compras nessas centrais. enterprise_fees_update_notice: As tarifas da sua iniciativa foram atualizadas. - enterprise_register_package_error: "Por favor selecione um pacote" + enterprise_register_package_error: "Por favor selecione um tipo de perfil" enterprise_register_error: "Não foi possível completar o registro para %{enterprise}" enterprise_register_success_notice: "Parabéns! O registro para %{enterprise} está completo!" enterprise_bulk_update_success_notice: "Iniciativas atualizadas com sucesso" @@ -2360,7 +2366,7 @@ pt_BR: hub_shop_text3: > Se você também quer vender seus próprios produtos, você precisará mudar essa iniciativa para ser um produtor. - choose_package: Por favor escolha um pacote + choose_package: Por favor escolha um tipo de perfil choose_package_text1: > Sua iniciativa não será totalmente ativada até que um tipo de perfil seja selecionado a partir das opções à esquerda. @@ -3023,7 +3029,8 @@ pt_BR: tax_invoice: "NOTA FISCAL" code: "Código" from: "De" - to: "Para" + to: "Informações de cobrança" + shipping: "Entrega" form: distribution_fields: title: "Distribuição" @@ -3140,7 +3147,7 @@ pt_BR: primary_taxon_form: product_category: Categoria de Produto group_buy_form: - group_buy: "Compra de grupo?" + group_buy: "Grupo de Compras?" bulk_unit_size: Tamanho da unidade em massa display_as: display_as: Mostrar como @@ -3300,7 +3307,7 @@ pt_BR: Se o URL acima não funcionar, tente copiar e colá-lo em seu navegador. Se continuar a ter problemas, por favor não hesite em contactar-nos. confirmation_instructions: - subject: Confirme sua conta OFN + subject: Confirme sua conta na OFB users: form: account_settings: Configurações da conta diff --git a/config/locales/sv.yml b/config/locales/sv.yml index f129bac722..ca90a48659 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -495,6 +495,11 @@ sv: next: "Näst" cancel: "Avbryt" outgoing: + outgoing: "Utgående" + distributor: "Distributör" + products: "Produkter" + tags: "Taggar" + fees: "Avgifter" cancel: "Avbryt" exchange_form: pickup_instructions_placeholder: "Instruktioner för upphämtning" @@ -1972,7 +1977,6 @@ sv: tax_invoice: "FAKTURA" code: "Kod" from: "Från" - to: "Till" form: distribution_fields: title: "Distribution" diff --git a/config/locales/tr.yml b/config/locales/tr.yml index bd09046967..b36a8da76b 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -19,6 +19,8 @@ tr: shipping_category_id: "Nakliye Kategorisi" variant_unit: "Varyant Birimi" variant_unit_name: "Varyant Birim Adı" + spree/credit_card: + base: "Kredi kartı" order_cycle: orders_close_at: Bitiş tarihi errors: @@ -858,6 +860,11 @@ tr: cancel: "İptal et" back_to_list: "Listeye geri dön" outgoing: + outgoing: "Giden" + distributor: "Dağıtımcı" + products: "Ürünler" + tags: "Etiketler" + fees: "Ücretler" previous: "Önceki" save: "Kaydet" save_and_back_to_list: "Kaydet ve Listeye Dön" @@ -3010,7 +3017,6 @@ tr: tax_invoice: "VERGİ FATURASI" code: "Kod" from: "İtibaren" - to: "Şu vakte kadar" form: distribution_fields: title: "Dağıtım" diff --git a/db/migrate/20200327105910_change_versions_custom_data_to_text.rb b/db/migrate/20200327105910_change_versions_custom_data_to_text.rb new file mode 100644 index 0000000000..0a995a85f4 --- /dev/null +++ b/db/migrate/20200327105910_change_versions_custom_data_to_text.rb @@ -0,0 +1,9 @@ +class ChangeVersionsCustomDataToText < ActiveRecord::Migration + def up + change_column :versions, :custom_data, :text + end + + def down + change_column :versions, :custom_data, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 2dbc55de89..36cd344ea1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(:version => 20200209163549) do +ActiveRecord::Schema.define(:version => 20200327105910) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1207,7 +1207,7 @@ ActiveRecord::Schema.define(:version => 20200209163549) do t.string "whodunnit" t.text "object" t.datetime "created_at" - t.string "custom_data" + t.text "custom_data" end add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id", using: :btree diff --git a/engines/web/spec/helpers/cookies_policy_helper_spec.rb b/engines/web/spec/helpers/cookies_policy_helper_spec.rb index b4d7f7fdf3..9c333b363f 100644 --- a/engines/web/spec/helpers/cookies_policy_helper_spec.rb +++ b/engines/web/spec/helpers/cookies_policy_helper_spec.rb @@ -33,6 +33,14 @@ module Web end describe "language from locale" do + # keeps global state unchanged + around do |example| + original_available_locales = I18n.available_locales + I18n.available_locales = ['en', 'en_GB', ''] + example.run + I18n.available_locales = original_available_locales + end + scenario "when locale is the language" do I18n.locale = "en" expect(helper.locale_language).to eq "en" diff --git a/lib/open_food_network/bulk_coop_report.rb b/lib/open_food_network/bulk_coop_report.rb index e4a89dbbe5..019dcddbb7 100644 --- a/lib/open_food_network/bulk_coop_report.rb +++ b/lib/open_food_network/bulk_coop_report.rb @@ -128,7 +128,7 @@ module OpenFoodNetwork def order_permissions return @order_permissions unless @order_permissions.nil? - @order_permissions = ::Permissions::Order.new(@user) + @order_permissions = ::Permissions::Order.new(@user, @params[:q]) end def report_line_items diff --git a/lib/open_food_network/enterprise_injection_data.rb b/lib/open_food_network/enterprise_injection_data.rb index 3f23ff7a0a..8bc386b2a6 100644 --- a/lib/open_food_network/enterprise_injection_data.rb +++ b/lib/open_food_network/enterprise_injection_data.rb @@ -1,7 +1,8 @@ module OpenFoodNetwork class EnterpriseInjectionData - def active_distributors - @active_distributors ||= Enterprise.distributors_with_active_order_cycles.ready_for_checkout + def active_distributor_ids + @active_distributor_ids ||= + Enterprise.distributors_with_active_order_cycles.ready_for_checkout.pluck(:id) end def earliest_closing_times diff --git a/lib/open_food_network/order_and_distributor_report.rb b/lib/open_food_network/order_and_distributor_report.rb index 64f46f41d1..b705c0cb16 100644 --- a/lib/open_food_network/order_and_distributor_report.rb +++ b/lib/open_food_network/order_and_distributor_report.rb @@ -5,7 +5,7 @@ module OpenFoodNetwork @user = user @render_table = render_table - @permissions = ::Permissions::Order.new(user) + @permissions = ::Permissions::Order.new(user, @params[:q]) end def header diff --git a/lib/open_food_network/orders_and_fulfillments_report.rb b/lib/open_food_network/orders_and_fulfillments_report.rb index fbac2f6551..90b0ff59c9 100644 --- a/lib/open_food_network/orders_and_fulfillments_report.rb +++ b/lib/open_food_network/orders_and_fulfillments_report.rb @@ -83,7 +83,7 @@ module OpenFoodNetwork def order_permissions return @order_permissions unless @order_permissions.nil? - @order_permissions = ::Permissions::Order.new(@user) + @order_permissions = ::Permissions::Order.new(@user, options[:q]) end def report_line_items diff --git a/lib/open_food_network/packing_report.rb b/lib/open_food_network/packing_report.rb index b9f9bc7f52..cecec8cff8 100644 --- a/lib/open_food_network/packing_report.rb +++ b/lib/open_food_network/packing_report.rb @@ -128,7 +128,7 @@ module OpenFoodNetwork def order_permissions return @order_permissions unless @order_permissions.nil? - @order_permissions = ::Permissions::Order.new(@user) + @order_permissions = ::Permissions::Order.new(@user, @params[:q]) end def is_temperature_controlled?(line_item) diff --git a/lib/open_food_network/reports/line_items.rb b/lib/open_food_network/reports/line_items.rb index 59d9901552..93c5fba9de 100644 --- a/lib/open_food_network/reports/line_items.rb +++ b/lib/open_food_network/reports/line_items.rb @@ -12,9 +12,7 @@ module OpenFoodNetwork end def list(line_item_includes = nil) - line_items = @order_permissions. - visible_line_items. - merge(Spree::LineItem.where(order_id: orders.result)) + line_items = @order_permissions.visible_line_items.in_orders(orders.result) if @params[:supplier_id_in].present? line_items = line_items.supplied_by_any(@params[:supplier_id_in]) diff --git a/spec/controllers/admin/bulk_line_items_controller_spec.rb b/spec/controllers/admin/bulk_line_items_controller_spec.rb index 6b7fe5bff4..941b44eb0c 100644 --- a/spec/controllers/admin/bulk_line_items_controller_spec.rb +++ b/spec/controllers/admin/bulk_line_items_controller_spec.rb @@ -36,22 +36,21 @@ describe Admin::BulkLineItemsController, type: :controller do end it "retrieves a list of line_items with appropriate attributes, including line items with appropriate attributes" do - keys = json_response.first.keys.map(&:to_sym) + keys = json_response['line_items'].first.keys.map(&:to_sym) expect(line_item_attributes.all?{ |attr| keys.include? attr }).to eq(true) end it "sorts line_items in ascending id line_item" do - ids = json_response.map{ |line_item| line_item['id'] } - expect(ids[0]).to be < ids[1] - expect(ids[1]).to be < ids[2] + expect(line_item_ids[0]).to be < line_item_ids[1] + expect(line_item_ids[1]).to be < line_item_ids[2] end it "formats final_weight_volume as a float" do - expect(json_response.map{ |line_item| line_item['final_weight_volume'] }.all?{ |fwv| fwv.is_a?(Float) }).to eq(true) + expect(json_response['line_items'].map{ |line_item| line_item['final_weight_volume'] }.all?{ |fwv| fwv.is_a?(Float) }).to eq(true) end it "returns distributor object with id key" do - expect(json_response.map{ |line_item| line_item['supplier'] }.all?{ |d| d.key?('id') }).to eq(true) + expect(json_response['line_items'].map{ |line_item| line_item['supplier'] }.all?{ |d| d.key?('id') }).to eq(true) end end @@ -61,7 +60,7 @@ describe Admin::BulkLineItemsController, type: :controller do end it "retrives a list of line items which match the criteria" do - expect(json_response.map{ |line_item| line_item['id'] }).to eq [line_item2.id, line_item3.id] + expect(line_item_ids).to eq [line_item2.id, line_item3.id] end end @@ -71,7 +70,7 @@ describe Admin::BulkLineItemsController, type: :controller do end it "retrives a list of line items whose orders match the criteria" do - expect(json_response.map{ |line_item| line_item['id'] }).to eq [line_item2.id, line_item3.id, line_item4.id] + expect(line_item_ids).to eq [line_item2.id, line_item3.id, line_item4.id] end end end @@ -106,7 +105,7 @@ describe Admin::BulkLineItemsController, type: :controller do end it "retrieves a list of line_items" do - keys = json_response.first.keys.map(&:to_sym) + keys = json_response['line_items'].first.keys.map(&:to_sym) expect(line_item_attributes.all?{ |attr| keys.include? attr }).to eq(true) end end @@ -118,11 +117,37 @@ describe Admin::BulkLineItemsController, type: :controller do end it "retrieves a list of line_items" do - keys = json_response.first.keys.map(&:to_sym) + keys = json_response['line_items'].first.keys.map(&:to_sym) expect(line_item_attributes.all?{ |attr| keys.include? attr }).to eq(true) end end end + + context "paginating" do + before do + allow(controller).to receive_messages spree_current_user: create(:admin_user) + end + + context "with pagination args" do + it "returns paginated results" do + spree_get :index, { page: 1, per_page: 2 }, format: :json + + expect(line_item_ids).to eq [line_item1.id, line_item2.id] + expect(json_response['pagination']).to eq( + { 'page' => 1, 'per_page' => 2, 'pages' => 2, 'results' => 4 } + ) + end + + it "returns paginated results for a second page" do + spree_get :index, { page: 2, per_page: 2 }, format: :json + + expect(line_item_ids).to eq [line_item3.id, line_item4.id] + expect(json_response['pagination']).to eq( + { 'page' => 2, 'per_page' => 2, 'pages' => 2, 'results' => 4 } + ) + end + end + end end describe '#update' do @@ -259,4 +284,10 @@ describe Admin::BulkLineItemsController, type: :controller do end end end + + private + + def line_item_ids + json_response['line_items'].map{ |line_item| line_item['id'] } + end end diff --git a/spec/controllers/checkout_controller_spec.rb b/spec/controllers/checkout_controller_spec.rb index b11ca1ab78..ccbf458674 100644 --- a/spec/controllers/checkout_controller_spec.rb +++ b/spec/controllers/checkout_controller_spec.rb @@ -197,13 +197,13 @@ describe CheckoutController, type: :controller do allow(controller).to receive(:current_order).and_return(order) end - it "returns errors" do + it "returns errors and flash if order.update_attributes fails" do spree_post :update, format: :json, order: {} expect(response.status).to eq(400) - expect(response.body).to eq({ errors: assigns[:order].errors, flash: {} }.to_json) + expect(response.body).to eq({ errors: assigns[:order].errors, flash: { error: order.errors.full_messages.to_sentence } }.to_json) end - it "returns flash" do + it "returns errors and flash if order.next fails" do allow(order).to receive(:update_attributes).and_return true allow(order).to receive(:next).and_return false spree_post :update, format: :json, order: {} diff --git a/spec/controllers/shops_controller_spec.rb b/spec/controllers/shops_controller_spec.rb index 2cecfc2c96..023e7b0245 100644 --- a/spec/controllers/shops_controller_spec.rb +++ b/spec/controllers/shops_controller_spec.rb @@ -7,7 +7,7 @@ describe ShopsController, type: :controller do let!(:distributor) { create(:distributor_enterprise) } before do - allow(Enterprise).to receive_message_chain(:distributors_with_active_order_cycles, :ready_for_checkout) { [distributor] } + allow(OpenFoodNetwork::EnterpriseInjectionData).to receive(:active_distributor_ids) { [distributor.id] } end it 'renders distributed product properties' do diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index ffe17400f4..a92afed022 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -494,7 +494,7 @@ feature ' it "shows a dialog and ignores changes when confirm dialog is accepted" do page.driver.accept_modal :confirm, text: "Unsaved changes exist and will be lost if you continue." do - fill_in "start_date_filter", with: (Date.current - 9).strftime("%F %T") + fill_in "start_date_filter", with: (Date.current - 9).strftime('%Y-%m-%d') end expect(page).to have_no_selector "#save-bar" within("tr#li_#{li2.id} td.quantity") do @@ -577,6 +577,7 @@ feature ' find("div#bulk-actions-dropdown").click find("div#bulk-actions-dropdown div.menu_item", text: "Delete Selected" ).click expect(page).to have_no_selector "tr#li_#{li1.id}" + expect(page).to have_selector "#quick_search" fill_in "quick_search", with: '' wait_until { request_monitor_finished 'LineItemsCtrl' } expect(page).to have_selector "tr#li_#{li2.id}" diff --git a/spec/features/admin/properties_spec.rb b/spec/features/admin/properties_spec.rb new file mode 100644 index 0000000000..905810039e --- /dev/null +++ b/spec/features/admin/properties_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require "spec_helper" + +feature ' + As an admin + I want to manage product properties +' do + include AuthenticationWorkflow + + scenario "creating and editing a property" do + login_to_admin_section + visit spree.admin_properties_path + + click_link 'New Property' + fill_in 'property_name', with: 'New property!' + fill_in 'property_presentation', with: 'New property presentation!' + click_button 'Create' + expect(page).to have_content 'New property!' + + page.find('td.actions a.icon-edit').click + expect(page).to have_field 'property_name', with: 'New property!' + fill_in 'property_name', with: 'New changed property!' + click_button 'Update' + expect(page).to have_content 'New changed property!' + end +end diff --git a/spec/features/consumer/shopping/embedded_shopfronts_spec.rb b/spec/features/consumer/shopping/embedded_shopfronts_spec.rb index 4a70dbf672..290c6af516 100644 --- a/spec/features/consumer/shopping/embedded_shopfronts_spec.rb +++ b/spec/features/consumer/shopping/embedded_shopfronts_spec.rb @@ -53,7 +53,7 @@ feature "Using embedded shopfront functionality", js: true do expect(page).to have_text 'Your shopping cart' find('a#checkout-link').click - expect(page).to have_text 'Checkout now' + expect(page).to have_text 'Ok, ready to checkout?' click_button 'Login' login_with_modal diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index 989eea5e4e..b8a6727727 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -27,7 +27,9 @@ feature "As a consumer I want to shop with a distributor", js: true do # Then we should see the distributor and its logo visit shop_path expect(page).to have_text distributor.name - find("#tab_about a").click + within ".tab-buttons" do + click_link "About" + end expect(first("distributor img")['src']).to include distributor.logo.url(:thumb) end @@ -36,7 +38,9 @@ feature "As a consumer I want to shop with a distributor", js: true do add_variant_to_order_cycle(exchange, variant) visit shop_path - find("#tab_producers a").click + within ".tab-buttons" do + click_link "Producers" + end expect(page).to have_content supplier.name end diff --git a/spec/javascripts/application_spec.js b/spec/javascripts/application_spec.js index 37194fc2b5..47368298f8 100644 --- a/spec/javascripts/application_spec.js +++ b/spec/javascripts/application_spec.js @@ -16,5 +16,5 @@ //= require i18n angular.module('templates', []) -angular.module('google-maps', []); +angular.module('uiGmapgoogle-maps', []); angular.module('duScroll', []); diff --git a/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee b/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee index 3b04893b34..a1808b5264 100644 --- a/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee @@ -13,23 +13,23 @@ describe "LineItemsCtrl", -> compare: (actual, expected) -> { pass: angular.equals(actual, expected) } - beforeEach inject(($controller, $rootScope, $httpBackend, _$timeout_, _VariantUnitManager_, _Enterprises_, _Orders_, _LineItems_, _OrderCycles_) -> + beforeEach inject(($controller, $rootScope, $httpBackend, _$timeout_, _VariantUnitManager_, _Enterprises_, _Orders_, _OrderCycles_) -> scope = $rootScope.$new() ctrl = $controller $timeout = _$timeout_ httpBackend = $httpBackend Enterprises = _Enterprises_ Orders = _Orders_ - LineItems = _LineItems_ OrderCycles = _OrderCycles_ VariantUnitManager = _VariantUnitManager_ - momentMock = jasmine.createSpyObj('moment', ['format', 'startOf', 'endOf', 'subtract', 'add']) + momentMock = jasmine.createSpyObj('moment', ['format', 'startOf', 'endOf', 'subtract', 'add', 'isValid']) spyOn(window,"moment").and.returnValue momentMock momentMock.startOf.and.returnValue momentMock momentMock.endOf.and.returnValue momentMock momentMock.subtract.and.returnValue momentMock momentMock.add.and.returnValue momentMock momentMock.format.and.returnValue "SomeDate" + momentMock.isValid.and.returnValue true supplier = { id: 1, name: "Supplier" } distributor = { id: 5, name: "Distributor" } @@ -37,8 +37,11 @@ describe "LineItemsCtrl", -> order = { id: 9, order_cycle: { id: 4 }, distributor: { id: 5 }, number: "R123456" } lineItem = { id: 7, quantity: 3, order: { id: 9 }, supplier: { id: 1 } } - httpBackend.expectGET("/api/orders.json?q%5Bcompleted_at_gteq%5D=SomeDate&q%5Bcompleted_at_lt%5D=SomeDate&q%5Bcompleted_at_not_null%5D=true&q%5Bstate_not_eq%5D=canceled").respond {orders: [order], pagination: {page: 1, pages: 1, results: 1}} - httpBackend.expectGET("/admin/bulk_line_items.json?q%5Border%5D%5Bcompleted_at_gteq%5D=SomeDate&q%5Border%5D%5Bcompleted_at_lt%5D=SomeDate&q%5Border%5D%5Bcompleted_at_not_null%5D=true&q%5Border%5D%5Bstate_not_eq%5D=canceled").respond [lineItem] + LineItems = + index: jasmine.createSpy('index').and.returnValue(lineItem) + all: [lineItem] + + httpBackend.expectGET("/api/orders.json?q%5Bcompleted_at_gteq%5D=SomeDate&q%5Bcompleted_at_lt%5D=SomeDate&q%5Bcompleted_at_not_null%5D=true&q%5Bdistributor_id_eq%5D=&q%5Border_cycle_id_eq%5D=&q%5Bstate_not_eq%5D=canceled").respond {orders: [order], pagination: {page: 1, pages: 1, results: 1}} httpBackend.expectGET("/admin/enterprises/visible.json?ams_prefix=basic&q%5Bsells_in%5D%5B%5D=own&q%5Bsells_in%5D%5B%5D=any").respond [distributor] httpBackend.expectGET("/admin/order_cycles.json?ams_prefix=basic&as=distributor&q%5Borders_close_at_gt%5D=SomeDate").respond [orderCycle] httpBackend.expectGET("/admin/enterprises/visible.json?ams_prefix=basic&q%5Bis_primary_producer_eq%5D=true").respond [supplier] @@ -52,12 +55,6 @@ describe "LineItemsCtrl", -> it "the RequestMonitor will have a state of loading", -> expect(scope.RequestMonitor.loading).toBe true - it "will not have reset the select filters", -> - expect(scope.distributorFilter).toBeUndefined() - expect(scope.supplierFilter).toBeUndefined() - expect(scope.orderCycleFilter).toBeUndefined() - expect(scope.quickSearch).toBeUndefined() - it "will not have reset the form state to pristine", -> expect(scope.bulk_order_form.$setPristine.calls.count()).toBe 0 @@ -83,49 +80,20 @@ describe "LineItemsCtrl", -> expect(scope.orders).toDeepEqual [ { id: 9, order_cycle: orderCycle, distributor: distributor, number: "R123456" } ] it "gets line_items, with dereferenced orders and suppliers", -> - expect(scope.lineItems).toDeepEqual [ { id: 7, quantity: 3, order: scope.orders[0], supplier: supplier } ] + expect(scope.line_items).toDeepEqual [ { id: 7, quantity: 3, order: scope.orders[0], supplier: supplier } ] it "the RequestMonitor will have a state of loaded", -> expect(scope.RequestMonitor.loading).toBe false it "resets the select filters", -> - expect(scope.distributorFilter).toBe 0 - expect(scope.supplierFilter).toBe 0 - expect(scope.orderCycleFilter).toBe 0 + expect(scope.distributorFilter).toBe '' + expect(scope.supplierFilter).toBe '' + expect(scope.orderCycleFilter).toBe '' expect(scope.quickSearch).toBe = "" it "resets the form state to pristine", -> expect(scope.bulk_order_form.$setPristine.calls.count()).toBe 1 - describe "deleting a line item", -> - order = line_item1 = line_item2 = null - - beforeEach inject((LineItemResource) -> - spyOn(window,"confirm").and.returnValue true - order = { number: "R12345678" } - line_item1 = new LineItemResource({ id: 1, order: order }) - line_item2 = new LineItemResource({ id: 2, order: order }) - scope.lineItems= [ line_item1, line_item2 ] - ) - - describe "where the request is successful", -> - beforeEach -> - httpBackend.expectDELETE("/admin/bulk_line_items/1.json").respond "nothing" - scope.deleteLineItem line_item1 - httpBackend.flush() - - it "removes the deleted item from the line_items array", -> - expect(scope.lineItems).toEqual [line_item2] - - describe "where the request is unsuccessful", -> - beforeEach -> - httpBackend.expectDELETE("/admin/bulk_line_items/1.json").respond 404, "NO CONTENT" - scope.deleteLineItem line_item1 - httpBackend.flush() - - it "does not remove line_item from the line_items array", -> - expect(scope.lineItems).toEqual [line_item1, line_item2] - describe "deleting 'checked' line items", -> line_item1 = line_item2 = line_item3 = line_item4 = null @@ -134,11 +102,11 @@ describe "LineItemsCtrl", -> line_item2 = { name: "line item 2", checked: true } line_item3 = { name: "line item 3", checked: false } line_item4 = { name: "line item 4", checked: true } - scope.lineItems = [ line_item1, line_item2, line_item3, line_item4 ] + scope.line_items = [ line_item1, line_item2, line_item3, line_item4 ] it "calls deletedLineItem for each 'checked' line item", -> spyOn(scope, "deleteLineItem") - scope.deleteLineItems(scope.lineItems) + scope.deleteLineItems(scope.line_items) expect(scope.deleteLineItem).toHaveBeenCalledWith(line_item2) expect(scope.deleteLineItem).toHaveBeenCalledWith(line_item4) expect(scope.deleteLineItem).not.toHaveBeenCalledWith(line_item1) diff --git a/spec/javascripts/unit/admin/line_items/services/line_items_spec.js.coffee b/spec/javascripts/unit/admin/line_items/services/line_items_spec.js.coffee index 7367e06d88..08456b2748 100644 --- a/spec/javascripts/unit/admin/line_items/services/line_items_spec.js.coffee +++ b/spec/javascripts/unit/admin/line_items/services/line_items_spec.js.coffee @@ -1,5 +1,5 @@ describe "LineItems service", -> - LineItems = LineItemResource = lineItems = $httpBackend = null + LineItems = LineItemResource = lineItems = $httpBackend = $rootScope = $timeout = null beforeEach -> module 'admin.lineItems' @@ -15,24 +15,27 @@ describe "LineItems service", -> $httpBackend = _$httpBackend_ describe "#index", -> - result = response = null + result = response = line_item = null beforeEach -> - response = [{ id: 5, name: 'LineItem 1'}] + line_item = { id: 5, name: 'LineItem 1'} + response = { line_items: [line_item] } $httpBackend.expectGET('/admin/bulk_line_items.json').respond 200, response result = LineItems.index() $httpBackend.flush() it "stores returned data in @byID, with ids as keys", -> # LineItemResource returns instances of Resource rather than raw objects - expect(LineItems.byID).toDeepEqual { 5: response[0] } + expect(LineItems.byID).toDeepEqual { 5: response['line_items'][0] } it "stores returned data in @pristineByID, with ids as keys", -> - expect(LineItems.pristineByID).toDeepEqual { 5: response[0] } + expect(LineItems.pristineByID).toDeepEqual { 5: response['line_items'][0] } + + it "stores returned data in @all, as an array", -> + expect(LineItems.all).toDeepEqual [line_item] it "returns an array of line items", -> - expect(result).toDeepEqual response - + expect(result).toDeepEqual [line_item] describe "#save", -> describe "success", -> @@ -115,6 +118,7 @@ describe "LineItems service", -> lineItem = new LineItemResource({ id: 15, order: { number: '12345678'} }) LineItems.pristineByID[15] = lineItem LineItems.byID[15] = lineItem + LineItems.all = [lineItem] $httpBackend.expectDELETE('/admin/bulk_line_items/15.json').respond 200, { id: 15, name: 'LineItem 1'} LineItems.delete(lineItem, callback).then( -> resolved = true).catch( -> rejected = true) $httpBackend.flush() @@ -122,6 +126,7 @@ describe "LineItems service", -> it "updates the pristine copy of the lineItem", -> expect(LineItems.pristineByID[15]).toBeUndefined() expect(LineItems.byID[15]).toBeUndefined() + expect(LineItems.all).toEqual([]) it "runs the callback", -> expect(callback).toHaveBeenCalled() diff --git a/spec/javascripts/unit/darkswarm/services/stripe_elements_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/stripe_elements_spec.js.coffee index 0252298f82..821df4b153 100644 --- a/spec/javascripts/unit/darkswarm/services/stripe_elements_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/stripe_elements_spec.js.coffee @@ -46,17 +46,23 @@ describe 'StripeElements Service', -> it "doesn't submit the form, shows an error message instead", inject (Loading, RailsFlashLoader) -> spyOn(Loading, "clear") spyOn(RailsFlashLoader, "loadFlash") - StripeElements.requestToken(secrets, submit) - $rootScope.$digest() # required for #then to by called - expect(submit).not.toHaveBeenCalled() - expect(Loading.clear).toHaveBeenCalled() - expect(RailsFlashLoader.loadFlash).toHaveBeenCalledWith({error: "Error: There was a problem"}) + StripeElements.requestToken(secrets, submit).then (data) -> + expect(submit).not.toHaveBeenCalled() + expect(Loading.clear).toHaveBeenCalled() + expect(RailsFlashLoader.loadFlash).toHaveBeenCalledWith({error: "Error: There was a problem"}) - describe 'mapCC', -> - it "maps the brand returned by Stripe to that required by activemerchant", -> - expect(StripeElements.mapCC('MasterCard')).toEqual "master" - expect(StripeElements.mapCC('Visa')).toEqual "visa" - expect(StripeElements.mapCC('American Express')).toEqual "american_express" - expect(StripeElements.mapCC('Discover')).toEqual "discover" - expect(StripeElements.mapCC('JCB')).toEqual "jcb" - expect(StripeElements.mapCC('Diners Club')).toEqual "diners_club" + describe 'mapTokenApiCardBrand', -> + it "maps the brand returned by Stripe's tokenAPI to that required by activemerchant", -> + expect(StripeElements.mapTokenApiCardBrand('MasterCard')).toEqual "master" + expect(StripeElements.mapTokenApiCardBrand('Visa')).toEqual "visa" + expect(StripeElements.mapTokenApiCardBrand('American Express')).toEqual "american_express" + expect(StripeElements.mapTokenApiCardBrand('Discover')).toEqual "discover" + expect(StripeElements.mapTokenApiCardBrand('JCB')).toEqual "jcb" + expect(StripeElements.mapTokenApiCardBrand('Diners Club')).toEqual "diners_club" + + describe 'mapPaymentMethodsApiCardBrand', -> + it "maps the brand returned by Stripe's paymentMethodsAPI to that required by activemerchant", -> + expect(StripeElements.mapPaymentMethodsApiCardBrand('mastercard')).toEqual "master" + expect(StripeElements.mapPaymentMethodsApiCardBrand('amex')).toEqual "american_express" + expect(StripeElements.mapPaymentMethodsApiCardBrand('diners')).toEqual "diners_club" + expect(StripeElements.mapPaymentMethodsApiCardBrand('visa')).toEqual "visa" diff --git a/spec/models/calculator/weight_spec.rb b/spec/models/calculator/weight_spec.rb index 94f7d1b498..1ca1759b40 100644 --- a/spec/models/calculator/weight_spec.rb +++ b/spec/models/calculator/weight_spec.rb @@ -19,8 +19,8 @@ describe Calculator::Weight do end describe "line item with variant_unit weight and variant unit_value" do - let(:variant) { build(:variant, unit_value: 10_000) } - let(:line_item) { build(:line_item, variant: variant, quantity: 2) } + let(:variant) { create(:variant, unit_value: 10_000) } + let(:line_item) { create(:line_item, variant: variant, quantity: 2) } before { subject.set_preference(:per_kg, 5) } @@ -46,11 +46,11 @@ describe Calculator::Weight do end it "computes shipping cost for an object with an order" do - variant1 = build(:variant, unit_value: 10_000) - variant2 = build(:variant, unit_value: 20_000) + variant1 = create(:variant, unit_value: 10_000) + variant2 = create(:variant, unit_value: 20_000) - line_item1 = build(:line_item, variant: variant1, quantity: 1) - line_item2 = build(:line_item, variant: variant2, quantity: 2) + line_item1 = create(:line_item, variant: variant1, quantity: 1) + line_item2 = create(:line_item, variant: variant2, quantity: 2) order = double(:order, line_items: [line_item1, line_item2]) object_with_order = double(:object_with_order, order: order) @@ -65,7 +65,7 @@ describe Calculator::Weight do let(:calculator) { described_class.new(preferred_per_kg: 6) } let(:line_item) do - build(:line_item, variant: variant, quantity: 2).tap do |object| + create(:line_item, variant: variant, quantity: 2).tap do |object| object.send(:calculate_final_weight_volume) end end @@ -141,7 +141,7 @@ describe Calculator::Weight do end context "when the product uses item unit" do - let!(:product_attributes) { { variant_unit: "items", variant_unit_scale: nil, variant_unit: "pc", display_as: "pc" } } + let!(:product_attributes) { { variant_unit: "items", variant_unit_scale: nil, variant_unit_name: "pc", display_as: "pc" } } let!(:variant_attributes) { { unit_value: 3.0, weight: 2.5, display_as: "pc" } } it "is correct" do @@ -151,4 +151,53 @@ describe Calculator::Weight do end end end + + context "when variant_unit is 'items'" do + let(:product) { + create(:product, variant_unit: 'items', variant_unit_scale: nil, variant_unit_name: "bunch") + } + let(:line_item) { create(:line_item, variant: variant, quantity: 1) } + + before { subject.set_preference(:per_kg, 5) } + + context "when unit_value is zero variant.weight is present" do + let(:variant) { create(:variant, product: product, unit_value: 0, weight: 10.0) } + + it "uses the variant weight" do + expect(subject.compute(line_item)).to eq 50.0 + end + end + + context "when unit_value is zero variant.weight is nil" do + let(:variant) { create(:variant, product: product, unit_value: 0, weight: nil) } + + it "uses zero weight" do + expect(subject.compute(line_item)).to eq 0 + end + end + + context "when unit_value is nil and variant.weight is present" do + let(:variant) { + create(:variant, product: product, unit_description: "bunches", unit_value: nil, weight: 10.0) + } + + it "uses the variant weight" do + line_item.final_weight_volume = 1 + + expect(subject.compute(line_item)).to eq 50.0 + end + end + + context "when unit_value is nil and variant.weight is nil" do + let(:variant) { + create(:variant, product: product, unit_description: "bunches", unit_value: nil, weight: nil) + } + + it "uses zero weight" do + line_item.final_weight_volume = 1 + + expect(subject.compute(line_item)).to eq 0 + end + end + end end diff --git a/spec/models/spree/line_item_spec.rb b/spec/models/spree/line_item_spec.rb index f2f5cd7164..4873a78d59 100644 --- a/spec/models/spree/line_item_spec.rb +++ b/spec/models/spree/line_item_spec.rb @@ -40,10 +40,13 @@ module Spree describe "finding line items with and without tax" do let(:tax_rate) { create(:tax_rate, calculator: Spree::Calculator::DefaultTax.new) } - let!(:adjustment1) { create(:adjustment, adjustable: li1, originator: tax_rate, label: "TR", amount: 123, included_tax: 10.00) } - let!(:adjustment2) { create(:adjustment, adjustable: li1, originator: tax_rate, label: "TR", amount: 123, included_tax: 10.00) } + let!(:adjustment1) { create(:adjustment, originator: tax_rate, label: "TR", amount: 123, included_tax: 10.00) } - before { li1; li2 } + before do + li1 + li2 + li1.adjustments << adjustment1 + end it "finds line items with tax" do expect(LineItem.with_tax).to eq([li1]) diff --git a/spec/models/spree/product_set_spec.rb b/spec/models/spree/product_set_spec.rb index ee5364bbd2..d81f139908 100644 --- a/spec/models/spree/product_set_spec.rb +++ b/spec/models/spree/product_set_spec.rb @@ -12,7 +12,6 @@ describe Spree::ProductSet do let(:collection_hash) do { 0 => { - product_id: 11, name: 'a product', price: 2.0, supplier_id: create(:enterprise).id, @@ -25,11 +24,10 @@ describe Spree::ProductSet do } end - it 'creates it with the specified attributes' do + it 'does not create a new product' do product_set.save - expect(Spree::Product.last.attributes) - .to include('name' => 'a product') + expect(Spree::Product.last).to be nil end end diff --git a/spec/models/spree/user_spec.rb b/spec/models/spree/user_spec.rb index f9fcd95056..0a5d8c439b 100644 --- a/spec/models/spree/user_spec.rb +++ b/spec/models/spree/user_spec.rb @@ -76,9 +76,11 @@ describe Spree.user_class do it "should send a confirmation email" do setup_email - expect do - create(:user, email: 'new_user@example.com', confirmation_sent_at: nil, confirmed_at: nil) - end.to send_confirmation_instructions + performing_deliveries do + expect do + create(:user, email: 'new_user@example.com', confirmation_sent_at: nil, confirmed_at: nil) + end.to send_confirmation_instructions + end sent_mail = ActionMailer::Base.deliveries.last expect(sent_mail.to).to eq ['new_user@example.com'] diff --git a/spec/serializers/api/cached_enterprise_serializer_spec.rb b/spec/serializers/api/cached_enterprise_serializer_spec.rb index e46b0006b9..c4e5624fa8 100644 --- a/spec/serializers/api/cached_enterprise_serializer_spec.rb +++ b/spec/serializers/api/cached_enterprise_serializer_spec.rb @@ -50,7 +50,7 @@ describe Api::CachedEnterpriseSerializer do context 'when the enterprise is not an active distributor' do let(:enterprise_injection_data) do - instance_double(OpenFoodNetwork::EnterpriseInjectionData, active_distributors: []) + instance_double(OpenFoodNetwork::EnterpriseInjectionData, active_distributor_ids: []) end it 'does not duplicate properties' do @@ -69,7 +69,7 @@ describe Api::CachedEnterpriseSerializer do context 'when the enterprise is an active distributor' do let(:enterprise_injection_data) do - instance_double(OpenFoodNetwork::EnterpriseInjectionData, active_distributors: [shop]) + instance_double(OpenFoodNetwork::EnterpriseInjectionData, active_distributor_ids: [shop.id]) end it 'does not duplicate properties' do diff --git a/spec/services/permissions/order_spec.rb b/spec/services/permissions/order_spec.rb index 1ccb6648ec..d60d6968e2 100644 --- a/spec/services/permissions/order_spec.rb +++ b/spec/services/permissions/order_spec.rb @@ -5,14 +5,21 @@ module Permissions let(:user) { double(:user) } let(:permissions) { Permissions::Order.new(user) } let!(:basic_permissions) { OpenFoodNetwork::Permissions.new(user) } + let(:distributor) { create(:distributor_enterprise) } + let(:coordinator) { create(:distributor_enterprise) } + let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, distributors: [distributor]) } + let(:order_completed) { create(:completed_order_with_totals, order_cycle: order_cycle, distributor: distributor ) } + let(:order_cancelled) { create(:order, order_cycle: order_cycle, distributor: distributor, state: 'canceled' ) } + let(:order_cart) { create(:order, order_cycle: order_cycle, distributor: distributor, state: 'cart' ) } + let(:order_from_last_year) { + create(:completed_order_with_totals, order_cycle: order_cycle, distributor: distributor, + completed_at: Time.zone.now - 1.year) + } before { allow(OpenFoodNetwork::Permissions).to receive(:new) { basic_permissions } } describe "finding orders that are visible in reports" do - let(:distributor) { create(:distributor_enterprise) } - let(:coordinator) { create(:distributor_enterprise) } let(:random_enterprise) { create(:distributor_enterprise) } - let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, distributors: [distributor]) } let(:order) { create(:order, order_cycle: order_cycle, distributor: distributor ) } let!(:line_item) { create(:line_item, order: order) } let!(:producer) { create(:supplier_enterprise) } @@ -64,6 +71,18 @@ module Permissions expect(permissions.visible_orders).to_not include order end end + + context "with search params" do + let(:search_params) { { completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') } } + let(:permissions) { Permissions::Order.new(user, search_params) } + + it "only returns completed, non-cancelled orders within search filter range" do + expect(permissions.visible_orders).to include order_completed + expect(permissions.visible_orders).to_not include order_cancelled + expect(permissions.visible_orders).to_not include order_cart + expect(permissions.visible_orders).to_not include order_from_last_year + end + end end context "as an enterprise that is a distributor in the order cycle, but not the distributor of the order" do @@ -78,10 +97,7 @@ module Permissions end describe "finding line items that are visible in reports" do - let(:distributor) { create(:distributor_enterprise) } - let(:coordinator) { create(:distributor_enterprise) } let(:random_enterprise) { create(:distributor_enterprise) } - let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, distributors: [distributor]) } let(:order) { create(:order, order_cycle: order_cycle, distributor: distributor ) } let!(:line_item1) { create(:line_item, order: order) } let!(:line_item2) { create(:line_item, order: order) } @@ -137,6 +153,27 @@ module Permissions expect(permissions.visible_line_items).to_not include line_item1, line_item2 end end + + context "with search params" do + let!(:line_item3) { create(:line_item, order: order_completed) } + let!(:line_item4) { create(:line_item, order: order_cancelled) } + let!(:line_item5) { create(:line_item, order: order_cart) } + let!(:line_item6) { create(:line_item, order: order_from_last_year) } + + let(:search_params) { { completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') } } + let(:permissions) { Permissions::Order.new(user, search_params) } + + before do + allow(user).to receive(:has_spree_role?) { "admin" } + end + + it "only returns line items from completed, non-cancelled orders within search filter range" do + expect(permissions.visible_line_items).to include order_completed.line_items.first + expect(permissions.visible_line_items).to_not include order_cancelled.line_items.first + expect(permissions.visible_line_items).to_not include order_cart.line_items.first + expect(permissions.visible_line_items).to_not include order_from_last_year.line_items.first + end + end end end end diff --git a/spec/services/variants_stock_levels_spec.rb b/spec/services/variants_stock_levels_spec.rb index f4a77d7018..5977845665 100644 --- a/spec/services/variants_stock_levels_spec.rb +++ b/spec/services/variants_stock_levels_spec.rb @@ -48,4 +48,53 @@ describe VariantsStockLevels do ) end end + + describe "when the variant has an override" do + let!(:distributor) { create(:distributor_enterprise) } + let(:supplier) { variant_in_the_order.product.supplier } + let!(:order_cycle) { + create(:simple_order_cycle, suppliers: [supplier], distributors: [distributor], + variants: [variant_in_the_order, variant_not_in_the_order]) + } + let!(:variant_override_in_order) { + create(:variant_override, hub: distributor, + variant: variant_in_the_order, + count_on_hand: 200) + } + let!(:variant_override_not_in_order) { + create(:variant_override, hub: distributor, + variant: variant_not_in_the_order, + count_on_hand: 201) + } + + before do + order.order_cycle = order_cycle + order.distributor = distributor + order.save + end + + context "when the variant is in the order" do + it "returns the on_hand value of the override" do + expect(variant_stock_levels.call(order, [variant_in_the_order.id])).to eq( + variant_in_the_order.id => { + quantity: 2, max_quantity: 3, on_hand: 200, on_demand: false + } + ) + end + end + + context "with variants that are not in the order" do + it "returns the on_hand value of the override" do + variant_ids = [variant_in_the_order.id, variant_not_in_the_order.id] + expect(variant_stock_levels.call(order, variant_ids)).to eq( + variant_in_the_order.id => { + quantity: 2, max_quantity: 3, on_hand: 200, on_demand: false + }, + variant_not_in_the_order.id => { + quantity: 0, max_quantity: 0, on_hand: 201, on_demand: false + } + ) + end + end + end end diff --git a/spec/views/spree/admin/orders/invoice.html.haml_spec.rb b/spec/views/spree/admin/orders/invoice.html.haml_spec.rb new file mode 100644 index 0000000000..8d7a82c129 --- /dev/null +++ b/spec/views/spree/admin/orders/invoice.html.haml_spec.rb @@ -0,0 +1,74 @@ +require "spec_helper" + +describe "spree/admin/orders/invoice.html.haml" do + let(:shop) { create(:distributor_enterprise) } + let(:order) { create(:completed_order_with_totals, distributor: shop) } + let(:adas_address) do + Spree::Address.new( + firstname: "Ada", + lastname: "Lovelace", + phone: "0404 123 456", + address1: "2 Mahome St", + city: "Thornbury", + zipcode: "3071", + state_id: 1, + state_name: "Victoria", + ) + end + let(:adas_address_display) { "2 Mahome St, Thornbury, 3071, Victoria" } + + before do + assign(:order, order) + end + + it "displays the customer code" do + order.customer = Customer.create!( + user: order.user, + email: order.user.email, + enterprise: order.distributor, + code: "Money Penny", + ) + render + expect(rendered).to have_content "Code: Money Penny" + end + + it "displays the billing address" do + order.bill_address = adas_address + render + expect(rendered).to have_content "Ada Lovelace" + expect(rendered).to have_content adas_address.phone + expect(rendered).to have_content adas_address_display + end + + it "displays shipping info" do + order.shipping_method.update_attributes!( + name: "Home delivery", + require_ship_address: true, + ) + order.ship_address = adas_address + + render + expect(rendered).to have_content "Shipping: Home delivery" + expect(rendered).to have_content adas_address.phone + expect(rendered).to have_content adas_address_display + end + + it "displays special instructions" do + order.special_instructions = "The combination is 12345." + + render + expect(rendered).to have_content "The combination is 12345." + end + + it "hides billing address for pickups" do + order.ship_address = adas_address + order.shipping_method.update_attributes!( + name: "Pickup", + require_ship_address: false, + ) + + render + expect(rendered).to have_content "Shipping: Pickup" + expect(rendered).to_not have_content adas_address_display + end +end diff --git a/vendor/assets/javascripts/angular-google-maps.min.js b/vendor/assets/javascripts/angular-google-maps.min.js index 84af2d8ff7..295fe9cc13 100644 --- a/vendor/assets/javascripts/angular-google-maps.min.js +++ b/vendor/assets/javascripts/angular-google-maps.min.js @@ -1,8 +1,9 @@ -/*! angular-google-maps 1.1.0 2014-05-17 +/*! angular-google-maps 2.0.0 2014-10-09 * AngularJS directives for Google Maps - * git: https://github.com/nlaplante/angular-google-maps.git + * git: https://github.com/angular-ui/angular-google-maps.git */ -function InfoBox(a){a=a||{},google.maps.OverlayView.apply(this,arguments),this.content_=a.content||"",this.disableAutoPan_=a.disableAutoPan||!1,this.maxWidth_=a.maxWidth||0,this.pixelOffset_=a.pixelOffset||new google.maps.Size(0,0),this.position_=a.position||new google.maps.LatLng(0,0),this.zIndex_=a.zIndex||null,this.boxClass_=a.boxClass||"infoBox",this.boxStyle_=a.boxStyle||{},this.closeBoxMargin_=a.closeBoxMargin||"2px",this.closeBoxURL_=a.closeBoxURL||"http://www.google.com/intl/en_us/mapfiles/close.gif",""===a.closeBoxURL&&(this.closeBoxURL_=""),this.infoBoxClearance_=a.infoBoxClearance||new google.maps.Size(1,1),"undefined"==typeof a.visible&&(a.visible="undefined"==typeof a.isHidden?!0:!a.isHidden),this.isHidden_=!a.visible,this.alignBottom_=a.alignBottom||!1,this.pane_=a.pane||"floatPane",this.enableEventPropagation_=a.enableEventPropagation||!1,this.div_=null,this.closeListener_=null,this.moveListener_=null,this.contextListener_=null,this.eventListeners_=null,this.fixedWidthSet_=null}function ClusterIcon(a,b){a.getMarkerClusterer().extend(ClusterIcon,google.maps.OverlayView),this.cluster_=a,this.className_=a.getMarkerClusterer().getClusterClass(),this.styles_=b,this.center_=null,this.div_=null,this.sums_=null,this.visible_=!1,this.setMap(a.getMap())}function Cluster(a){this.markerClusterer_=a,this.map_=a.getMap(),this.gridSize_=a.getGridSize(),this.minClusterSize_=a.getMinimumClusterSize(),this.averageCenter_=a.getAverageCenter(),this.markers_=[],this.center_=null,this.bounds_=null,this.clusterIcon_=new ClusterIcon(this,a.getStyles())}function MarkerClusterer(a,b,c){this.extend(MarkerClusterer,google.maps.OverlayView),b=b||[],c=c||{},this.markers_=[],this.clusters_=[],this.listeners_=[],this.activeMap_=null,this.ready_=!1,this.gridSize_=c.gridSize||60,this.minClusterSize_=c.minimumClusterSize||2,this.maxZoom_=c.maxZoom||null,this.styles_=c.styles||[],this.title_=c.title||"",this.zoomOnClick_=!0,void 0!==c.zoomOnClick&&(this.zoomOnClick_=c.zoomOnClick),this.averageCenter_=!1,void 0!==c.averageCenter&&(this.averageCenter_=c.averageCenter),this.ignoreHidden_=!1,void 0!==c.ignoreHidden&&(this.ignoreHidden_=c.ignoreHidden),this.enableRetinaIcons_=!1,void 0!==c.enableRetinaIcons&&(this.enableRetinaIcons_=c.enableRetinaIcons),this.imagePath_=c.imagePath||MarkerClusterer.IMAGE_PATH,this.imageExtension_=c.imageExtension||MarkerClusterer.IMAGE_EXTENSION,this.imageSizes_=c.imageSizes||MarkerClusterer.IMAGE_SIZES,this.calculator_=c.calculator||MarkerClusterer.CALCULATOR,this.batchSize_=c.batchSize||MarkerClusterer.BATCH_SIZE,this.batchSizeIE_=c.batchSizeIE||MarkerClusterer.BATCH_SIZE_IE,this.clusterClass_=c.clusterClass||"cluster",-1!==navigator.userAgent.toLowerCase().indexOf("msie")&&(this.batchSize_=this.batchSizeIE_),this.setupStyles_(),this.addMarkers(b,!0),this.setMap(a)}function inherits(a,b){function c(){}c.prototype=b.prototype,a.superClass_=b.prototype,a.prototype=new c,a.prototype.constructor=a}function MarkerLabel_(a,b){this.marker_=a,this.handCursorURL_=a.handCursorURL,this.labelDiv_=document.createElement("div"),this.labelDiv_.style.cssText="position: absolute; overflow: hidden;",this.eventDiv_=document.createElement("div"),this.eventDiv_.style.cssText=this.labelDiv_.style.cssText,this.eventDiv_.setAttribute("onselectstart","return false;"),this.eventDiv_.setAttribute("ondragstart","return false;"),this.crossDiv_=MarkerLabel_.getSharedCross(b)}function MarkerWithLabel(a){a=a||{},a.labelContent=a.labelContent||"",a.labelAnchor=a.labelAnchor||new google.maps.Point(0,0),a.labelClass=a.labelClass||"markerLabels",a.labelStyle=a.labelStyle||{},a.labelInBackground=a.labelInBackground||!1,"undefined"==typeof a.labelVisible&&(a.labelVisible=!0),"undefined"==typeof a.raiseOnDrag&&(a.raiseOnDrag=!0),"undefined"==typeof a.clickable&&(a.clickable=!0),"undefined"==typeof a.draggable&&(a.draggable=!1),"undefined"==typeof a.optimized&&(a.optimized=!1),a.crossImage=a.crossImage||"http"+("https:"===document.location.protocol?"s":"")+"://maps.gstatic.com/intl/en_us/mapfiles/drag_cross_67_16.png",a.handCursor=a.handCursor||"http"+("https:"===document.location.protocol?"s":"")+"://maps.gstatic.com/intl/en_us/mapfiles/closedhand_8_8.cur",a.optimized=!1,this.label=new MarkerLabel_(this,a.crossImage,a.handCursor),google.maps.Marker.apply(this,arguments)}(function(){angular.module("google-maps.directives.api.utils",[]),angular.module("google-maps.directives.api.managers",[]),angular.module("google-maps.directives.api.models.child",["google-maps.directives.api.utils"]),angular.module("google-maps.directives.api.models.parent",["google-maps.directives.api.managers","google-maps.directives.api.models.child"]),angular.module("google-maps.directives.api",["google-maps.directives.api.models.parent"]),angular.module("google-maps",["google-maps.directives.api"]).factory("debounce",["$timeout",function(a){return function(b){var c;return c=0,function(){var d,e,f;return f=this,d=arguments,c++,e=function(a){return function(){return a===c?b.apply(f,d):void 0}}(c),a(e,0,!0)}}}])}).call(this),function(){angular.element(document).ready(function(){return(google||("undefined"!=typeof google&&null!==google?google.maps:void 0)||null!=google.maps.InfoWindow)&&(google.maps.InfoWindow.prototype._open=google.maps.InfoWindow.prototype.open,google.maps.InfoWindow.prototype._close=google.maps.InfoWindow.prototype.close,google.maps.InfoWindow.prototype._isOpen=!1,google.maps.InfoWindow.prototype.open=function(a,b){this._isOpen=!0,this._open(a,b)},google.maps.InfoWindow.prototype.close=function(){this._isOpen=!1,this._close()},google.maps.InfoWindow.prototype.isOpen=function(a){return null==a&&(a=void 0),null==a?this._isOpen:this._isOpen=a},window.InfoBox)?(window.InfoBox.prototype._open=window.InfoBox.prototype.open,window.InfoBox.prototype._close=window.InfoBox.prototype.close,window.InfoBox.prototype._isOpen=!1,window.InfoBox.prototype.open=function(a,b){this._isOpen=!0,this._open(a,b)},window.InfoBox.prototype.close=function(){this._isOpen=!1,this._close()},window.InfoBox.prototype.isOpen=function(a){return null==a&&(a=void 0),null==a?this._isOpen:this._isOpen=a}):void 0})}.call(this),function(){_.intersectionObjects=function(a,b,c){var d;return null==c&&(c=void 0),d=_.map(a,function(a){return _.find(b,function(b){return null!=c?c(a,b):_.isEqual(a,b)})}),_.filter(d,function(a){return null!=a})},_.containsObject=_.includeObject=function(a,b,c){return null==c&&(c=void 0),null===a?!1:_.any(a,function(a){return null!=c?c(a,b):_.isEqual(a,b)})},_.differenceObjects=function(a,b,c){return null==c&&(c=void 0),_.filter(a,function(a){return!_.containsObject(b,a)})},_.withoutObjects=function(a,b){return _.differenceObjects(a,b)},_.indexOfObject=function(a,b,c,d){var e,f;if(null==a)return-1;if(e=0,f=a.length,d){if("number"!=typeof d)return e=_.sortedIndex(a,b),a[e]===b?e:-1;e=0>d?Math.max(0,f+d):d}for(;f>e;){if(null!=c){if(c(a[e],b))return e}else if(_.isEqual(a[e],b))return e;e++}return-1},_["extends"]=function(a){return _.reduce(a,function(a,b){return _.extend(a,b)},{})}}.call(this),function(){var a;a={each:function(a,b,c,d,e,f){var g;return null==e&&(e=100),null==f&&(f=0),void 0===a||(null!=a?a.length:void 0)<=0?void c():(g=function(){var h,i;for(h=e,i=f;h--&&ib;b++)if(b in this&&this[b]===a)return b;return-1};angular.module("google-maps.directives.api.utils").factory("BaseObject",function(){var b,c;return c=["extended","included"],b=function(){function b(){}return b.extend=function(b){var d,e,f;for(d in b)e=b[d],a.call(c,d)<0&&(this[d]=e);return null!=(f=b.extended)&&f.apply(this),this},b.include=function(b){var d,e,f;for(d in b)e=b[d],a.call(c,d)<0&&(this.prototype[d]=e);return null!=(f=b.included)&&f.apply(this),this},b}()})}.call(this),function(){angular.module("google-maps.directives.api.utils").factory("ChildEvents",function(){return{onChildCreation:function(){}}})}.call(this),function(){var a={}.hasOwnProperty,b=function(b,c){function d(){this.constructor=b}for(var e in c)a.call(c,e)&&(b[e]=c[e]);return d.prototype=c.prototype,b.prototype=new d,b.__super__=c.prototype,b};angular.module("google-maps.directives.api.utils").factory("FitHelper",["BaseObject","Logger",function(a){var c,d;return c=function(a){function c(){return d=c.__super__.constructor.apply(this,arguments)}return b(c,a),c.prototype.fit=function(a,b){var c,d;return b&&a&&a.length>0?(c=new google.maps.LatLngBounds,d=!1,_async.each(a,function(a){return a?(d||(d=!0),c.extend(a.getPosition())):void 0},function(){return d?b.fitBounds(c):void 0})):void 0},c}(a)}])}.call(this),function(){angular.module("google-maps.directives.api.utils").service("GmapUtil",["Logger","$compile",function(a,b){var c,d;return c=function(a){return Array.isArray(a)&&2===a.length?new google.maps.LatLng(a[1],a[0]):angular.isDefined(a.type)&&"Point"===a.type?new google.maps.LatLng(a.coordinates[1],a.coordinates[0]):new google.maps.LatLng(a.latitude,a.longitude)},d=function(a){if(angular.isUndefined(a))return!1;if(_.isArray(a)){if(2===a.length)return!0}else if(null!=a&&(null!=a?a.type:void 0)){if("Point"===a.type&&_.isArray(a.coordinates)&&2===a.coordinates.length)return!0}else if(a&&angular.isDefined((null!=a?a.latitude:void 0)&&angular.isDefined(null!=a?a.longitude:void 0)))return!0;return!1},{getLabelPositionPoint:function(a){var b,c;return void 0===a?void 0:(a=/^([-\d\.]+)\s([-\d\.]+)$/.exec(a),b=parseFloat(a[1]),c=parseFloat(a[2]),null!=b&&null!=c?new google.maps.Point(b,c):void 0)},createMarkerOptions:function(a,b,e,f){var g;return null==f&&(f=void 0),null==e&&(e={}),g=angular.extend({},e,{position:null!=e.position?e.position:c(a),icon:null!=e.icon?e.icon:b,visible:null!=e.visible?e.visible:d(a)}),null!=f&&(g.map=f),g},createWindowOptions:function(d,e,f,g){return null!=f&&null!=g&&null!=b?angular.extend({},g,{content:this.buildContent(e,g,f),position:null!=g.position?g.position:angular.isObject(d)?d.getPosition():c(e.coords)}):g?g:(a.error("infoWindow defaults not defined"),f?void 0:a.error("infoWindow content not defined"))},buildContent:function(a,c,d){var e,f;return null!=c.content?f=c.content:null!=b?(e=b(d)(a),e.length>0&&(f=e[0])):f=d,f},defaultDelay:50,isTrue:function(a){return angular.isDefined(a)&&null!==a&&a===!0||"1"===a||"y"===a||"true"===a},isFalse:function(a){return-1!==["false","FALSE",0,"n","N","no","NO"].indexOf(a)},getCoords:c,validateCoords:d,validatePath:function(a){var b,c;if(c=0,angular.isUndefined(a.type)){if(!Array.isArray(a)||a.length<2)return!1;for(;cc;c++)b=a[c],e.push(this.add(b));return e},f.prototype.remove=function(a,b){var c,d;return this.handleOptDraw(a,b,!1),b?(c=void 0,null!=this.gMarkers.indexOf?c=this.gMarkers.indexOf(a):(d=0,_.find(this.gMarkers,function(b){d+=1,b===a&&(c=d)})),null!=c?this.gMarkers.splice(c,1):void 0):void 0},f.prototype.removeMany=function(){var a=this;return this.gMarkers.forEach(function(b){return a.remove(b)})},f.prototype.draw=function(){var a,b=this;return a=[],this.gMarkers.forEach(function(c){return c.isDrawn?void 0:c.doAdd?c.setMap(b.gMap):a.push(c)}),a.forEach(function(a){return b.remove(a,!0)})},f.prototype.clear=function(){var a,b,c,d;for(d=this.gMarkers,b=0,c=d.length;c>b;b++)a=d[b],a.setMap(null);return delete this.gMarkers,this.gMarkers=[]},f.prototype.handleOptDraw=function(a,b,c){return b===!0?(a.setMap(c?this.gMap:null),a.isDrawn=!0):(a.isDrawn=!1,a.doAdd=c)},f.prototype.fit=function(){return f.__super__.fit.call(this,this.gMarkers,this.gMap)},f}(d)}])}.call(this),function(){angular.module("google-maps").factory("array-sync",["add-events",function(a){return function(b,c,d){var e,f,g,h,i,j,k,l,m;return h=!1,l=c.$eval(d),c["static"]||(i={set_at:function(a){var c;if(!h&&(c=b.getAt(a)))return c.lng&&c.lat?(l[a].latitude=c.lat(),l[a].longitude=c.lng()):l[a]=c},insert_at:function(a){var c;if(!h&&(c=b.getAt(a)))return c.lng&&c.lat?l.splice(a,0,{latitude:c.lat(),longitude:c.lng()}):l.splice(a,0,c)},remove_at:function(a){return h?void 0:l.splice(a,1)}},"Polygon"===l.type?e=l.coordinates[0]:"LineString"===l.type&&(e=l.coordinates),f={set_at:function(a){var c;if(!h&&(c=b.getAt(a),c&&c.lng&&c.lat))return e[a][1]=c.lat(),e[a][0]=c.lng()},insert_at:function(a){var c;if(!h&&(c=b.getAt(a),c&&c.lng&&c.lat))return e.splice(a,0,[c.lng(),c.lat()])},remove_at:function(a){return h?void 0:e.splice(a,1)}},k=a(b,angular.isUndefined(l.type)?i:f)),j=function(a){var c,d,e,f,g,i,j;if(h=!0,g=b,a){for(c=0,i=g.getLength(),e=a.length,d=Math.min(i,e),f=void 0;d>c;)j=g.getAt(c),f=a[c],"function"==typeof f.equals?f.equals(j)||g.setAt(c,f):(j.lat()!==f.latitude||j.lng()!==f.longitude)&&g.setAt(c,new google.maps.LatLng(f.latitude,f.longitude)),c++;for(;e>c;)f=a[c],g.push("function"==typeof f.lat&&"function"==typeof f.lng?f:new google.maps.LatLng(f.latitude,f.longitude)),c++;for(;i>c;)g.pop(),c++}return h=!1},g=function(a){var c,d,e,f,g,i,j,k;if(h=!0,i=b,a){for("Polygon"===l.type?c=a.coordinates[0]:"LineString"===l.type&&(c=a.coordinates),d=0,j=i.getLength(),f=c.length,e=Math.min(j,f),g=void 0;e>d;)k=i.getAt(d),g=c[d],(k.lat()!==g[1]||k.lng()!==g[0])&&i.setAt(d,new google.maps.LatLng(g[1],g[0])),d++;for(;f>d;)g=c[d],i.push(new google.maps.LatLng(g[1],g[0])),d++;for(;j>d;)i.pop(),d++}return h=!1},c["static"]||(m=angular.isUndefined(l.type)?c.$watchCollection(d,j):c.$watch(d,g)),function(){return k&&(k(),k=null),m?(m(),m=null):void 0}}}])}.call(this),function(){angular.module("google-maps").factory("add-events",["$timeout",function(a){var b,c;return b=function(b,c,d){return google.maps.event.addListener(b,c,function(){return d.apply(this,arguments),a(function(){},!0)})},c=function(a,c,d){var e;return d?b(a,c,d):(e=[],angular.forEach(c,function(c,d){return e.push(b(a,d,c))}),function(){return angular.forEach(e,function(a){return google.maps.event.removeListener(a)}),e=null})}}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.child").factory("MarkerLabelChildModel",["BaseObject","GmapUtil",function(b,d){var e;return e=function(b){function e(b,c){this.destroy=a(this.destroy,this),this.draw=a(this.draw,this),this.setPosition=a(this.setPosition,this),this.setZIndex=a(this.setZIndex,this),this.setVisible=a(this.setVisible,this),this.setAnchor=a(this.setAnchor,this),this.setMandatoryStyles=a(this.setMandatoryStyles,this),this.setStyles=a(this.setStyles,this),this.setContent=a(this.setContent,this),this.setTitle=a(this.setTitle,this),this.getSharedCross=a(this.getSharedCross,this);var d,f,g;e.__super__.constructor.call(this),d=this,this.marker=b,this.marker.set("labelContent",c.labelContent),this.marker.set("labelAnchor",this.getLabelPositionPoint(c.labelAnchor)),this.marker.set("labelClass",c.labelClass||"labels"),this.marker.set("labelStyle",c.labelStyle||{opacity:100}),this.marker.set("labelInBackground",c.labelInBackground||!1),c.labelVisible||this.marker.set("labelVisible",!0),c.raiseOnDrag||this.marker.set("raiseOnDrag",!0),c.clickable||this.marker.set("clickable",!0),c.draggable||this.marker.set("draggable",!1),c.optimized||this.marker.set("optimized",!1),c.crossImage=null!=(f=c.crossImage)?f:document.location.protocol+"//maps.gstatic.com/intl/en_us/mapfiles/drag_cross_67_16.png",c.handCursor=null!=(g=c.handCursor)?g:document.location.protocol+"//maps.gstatic.com/intl/en_us/mapfiles/closedhand_8_8.cur",this.markerLabel=new MarkerLabel_(this.marker,c.crossImage,c.handCursor),this.marker.set("setMap",function(a){return google.maps.Marker.prototype.setMap.apply(this,arguments),d.markerLabel.setMap(a)}),this.marker.setMap(this.marker.getMap())}return c(e,b),e.include(d),e.prototype.getSharedCross=function(a){return this.markerLabel.getSharedCross(a)},e.prototype.setTitle=function(){return this.markerLabel.setTitle()},e.prototype.setContent=function(){return this.markerLabel.setContent()},e.prototype.setStyles=function(){return this.markerLabel.setStyles()},e.prototype.setMandatoryStyles=function(){return this.markerLabel.setMandatoryStyles()},e.prototype.setAnchor=function(){return this.markerLabel.setAnchor()},e.prototype.setVisible=function(){return this.markerLabel.setVisible()},e.prototype.setZIndex=function(){return this.markerLabel.setZIndex()},e.prototype.setPosition=function(){return this.markerLabel.setPosition()},e.prototype.draw=function(){return this.markerLabel.draw()},e.prototype.destroy=function(){return null!=this.markerLabel.labelDiv_.parentNode&&null!=this.markerLabel.eventDiv_.parentNode?this.markerLabel.onRemove():void 0},e}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.child").factory("MarkerChildModel",["ModelKey","GmapUtil","Logger","$injector","MarkerEventHelper",function(b,d,e,f,g){var h;return h=function(b){function h(b,c,d,f,g,i,j,k){var l,m=this;this.model=b,this.parentScope=c,this.gMap=d,this.$timeout=f,this.defaults=g,this.doClick=i,this.gMarkerManager=j,this.idKey=k,this.watchDestroy=a(this.watchDestroy,this),this.setLabelOptions=a(this.setLabelOptions,this),this.isLabelDefined=a(this.isLabelDefined,this),this.setOptions=a(this.setOptions,this),this.setIcon=a(this.setIcon,this),this.setCoords=a(this.setCoords,this),this.destroy=a(this.destroy,this),this.maybeSetScopeValue=a(this.maybeSetScopeValue,this),this.createMarker=a(this.createMarker,this),this.setMyScope=a(this.setMyScope,this),l=this,this.model[this.idKey]&&(this.id=this.model[this.idKey]),this.iconKey=this.parentScope.icon,this.coordsKey=this.parentScope.coords,this.clickKey=this.parentScope.click(),this.labelContentKey=this.parentScope.labelContent,this.optionsKey=this.parentScope.options,this.labelOptionsKey=this.parentScope.labelOptions,h.__super__.constructor.call(this,this.parentScope.$new(!1)),this.scope.model=this.model,this.setMyScope(this.model,void 0,!0),this.createMarker(this.model),this.scope.$watch("model",function(a,b){return a!==b?m.setMyScope(a,b):void 0},!0),this.$log=e,this.$log.info(l),this.watchDestroy(this.scope)}return c(h,b),h.include(d),h.include(g),h.prototype.setMyScope=function(a,b,c){var d=this;return null==b&&(b=void 0),null==c&&(c=!1),this.maybeSetScopeValue("icon",a,b,this.iconKey,this.evalModelHandle,c,this.setIcon),this.maybeSetScopeValue("coords",a,b,this.coordsKey,this.evalModelHandle,c,this.setCoords),this.maybeSetScopeValue("labelContent",a,b,this.labelContentKey,this.evalModelHandle,c),_.isFunction(this.clickKey)&&f?this.scope.click=function(){return f.invoke(d.clickKey,void 0,{$markerModel:a})}:(this.maybeSetScopeValue("click",a,b,this.clickKey,this.evalModelHandle,c),this.createMarker(a,b,c))},h.prototype.createMarker=function(a,b,c){var d=this;return null==b&&(b=void 0),null==c&&(c=!1),this.maybeSetScopeValue("options",a,b,this.optionsKey,function(a,b){var c;return void 0===a?void 0:(c="self"===b?a:a[b],void 0===c?c=void 0===b?d.defaults:d.scope.options:c)},c,this.setOptions)},h.prototype.maybeSetScopeValue=function(a,b,c,d,e,f,g){var h,i;return null==g&&(g=void 0),void 0===c?(this.scope[a]=e(b,d),void(f||null!=g&&g(this.scope))):(i=e(c,d),h=e(b,d),h===i||this.scope[a]===h||(this.scope[a]=h,f)?void 0:(null!=g&&g(this.scope),this.gMarkerManager.draw()))},h.prototype.destroy=function(){return this.scope.$destroy()},h.prototype.setCoords=function(a){return a.$id===this.scope.$id&&void 0!==this.gMarker?null!=a.coords?this.validateCoords(this.scope.coords)?(this.gMarker.setPosition(this.getCoords(a.coords)),this.gMarker.setVisible(this.validateCoords(a.coords)),this.gMarkerManager.remove(this.gMarker),this.gMarkerManager.add(this.gMarker)):void this.$log.error("MarkerChildMarker cannot render marker as scope.coords as no position on marker: "+JSON.stringify(this.model)):this.gMarkerManager.remove(this.gMarker):void 0},h.prototype.setIcon=function(a){return a.$id===this.scope.$id&&void 0!==this.gMarker?(this.gMarkerManager.remove(this.gMarker),this.gMarker.setIcon(a.icon),this.gMarkerManager.add(this.gMarker),this.gMarker.setPosition(this.getCoords(a.coords)),this.gMarker.setVisible(this.validateCoords(a.coords))):void 0},h.prototype.setOptions=function(a){var b,c=this;if(a.$id===this.scope.$id&&(null!=this.gMarker&&(this.gMarkerManager.remove(this.gMarker),delete this.gMarker),null!=(b=a.coords)?b:"function"==typeof a.icon?a.icon(null!=a.options):void 0))return this.opts=this.createMarkerOptions(a.coords,a.icon,a.options),delete this.gMarker,this.gMarker=this.isLabelDefined(a)?new MarkerWithLabel(this.setLabelOptions(this.opts,a)):new google.maps.Marker(this.opts),this.setEvents(this.gMarker,this.parentScope,this.model),this.id&&(this.gMarker.key=this.id),this.gMarkerManager.add(this.gMarker),google.maps.event.addListener(this.gMarker,"click",function(){return c.doClick&&null!=c.scope.click?c.scope.click():void 0})},h.prototype.isLabelDefined=function(a){return null!=a.labelContent},h.prototype.setLabelOptions=function(a,b){return a.labelAnchor=this.getLabelPositionPoint(b.labelAnchor),a.labelClass=b.labelClass,a.labelContent=b.labelContent,a},h.prototype.watchDestroy=function(a){var b=this;return a.$on("$destroy",function(){var a,c;return null!=b.gMarker&&(google.maps.event.clearListeners(b.gMarker,"click"),(null!=(c=b.parentScope)?c.events:void 0)&&_.isArray(b.parentScope.events)&&b.parentScope.events.forEach(function(a,b){return google.maps.event.clearListeners(this.gMarker,b)}),b.gMarkerManager.remove(b.gMarker,!0),delete b.gMarker),a=void 0})},h}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api").factory("PolylineChildModel",["BaseObject","Logger","$timeout","array-sync","GmapUtil",function(b,d,e,f,g){var h,i;return h=d,i=function(b){function d(b,c,d,e,g){var i,j,k,l=this;this.scope=b,this.attrs=c,this.map=d,this.defaults=e,this.model=g,this.buildOpts=a(this.buildOpts,this),k=this,j=this.convertPathPoints(this.scope.path),this.polyline=new google.maps.Polyline(this.buildOpts(j)),this.isTrue(this.attrs.fit)&&extendMapBounds(d,j),!b["static"]&&angular.isDefined(b.editable)&&b.$watch("editable",function(a,b){return a!==b?this.polyline.setEditable(a):void 0}),angular.isDefined(b.draggable)&&b.$watch("draggable",function(a,b){return a!==b?this.polyline.setDraggable(a):void 0}),angular.isDefined(b.visible)&&b.$watch("visible",function(a,b){return a!==b?this.polyline.setVisible(a):void 0}),angular.isDefined(b.geodesic)&&b.$watch("geodesic",function(a,b){return a!==b?this.polyline.setOptions(this.buildOpts(this.polyline.getPath())):void 0 -}),angular.isDefined(b.stroke)&&angular.isDefined(b.stroke.weight)&&b.$watch("stroke.weight",function(a,b){return a!==b?this.polyline.setOptions(this.buildOpts(this.polyline.getPath())):void 0}),angular.isDefined(b.stroke)&&angular.isDefined(b.stroke.color)&&b.$watch("stroke.color",function(a,b){return a!==b?this.polyline.setOptions(this.buildOpts(this.polyline.getPath())):void 0}),angular.isDefined(b.icons)&&b.$watch("icons",function(a,b){return a!==b?this.polyline.setOptions(this.buildOpts(this.polyline.getPath())):void 0}),i=f(this.polyline.getPath(),b,"path"),b.$on("$destroy",function(){return l.polyline.setMap(null),l.polyline=null,l.scope=null,i?(i(),i=null):void 0}),h.info(this)}return c(d,b),d.include(g),d.prototype.buildOpts=function(a){var b,c=this;return b=angular.extend({},this.defaults,{map:this.map,path:a,icons:this.scope.icons,strokeColor:this.scope.stroke&&this.scope.stroke.color,strokeOpacity:this.scope.stroke&&this.scope.stroke.opacity,strokeWeight:this.scope.stroke&&this.scope.stroke.weight}),angular.forEach({clickable:!0,draggable:!1,editable:!1,geodesic:!1,visible:!0,"static":!1},function(a,d){return b[d]=angular.isUndefined(c.scope[d])||null===c.scope[d]?a:c.scope[d]}),b["static"]&&(b.editable=!1),b},d.prototype.destroy=function(){return this.scope.$destroy()},d}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.child").factory("WindowChildModel",["BaseObject","GmapUtil","Logger","$compile","$http","$templateCache",function(b,d,e,f,g,h){var i;return i=function(b){function i(b,c,d,f,g,h,i,j,k){this.model=b,this.scope=c,this.opts=d,this.isIconVisibleOnClick=f,this.mapCtrl=g,this.markerCtrl=h,this.element=i,this.needToManualDestroy=null!=j?j:!1,this.markerIsVisibleAfterWindowClose=null!=k?k:!0,this.destroy=a(this.destroy,this),this.remove=a(this.remove,this),this.hideWindow=a(this.hideWindow,this),this.getLatestPosition=a(this.getLatestPosition,this),this.showWindow=a(this.showWindow,this),this.handleClick=a(this.handleClick,this),this.watchCoords=a(this.watchCoords,this),this.watchShow=a(this.watchShow,this),this.createGWin=a(this.createGWin,this),this.watchElement=a(this.watchElement,this),this.googleMapsHandles=[],this.$log=e,this.createGWin(),null!=this.markerCtrl&&this.markerCtrl.setClickable(!0),this.handleClick(),this.watchElement(),this.watchShow(),this.watchCoords(),this.$log.info(this)}return c(i,b),i.include(d),i.prototype.watchElement=function(){var a=this;return this.scope.$watch(function(){var b;if(a.element&&a.html)return a.html!==a.element.html()&&a.gWin?(null!=(b=a.opts)&&(b.content=void 0),a.remove(),a.createGWin(),a.showHide()):void 0})},i.prototype.createGWin=function(){var a,b=this;return null==this.gWin&&(a={},null!=this.opts&&(this.scope.coords&&(this.opts.position=this.getCoords(this.scope.coords)),a=this.opts),this.element&&(this.html=_.isObject(this.element)?this.element.html():this.element),this.opts=this.createWindowOptions(this.markerCtrl,this.scope,this.html,a)),null==this.opts||this.gWin?void 0:(this.gWin=this.opts.boxClass&&window.InfoBox&&"function"==typeof window.InfoBox?new window.InfoBox(this.opts):new google.maps.InfoWindow(this.opts),this.googleMapsHandles.push(google.maps.event.addListener(this.gWin,"closeclick",function(){var a;return null!=(a=b.markerCtrl)&&a.setVisible(b.markerIsVisibleAfterWindowClose),b.gWin.isOpen(!1),null!=b.scope.closeClick?b.scope.closeClick():void 0})))},i.prototype.watchShow=function(){var a=this;return this.scope.$watch("show",function(b,c){return b!==c?b?a.showWindow():a.hideWindow():null!=a.gWin&&b&&!a.gWin.getMap()?a.showWindow():void 0},!0)},i.prototype.watchCoords=function(){var a,b=this;return a=null!=this.markerCtrl?this.scope.$parent:this.scope,a.$watch("coords",function(a,c){var d;if(a!==c){if(null==a)return b.hideWindow();if(!b.validateCoords(a))return void b.$log.error("WindowChildMarker cannot render marker as scope.coords as no position on marker: "+JSON.stringify(b.model));if(d=b.getCoords(a),b.gWin.setPosition(d),b.opts)return b.opts.position=d}},!0)},i.prototype.handleClick=function(){var a=this;return null!=this.markerCtrl?this.googleMapsHandles.push(google.maps.event.addListener(this.markerCtrl,"click",function(){var b;return null==a.gWin&&a.createGWin(),b=a.markerCtrl.getPosition(),null!=a.gWin&&(a.gWin.setPosition(b),a.opts&&(a.opts.position=b),a.showWindow()),a.initialMarkerVisibility=a.markerCtrl.getVisible(),a.markerCtrl.setVisible(a.isIconVisibleOnClick)})):void 0},i.prototype.showWindow=function(){var a,b=this;return a=function(){return!b.gWin||!b.scope.show&&null!=b.scope.show||b.gWin.isOpen()?void 0:b.gWin.open(b.mapCtrl)},this.scope.templateUrl?(this.gWin&&g.get(this.scope.templateUrl,{cache:h}).then(function(a){var c,d;return d=b.scope.$new(),angular.isDefined(b.scope.templateParameter)&&(d.parameter=b.scope.templateParameter),c=f(a.data)(d),b.gWin.setContent(c[0])}),a()):a()},i.prototype.showHide=function(){return this.scope.show?this.showWindow():this.hideWindow()},i.prototype.getLatestPosition=function(){return null!=this.gWin&&null!=this.markerCtrl?this.gWin.setPosition(this.markerCtrl.getPosition()):void 0},i.prototype.hideWindow=function(){return null!=this.gWin&&this.gWin.isOpen()?this.gWin.close():void 0},i.prototype.remove=function(){return this.hideWindow(),_.each(this.googleMapsHandles,function(a){return google.maps.event.removeListener(a)}),this.googleMapsHandles.length=0,delete this.gWin},i.prototype.destroy=function(a){var b;return null==a&&(a=!1),this.remove(),null!=this.scope&&(this.needToManualDestroy||a)&&this.scope.$destroy(),b=void 0},i}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.parent").factory("IMarkerParentModel",["ModelKey","Logger",function(b,d){var e;return e=function(b){function e(b,c,f,g,h){var i,j=this;if(this.scope=b,this.element=c,this.attrs=f,this.mapCtrl=g,this.$timeout=h,this.linkInit=a(this.linkInit,this),this.onDestroy=a(this.onDestroy,this),this.onWatch=a(this.onWatch,this),this.watch=a(this.watch,this),this.validateScope=a(this.validateScope,this),this.onTimeOut=a(this.onTimeOut,this),e.__super__.constructor.call(this,this.scope),i=this,this.$log=d,!this.validateScope(b))throw new String("Unable to construct IMarkerParentModel due to invalid scope");this.doClick=angular.isDefined(f.click),null!=b.options&&(this.DEFAULTS=b.options),this.$timeout(function(){return j.onTimeOut(b),j.watch("coords",j.scope),j.watch("icon",j.scope),j.watch("options",j.scope),b.$on("$destroy",function(){return j.onDestroy(b)})})}return c(e,b),e.prototype.DEFAULTS={},e.prototype.onTimeOut=function(){},e.prototype.validateScope=function(a){var b;return null==a?(this.$log.error(this.constructor.name+": invalid scope used"),!1):(b=null!=a.coords,b?b:(this.$log.error(this.constructor.name+": no valid coords attribute found"),!1))},e.prototype.watch=function(a,b){var c,d=this;return c=function(c,e){return c!==e?d.onWatch(a,b,c,e):void 0},b.$watch(a,c,!0)},e.prototype.onWatch=function(){throw new String("OnWatch Not Implemented!!")},e.prototype.onDestroy=function(){throw new String("OnDestroy Not Implemented!!")},e.prototype.linkInit=function(){throw new String("LinkInit Not Implemented!!")},e}(b)}])}.call(this),function(){var a={}.hasOwnProperty,b=function(b,c){function d(){this.constructor=b}for(var e in c)a.call(c,e)&&(b[e]=c[e]);return d.prototype=c.prototype,b.prototype=new d,b.__super__=c.prototype,b};angular.module("google-maps.directives.api.models.parent").factory("IWindowParentModel",["ModelKey","GmapUtil","Logger",function(a,c,d){var e;return e=function(a){function e(a,b,c,f,g,h,i,j){var k;e.__super__.constructor.call(this,a),k=this,this.$log=d,this.$timeout=g,this.$compile=h,this.$http=i,this.$templateCache=j,null!=a.options&&(this.DEFAULTS=a.options)}return b(e,a),e.include(c),e.prototype.DEFAULTS={},e}(a)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.parent").factory("LayerParentModel",["BaseObject","Logger",function(b,d){var e;return e=function(b){function e(b,c,e,f,g,h,i){var j=this;return this.scope=b,this.element=c,this.attrs=e,this.mapCtrl=f,this.$timeout=g,this.onLayerCreated=null!=h?h:void 0,this.$log=null!=i?i:d,this.createGoogleLayer=a(this.createGoogleLayer,this),null==this.attrs.type?void this.$log.info("type attribute for the layer directive is mandatory. Layer creation aborted!!"):(this.createGoogleLayer(),this.gMap=void 0,this.doShow=!0,void this.$timeout(function(){return j.gMap=f.getMap(),angular.isDefined(j.attrs.show)&&(j.doShow=j.scope.show),j.doShow&&null!=j.gMap&&j.layer.setMap(j.gMap),j.scope.$watch("show",function(a,b){return a!==b?(j.doShow=a,j.layer.setMap(a?j.gMap:null)):void 0},!0),j.scope.$watch("options",function(a,b){return a!==b?(j.layer.setMap(null),j.layer=null,j.createGoogleLayer()):void 0},!0),j.scope.$on("$destroy",function(){return j.layer.setMap(null)})}))}return c(e,b),e.prototype.createGoogleLayer=function(){var a=this;return this.layer=null==this.attrs.options?void 0===this.attrs.namespace?new google.maps[this.attrs.type]:new google.maps[this.attrs.namespace][this.attrs.type]:void 0===this.attrs.namespace?new google.maps[this.attrs.type](this.scope.options):new google.maps[this.attrs.namespace][this.attrs.type](this.scope.options),this.$timeout(function(){var b;return null!=a.layer&&null!=a.onLayerCreated&&(b=a.onLayerCreated(a.scope,a.layer))?b(a.layer):void 0})},e}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.parent").factory("MarkerParentModel",["IMarkerParentModel","GmapUtil","MarkerEventHelper",function(b,d,e){var f;return f=function(b){function f(b,c,d,e,g,h,i){var j;this.gMarkerManager=h,this.doFit=i,this.onDestroy=a(this.onDestroy,this),this.setGMarker=a(this.setGMarker,this),this.onWatch=a(this.onWatch,this),this.onTimeOut=a(this.onTimeOut,this),f.__super__.constructor.call(this,b,c,d,e,g),j=this}return c(f,b),f.include(d),f.include(e),f.prototype.onTimeOut=function(a){var b,c=this;return b=this.createMarkerOptions(a.coords,a.icon,a.options,this.mapCtrl.getMap()),this.setGMarker(new google.maps.Marker(b)),google.maps.event.addListener(this.scope.gMarker,"click",function(){return c.doClick&&null!=a.click?c.$timeout(function(){return c.scope.click()}):void 0}),this.setEvents(this.scope.gMarker,a,a),this.$log.info(this)},f.prototype.onWatch=function(a,b){switch(a){case"coords":return this.validateCoords(b.coords)&&null!=this.scope.gMarker?(this.scope.gMarker.setMap(this.mapCtrl.getMap()),this.scope.gMarker.setPosition(this.getCoords(b.coords)),this.scope.gMarker.setVisible(this.validateCoords(b.coords)),this.scope.gMarker.setOptions(b.options)):this.scope.gMarker.setMap(null);case"icon":if(null!=b.icon&&this.validateCoords(b.coords)&&null!=this.scope.gMarker)return this.scope.gMarker.setOptions(b.options),this.scope.gMarker.setIcon(b.icon),this.scope.gMarker.setMap(null),this.scope.gMarker.setMap(this.mapCtrl.getMap()),this.scope.gMarker.setPosition(this.getCoords(b.coords)),this.scope.gMarker.setVisible(this.validateCoords(b.coords));break;case"options":if(this.validateCoords(b.coords)&&null!=b.icon&&b.options)return null!=this.scope.gMarker&&this.scope.gMarker.setMap(null),this.setGMarker(new google.maps.Marker(this.createMarkerOptions(b.coords,b.icon,b.options,this.mapCtrl.getMap())))}},f.prototype.setGMarker=function(a){return this.scope.gMarker&&(delete this.scope.gMarker,this.gMarkerManager.remove(this.scope.gMarker,!1)),this.scope.gMarker=a,this.scope.gMarker&&(this.gMarkerManager.add(this.scope.gMarker,!1),this.doFit)?this.gMarkerManager.fit():void 0},f.prototype.onDestroy=function(){var a;return this.scope.gMarker?(this.scope.gMarker.setMap(null),this.gMarkerManager.remove(this.scope.gMarker,!1),delete this.scope.gMarker,a=void 0):void(a=void 0)},f}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.parent").factory("MarkersParentModel",["IMarkerParentModel","ModelsWatcher","PropMap","MarkerChildModel","ClustererMarkerManager","MarkerManager",function(b,d,e,f,g,h){var i;return i=function(b){function i(b,c,d,f,g){this.onDestroy=a(this.onDestroy,this),this.newChildMarker=a(this.newChildMarker,this),this.pieceMealMarkers=a(this.pieceMealMarkers,this),this.reBuildMarkers=a(this.reBuildMarkers,this),this.createMarkersFromScratch=a(this.createMarkersFromScratch,this),this.validateScope=a(this.validateScope,this),this.onWatch=a(this.onWatch,this),this.onTimeOut=a(this.onTimeOut,this);var h,j=this;i.__super__.constructor.call(this,b,c,d,f,g),h=this,this.scope.markerModels=new e,this.$timeout=g,this.$log.info(this),this.doRebuildAll=null!=this.scope.doRebuildAll?this.scope.doRebuildAll:!0,this.setIdKey(b),this.scope.$watch("doRebuildAll",function(a,b){return a!==b?j.doRebuildAll=a:void 0})}return c(i,b),i.include(d),i.prototype.onTimeOut=function(a){return this.watch("models",a),this.watch("doCluster",a),this.watch("clusterOptions",a),this.watch("clusterEvents",a),this.watch("fit",a),this.watch("idKey",a),this.gMarkerManager=void 0,this.createMarkersFromScratch(a)},i.prototype.onWatch=function(a,b,c,d){return"idKey"===a&&c!==d&&(this.idKey=c),this.doRebuildAll?this.reBuildMarkers(b):this.pieceMealMarkers(b)},i.prototype.validateScope=function(a){var b;return b=angular.isUndefined(a.models)||void 0===a.models,b&&this.$log.error(this.constructor.name+": no valid models attribute found"),i.__super__.validateScope.call(this,a)||b},i.prototype.createMarkersFromScratch=function(a){var b=this;return a.doCluster?(a.clusterEvents&&(this.clusterInternalOptions=_.once(function(){var c,d,e,f;return c=b,b.origClusterEvents?void 0:(b.origClusterEvents={click:null!=(d=a.clusterEvents)?d.click:void 0,mouseout:null!=(e=a.clusterEvents)?e.mouseout:void 0,mouseover:null!=(f=a.clusterEvents)?f.mouseover:void 0},_.extend(a.clusterEvents,{click:function(a){return c.maybeExecMappedEvent(a,"click")},mouseout:function(a){return c.maybeExecMappedEvent(a,"mouseout")},mouseover:function(a){return c.maybeExecMappedEvent(a,"mouseover")}}))})()),a.clusterOptions||a.clusterEvents?void 0===this.gMarkerManager?this.gMarkerManager=new g(this.mapCtrl.getMap(),void 0,a.clusterOptions,this.clusterInternalOptions):this.gMarkerManager.opt_options!==a.clusterOptions&&(this.gMarkerManager=new g(this.mapCtrl.getMap(),void 0,a.clusterOptions,this.clusterInternalOptions)):this.gMarkerManager=new g(this.mapCtrl.getMap())):this.gMarkerManager=new h(this.mapCtrl.getMap()),_async.each(a.models,function(c){return b.newChildMarker(c,a)},function(){return b.gMarkerManager.draw(),a.fit?b.gMarkerManager.fit():void 0})},i.prototype.reBuildMarkers=function(a){return a.doRebuild||void 0===a.doRebuild?(this.onDestroy(a),this.createMarkersFromScratch(a)):void 0},i.prototype.pieceMealMarkers=function(a){var b=this;return null!=this.scope.models&&this.scope.models.length>0&&this.scope.markerModels.length>0?this.figureOutState(this.idKey,a,this.scope.markerModels,this.modelKeyComparison,function(c){var d;return d=c,_async.each(d.removals,function(a){return null!=a?(a.destroy(),b.scope.markerModels.remove(a.id)):void 0},function(){return _async.each(d.adds,function(c){return b.newChildMarker(c,a)},function(){return b.gMarkerManager.draw(),a.markerModels=b.scope.markerModels})})}):this.reBuildMarkers(a)},i.prototype.newChildMarker=function(a,b){var c;return null==a[this.idKey]?void this.$log.error("Marker model has no id to assign a child to. This is required for performance. Please assign id, or redirect id to a different key."):(this.$log.info("child",c,"markers",this.scope.markerModels),c=new f(a,b,this.mapCtrl,this.$timeout,this.DEFAULTS,this.doClick,this.gMarkerManager,this.idKey),this.scope.markerModels.put(a[this.idKey],c),c)},i.prototype.onDestroy=function(){return _.each(this.scope.markerModels.values(),function(a){return null!=a?a.destroy():void 0}),delete this.scope.markerModels,this.scope.markerModels=new e,null!=this.gMarkerManager?this.gMarkerManager.clear():void 0},i.prototype.maybeExecMappedEvent=function(a,b){var c,d;return _.isFunction(null!=(d=this.scope.clusterEvents)?d[b]:void 0)&&(c=this.mapClusterToMarkerModels(a),this.origClusterEvents[b])?this.origClusterEvents[b](c.cluster,c.mapped):void 0},i.prototype.mapClusterToMarkerModels=function(a){var b,c,d=this;return b=a.getMarkers(),c=b.map(function(a){return d.scope.markerModels[a.key].model}),{cluster:a,mapped:c}},i}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.parent").factory("PolylinesParentModel",["$timeout","Logger","ModelKey","ModelsWatcher","PropMap","PolylineChildModel",function(b,d,e,f,g,h){var i;return i=function(e){function i(c,e,f,h,j){var k,l=this;this.scope=c,this.element=e,this.attrs=f,this.gMap=h,this.defaults=j,this.modelKeyComparison=a(this.modelKeyComparison,this),this.setChildScope=a(this.setChildScope,this),this.createChild=a(this.createChild,this),this.pieceMeal=a(this.pieceMeal,this),this.createAllNew=a(this.createAllNew,this),this.watchIdKey=a(this.watchIdKey,this),this.createChildScopes=a(this.createChildScopes,this),this.watchOurScope=a(this.watchOurScope,this),this.watchDestroy=a(this.watchDestroy,this),this.rebuildAll=a(this.rebuildAll,this),this.doINeedToWipe=a(this.doINeedToWipe,this),this.watchModels=a(this.watchModels,this),this.watch=a(this.watch,this),i.__super__.constructor.call(this,c),k=this,this.$log=d,this.plurals=new g,this.scopePropNames=["path","stroke","clickable","draggable","editable","geodesic","icons","visible"],_.each(this.scopePropNames,function(a){return this[a+"Key"]=void 0}),this.models=void 0,this.firstTime=!0,this.$log.info(this),b(function(){return l.watchOurScope(c),l.createChildScopes()})}return c(i,e),i.include(f),i.prototype.watch=function(a,b,c){var d=this;return a.$watch(b,function(a,e){return a!==e?(d[c]="function"==typeof a?a():a,_async.each(_.values(d.plurals),function(a){return a.scope[b]="self"===d[c]?a:a[d[c]]},function(){})):void 0})},i.prototype.watchModels=function(a){var b=this;return a.$watch("models",function(c,d){return _.isEqual(c,d)?void 0:b.doINeedToWipe(c)?b.rebuildAll(a,!0,!0):b.createChildScopes(!1)},!0)},i.prototype.doINeedToWipe=function(a){var b;return b=null!=a?0===a.length:!0,this.plurals.length>0&&b},i.prototype.rebuildAll=function(a,b,c){var d=this;return _async.each(this.plurals.values(),function(a){return a.destroy()},function(){return c&&delete d.plurals,d.plurals=new g,b?d.createChildScopes():void 0})},i.prototype.watchDestroy=function(a){var b=this;return a.$on("$destroy",function(){return b.rebuildAll(a,!1,!0)})},i.prototype.watchOurScope=function(a){var b=this;return _.each(this.scopePropNames,function(c){var d;return d=c+"Key",b[d]="function"==typeof a[c]?a[c]():a[c],b.watch(a,c,d)})},i.prototype.createChildScopes=function(a){return null==a&&(a=!0),angular.isUndefined(this.scope.models)?void this.$log.error("No models to create polylines from! I Need direct models!"):null!=this.gMap&&null!=this.scope.models?(this.watchIdKey(this.scope),a?this.createAllNew(this.scope,!1):this.pieceMeal(this.scope,!1)):void 0},i.prototype.watchIdKey=function(a){var b=this;return this.setIdKey(a),a.$watch("idKey",function(c,d){return c!==d&&null==c?(b.idKey=c,b.rebuildAll(a,!0,!0)):void 0})},i.prototype.createAllNew=function(a,b){var c=this;return null==b&&(b=!1),this.models=a.models,this.firstTime&&(this.watchModels(a),this.watchDestroy(a)),_async.each(a.models,function(a){return c.createChild(a,c.gMap)},function(){return c.firstTime=!1})},i.prototype.pieceMeal=function(a,b){var c=this;return null==b&&(b=!0),this.models=a.models,null!=a&&null!=a.models&&a.models.length>0&&this.plurals.length>0?this.figureOutState(this.idKey,a,this.plurals,this.modelKeyComparison,function(a){var b;return b=a,_async.each(b.removals,function(a){var b;return b=c.plurals[a],null!=b?(b.destroy(),c.plurals.remove(a)):void 0},function(){return _async.each(b.adds,function(a){return c.createChild(a,c.gMap)},function(){})})}):this.rebuildAll(this.scope,!0,!0)},i.prototype.createChild=function(a,b){var c,d,e=this;return d=this.scope.$new(!1),this.setChildScope(d,a),d.$watch("model",function(a,b){return a!==b?e.setChildScope(d,a):void 0},!0),d["static"]=this.scope["static"],c=new h(d,this.attrs,b,this.defaults,a),null==a[this.idKey]?void this.$log.error("Polyline model has no id to assign a child to. This is required for performance. Please assign id, or redirect id to a different key."):(this.plurals.put(a[this.idKey],c),c)},i.prototype.setChildScope=function(a,b){var c=this;return _.each(this.scopePropNames,function(d){var e,f;return e=d+"Key",f="self"===c[e]?b:b[c[e]],f!==a[d]?a[d]=f:void 0}),a.model=b},i.prototype.modelKeyComparison=function(a,b){return _.isEqual(this.evalModelHandle(a,this.scope.path),this.evalModelHandle(b,this.scope.path))},i}(e)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.parent").factory("WindowsParentModel",["IWindowParentModel","ModelsWatcher","PropMap","WindowChildModel","Linked",function(b,d,e,f,g){var h;return h=function(b){function h(b,c,d,f,i,j,k,l,m){var n,o=this;this.$interpolate=m,this.interpolateContent=a(this.interpolateContent,this),this.setChildScope=a(this.setChildScope,this),this.createWindow=a(this.createWindow,this),this.setContentKeys=a(this.setContentKeys,this),this.pieceMealWindows=a(this.pieceMealWindows,this),this.createAllNewWindows=a(this.createAllNewWindows,this),this.watchIdKey=a(this.watchIdKey,this),this.createChildScopesWindows=a(this.createChildScopesWindows,this),this.watchOurScope=a(this.watchOurScope,this),this.watchDestroy=a(this.watchDestroy,this),this.rebuildAll=a(this.rebuildAll,this),this.doINeedToWipe=a(this.doINeedToWipe,this),this.watchModels=a(this.watchModels,this),this.watch=a(this.watch,this),h.__super__.constructor.call(this,b,c,d,f,i,j,k,l),n=this,this.windows=new e,this.scopePropNames=["show","coords","templateUrl","templateParameter","isIconVisibleOnClick","closeClick"],_.each(this.scopePropNames,function(a){return this[a+"Key"]=void 0}),this.linked=new g(b,c,d,f),this.models=void 0,this.contentKeys=void 0,this.isIconVisibleOnClick=void 0,this.firstTime=!0,this.$log.info(n),this.parentScope=void 0,this.$timeout(function(){return o.watchOurScope(b),o.doRebuildAll=null!=o.scope.doRebuildAll?o.scope.doRebuildAll:!0,b.$watch("doRebuildAll",function(a,b){return a!==b?o.doRebuildAll=a:void 0}),o.createChildScopesWindows()},50)}return c(h,b),h.include(d),h.prototype.watch=function(a,b,c){var d=this;return a.$watch(b,function(a,e){return a!==e?(d[c]="function"==typeof a?a():a,_async.each(_.values(d.windows),function(a){return a.scope[b]="self"===d[c]?a:a[d[c]]},function(){})):void 0})},h.prototype.watchModels=function(a){var b=this;return a.$watch("models",function(c,d){return _.isEqual(c,d)?void 0:b.doRebuildAll||b.doINeedToWipe(c)?b.rebuildAll(a,!0,!0):b.createChildScopesWindows(!1)})},h.prototype.doINeedToWipe=function(a){var b;return b=null!=a?0===a.length:!0,this.windows.length>0&&b},h.prototype.rebuildAll=function(a,b,c){var d=this;return _async.each(this.windows.values(),function(a){return a.destroy()},function(){return c&&delete d.windows,d.windows=new e,b?d.createChildScopesWindows():void 0})},h.prototype.watchDestroy=function(a){var b=this;return a.$on("$destroy",function(){return b.rebuildAll(a,!1,!0)})},h.prototype.watchOurScope=function(a){var b=this;return _.each(this.scopePropNames,function(c){var d;return d=c+"Key",b[d]="function"==typeof a[c]?a[c]():a[c],b.watch(a,c,d)})},h.prototype.createChildScopesWindows=function(a){var b,c;return null==a&&(a=!0),this.isIconVisibleOnClick=!0,angular.isDefined(this.linked.attrs.isiconvisibleonclick)&&(this.isIconVisibleOnClick=this.linked.scope.isIconVisibleOnClick),this.gMap=this.linked.ctrls[0].getMap(),null!=this.linked.ctrls[1]&&(b=this.linked.ctrls.length>1?this.linked.ctrls[1].getMarkersScope():void 0),c=angular.isUndefined(this.linked.scope.models),!c||void 0!==b&&void 0!==b.markerModels&&void 0!==b.models?null!=this.gMap?null!=this.linked.scope.models?(this.watchIdKey(this.linked.scope),a?this.createAllNewWindows(this.linked.scope,!1):this.pieceMealWindows(this.linked.scope,!1)):(this.parentScope=b,this.watchIdKey(this.parentScope),a?this.createAllNewWindows(b,!0,"markerModels",!1):this.pieceMealWindows(b,!0,"markerModels",!1)):void 0:void this.$log.error("No models to create windows from! Need direct models or models derrived from markers!")},h.prototype.watchIdKey=function(a){var b=this;return this.setIdKey(a),a.$watch("idKey",function(c,d){return c!==d&&null==c?(b.idKey=c,b.rebuildAll(a,!0,!0)):void 0})},h.prototype.createAllNewWindows=function(a,b,c,d){var e=this;return null==c&&(c="models"),null==d&&(d=!1),this.models=a.models,this.firstTime&&(this.watchModels(a),this.watchDestroy(a)),this.setContentKeys(a.models),_async.each(a.models,function(d){var f;return f=b?a[c][[d[e.idKey]]].gMarker:void 0,e.createWindow(d,f,e.gMap)},function(){return e.firstTime=!1})},h.prototype.pieceMealWindows=function(a,b,c,d){var e=this;return null==c&&(c="models"),null==d&&(d=!0),this.models=a.models,null!=a&&null!=a.models&&a.models.length>0&&this.windows.length>0?this.figureOutState(this.idKey,a,this.windows,this.modelKeyComparison,function(b){var d;return d=b,_async.each(d.removals,function(a){return null!=a?(a.destroy(),e.windows.remove(a.id)):void 0},function(){return _async.each(d.adds,function(b){var d;return d=a[c][b[e.idKey]].gMarker,e.createWindow(b,d,e.gMap)},function(){})})}):this.rebuildAll(this.scope,!0,!0)},h.prototype.setContentKeys=function(a){return a.length>0?this.contentKeys=Object.keys(a[0]):void 0},h.prototype.createWindow=function(a,b,c){var d,e,g,h,i=this;return e=this.linked.scope.$new(!1),this.setChildScope(e,a),e.$watch("model",function(a,b){return a!==b?i.setChildScope(e,a):void 0},!0),g={html:function(){return i.interpolateContent(i.linked.element.html(),a)}},h=this.createWindowOptions(b,e,g.html(),this.DEFAULTS),d=new f(a,e,h,this.isIconVisibleOnClick,c,b,g,!0,!0),null==a[this.idKey]?void this.$log.error("Window model has no id to assign a child to. This is required for performance. Please assign id, or redirect id to a different key."):(this.windows.put(a[this.idKey],d),d)},h.prototype.setChildScope=function(a,b){var c=this;return _.each(this.scopePropNames,function(d){var e,f;return e=d+"Key",f="self"===c[e]?b:b[c[e]],f!==a[d]?a[d]=f:void 0}),a.model=b},h.prototype.interpolateContent=function(a,b){var c,d,e,f,g,h;if(void 0!==this.contentKeys&&0!==this.contentKeys.length){for(c=this.$interpolate(a),d={},h=this.contentKeys,f=0,g=h.length;g>f;f++)e=h[f],d[e]=b[e];return c(d)}},h}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api").factory("ILabel",["BaseObject","Logger",function(b,d){var e;return e=function(b){function e(b){this.link=a(this.link,this);var c;c=this,this.restrict="ECMA",this.replace=!0,this.template=void 0,this.require=void 0,this.transclude=!0,this.priority=-100,this.scope={labelContent:"=content",labelAnchor:"@anchor",labelClass:"@class",labelStyle:"=style"},this.$log=d,this.$timeout=b}return c(e,b),e.prototype.link=function(){throw new Exception("Not Implemented!!")},e}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api").factory("IMarker",["Logger","BaseObject",function(b,d){var e;return e=function(d){function e(c){this.link=a(this.link,this);var d;d=this,this.$log=b,this.$timeout=c,this.restrict="ECMA",this.require="^googleMap",this.priority=-1,this.transclude=!0,this.replace=!0,this.scope={coords:"=coords",icon:"=icon",click:"&click",options:"=options",events:"=events",fit:"=fit"}}return c(e,d),e.prototype.controller=["$scope","$element",function(){throw new Exception("Not Implemented!!")}],e.prototype.link=function(){throw new Exception("Not implemented!!")},e}(d)}])}.call(this),function(){var a={}.hasOwnProperty,b=function(b,c){function d(){this.constructor=b}for(var e in c)a.call(c,e)&&(b[e]=c[e]);return d.prototype=c.prototype,b.prototype=new d,b.__super__=c.prototype,b};angular.module("google-maps.directives.api").factory("IPolyline",["GmapUtil","BaseObject","Logger",function(a,c,d){var e;return e=function(c){function e(){var a;a=this}return b(e,c),e.include(a),e.prototype.restrict="ECA",e.prototype.replace=!0,e.prototype.require="^googleMap",e.prototype.scope={path:"=",stroke:"=",clickable:"=",draggable:"=",editable:"=",geodesic:"=",icons:"=",visible:"=","static":"="},e.prototype.DEFAULTS={},e.prototype.$log=d,e}(c)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api").factory("IWindow",["BaseObject","ChildEvents","Logger",function(b,d,e){var f;return f=function(b){function f(b,c,d,f){var g;this.$timeout=b,this.$compile=c,this.$http=d,this.$templateCache=f,this.link=a(this.link,this),g=this,this.restrict="ECMA",this.template=void 0,this.transclude=!0,this.priority=-100,this.require=void 0,this.replace=!0,this.scope={coords:"=coords",show:"=show",templateUrl:"=templateurl",templateParameter:"=templateparameter",isIconVisibleOnClick:"=isiconvisibleonclick",closeClick:"&closeclick",options:"=options"},this.$log=e}return c(f,b),f.include(d),f.prototype.link=function(){throw new Exception("Not Implemented!!")},f}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api").factory("Map",["$timeout","Logger","GmapUtil","BaseObject",function(b,d,e,f){"use strict"; -var g,h,i;return g=d,h={mapTypeId:google.maps.MapTypeId.ROADMAP},i=function(b){function d(){this.link=a(this.link,this);var b;b=this}return c(d,b),d.include(e),d.prototype.restrict="ECMA",d.prototype.transclude=!0,d.prototype.replace=!1,d.prototype.template='
',d.prototype.scope={center:"=center",zoom:"=zoom",dragging:"=dragging",control:"=",windows:"=windows",options:"=options",events:"=events",styles:"=styles",bounds:"=bounds"},d.prototype.controller=["$scope",function(a){return{getMap:function(){return a.map}}}],d.prototype.link=function(a,b,c){var d,e,f,i,j,k,l,m,n=this;if(!this.validateCoords(a.center))return void g.error("angular-google-maps: could not find a valid center property");if(!angular.isDefined(a.zoom))return void g.error("angular-google-maps: map zoom property not set");if(e=angular.element(b),e.addClass("angular-google-map"),j={options:{}},c.options&&(j.options=a.options),c.styles&&(j.styles=a.styles),c.type&&(l=c.type.toUpperCase(),google.maps.MapTypeId.hasOwnProperty(l)?j.mapTypeId=google.maps.MapTypeId[c.type.toUpperCase()]:g.error('angular-google-maps: invalid map type "'+c.type+'"')),m=new google.maps.Map(e.find("div")[1],angular.extend({},h,j,{center:this.getCoords(a.center),draggable:this.isTrue(c.draggable),zoom:a.zoom,bounds:a.bounds})),d=!1,google.maps.event.addListener(m,"dragstart",function(){return d=!0,_.defer(function(){return a.$apply(function(a){return null!=a.dragging?a.dragging=d:void 0})})}),google.maps.event.addListener(m,"dragend",function(){return d=!1,_.defer(function(){return a.$apply(function(a){return null!=a.dragging?a.dragging=d:void 0})})}),google.maps.event.addListener(m,"drag",function(){var b;return b=m.center,_.defer(function(){return a.$apply(function(a){return angular.isDefined(a.center.type)?(a.center.coordinates[1]=b.lat(),a.center.coordinates[0]=b.lng()):(a.center.latitude=b.lat(),a.center.longitude=b.lng())})})}),google.maps.event.addListener(m,"zoom_changed",function(){return a.zoom!==m.zoom?_.defer(function(){return a.$apply(function(a){return a.zoom=m.zoom})}):void 0}),k=!1,google.maps.event.addListener(m,"center_changed",function(){var b;return b=m.center,k?void 0:_.defer(function(){return a.$apply(function(a){if(!m.dragging)if(angular.isDefined(a.center.type)){if(a.center.coordinates[1]!==b.lat()&&(a.center.coordinates[1]=b.lat()),a.center.coordinates[0]!==b.lng())return a.center.coordinates[0]=b.lng()}else if(a.center.latitude!==b.lat()&&(a.center.latitude=b.lat()),a.center.longitude!==b.lng())return a.center.longitude=b.lng()})})}),google.maps.event.addListener(m,"idle",function(){var b,c,d;return b=m.getBounds(),c=b.getNorthEast(),d=b.getSouthWest(),_.defer(function(){return a.$apply(function(a){return null!==a.bounds&&void 0!==a.bounds&&void 0!==a.bounds?(a.bounds.northeast={latitude:c.lat(),longitude:c.lng()},a.bounds.southwest={latitude:d.lat(),longitude:d.lng()}):void 0})})}),angular.isDefined(a.events)&&null!==a.events&&angular.isObject(a.events)){i=function(b){return function(){return a.events[b].apply(a,[m,b,arguments])}};for(f in a.events)a.events.hasOwnProperty(f)&&angular.isFunction(a.events[f])&&google.maps.event.addListener(m,f,i(f))}return a.map=m,null!=c.control&&null!=a.control&&(a.control.refresh=function(a){var b;if(null!=m)return google.maps.event.trigger(m,"resize"),null!=(null!=a?a.latitude:void 0)&&null!=(null!=a?a.latitude:void 0)?(b=n.getCoords(a),n.isTrue(c.pan)?m.panTo(b):m.setCenter(b)):void 0},a.control.getGMap=function(){return m}),a.$watch("center",function(b,e){var f;return f=n.getCoords(b),b===e||f.lat()===m.center.lat()&&f.lng()===m.center.lng()?void 0:(k=!0,d||(n.validateCoords(b)||g.error("Invalid center for newValue: "+JSON.stringify(b)),n.isTrue(c.pan)&&a.zoom===m.zoom?m.panTo(f):m.setCenter(f)),k=!1)},!0),a.$watch("zoom",function(a,b){return a!==b&&a!==m.zoom?_.defer(function(){return m.setZoom(a)}):void 0}),a.$watch("bounds",function(a,b){var c,d,e;if(a!==b)return null==a.northeast.latitude||null==a.northeast.longitude||null==a.southwest.latitude||null==a.southwest.longitude?void g.error("Invalid map bounds for new value: "+JSON.stringify(a)):(d=new google.maps.LatLng(a.northeast.latitude,a.northeast.longitude),e=new google.maps.LatLng(a.southwest.latitude,a.southwest.longitude),c=new google.maps.LatLngBounds(e,d),m.fitBounds(c))}),a.$watch("options",function(a,b){return _.isEqual(a,b)||(j.options=a,null==m)?void 0:m.setOptions(j)},!0),a.$watch("styles",function(a,b){return _.isEqual(a,b)||(j.styles=a,null==m)?void 0:m.setOptions(j)},!0)},d}(f)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api").factory("Marker",["IMarker","MarkerParentModel","MarkerManager",function(b,d,e){var f;return f=function(b){function f(b){this.link=a(this.link,this);var c;f.__super__.constructor.call(this,b),c=this,this.template='',this.$log.info(this)}return c(f,b),f.prototype.controller=["$scope","$element",function(a){return{getMarkerScope:function(){return a}}}],f.prototype.link=function(a,b,c,f){var g;return a.fit&&(g=!0),this.gMarkerManager||(this.gMarkerManager=new e(f.getMap())),new d(a,b,c,f,this.$timeout,this.gMarkerManager,g)},f}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api").factory("Markers",["IMarker","MarkersParentModel",function(b,d){var e;return e=function(b){function e(b){this.link=a(this.link,this);var c;e.__super__.constructor.call(this,b),this.template='',this.scope.idKey="=idkey",this.scope.doRebuildAll="=dorebuildall",this.scope.models="=models",this.scope.doCluster="=docluster",this.scope.clusterOptions="=clusteroptions",this.scope.clusterEvents="=clusterevents",this.scope.labelContent="=labelcontent",this.scope.labelAnchor="@labelanchor",this.scope.labelClass="@labelclass",this.$timeout=b,c=this,this.$log.info(this)}return c(e,b),e.prototype.controller=["$scope","$element",function(a){return{getMarkersScope:function(){return a}}}],e.prototype.link=function(a,b,c,e){return new d(a,b,c,e,this.$timeout)},e}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api").factory("Polyline",["IPolyline","$timeout","array-sync","PolylineChildModel",function(b,d,e,f){var g,h;return g=function(b){function e(){return this.link=a(this.link,this),h=e.__super__.constructor.apply(this,arguments)}return c(e,b),e.prototype.link=function(a,b,c,e){var g=this;return angular.isUndefined(a.path)||null===a.path||!this.validatePath(a.path)?void this.$log.error("polyline: no valid path attribute found"):d(function(){return new f(a,c,e.getMap(),g.DEFAULTS)})},e}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api").factory("Polylines",["IPolyline","$timeout","array-sync","PolylinesParentModel",function(b,d,e,f){var g;return g=function(b){function e(){this.link=a(this.link,this),e.__super__.constructor.call(this),this.scope.idKey="=idkey",this.scope.models="=models",this.$log.info(this)}return c(e,b),e.prototype.link=function(a,b,c,e){var g=this;return angular.isUndefined(a.path)||null===a.path?void this.$log.error("polylines: no valid path attribute found"):a.models?d(function(){return new f(a,b,c,e.getMap(),g.DEFAULTS)}):void this.$log.error("polylines: no models found to create from")},e}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api").factory("Window",["IWindow","GmapUtil","WindowChildModel",function(b,d,e){var f;return f=function(b){function f(b,c,d,e){this.link=a(this.link,this);var g;f.__super__.constructor.call(this,b,c,d,e),g=this,this.require=["^googleMap","^?marker"],this.template='',this.$log.info(g)}return c(f,b),f.include(d),f.prototype.link=function(a,b,c,f){var g=this;return this.$timeout(function(){var d,h,i,j,k,l,m,n;return i=!0,angular.isDefined(c.isiconvisibleonclick)&&(i=a.isIconVisibleOnClick),j=f[0].getMap(),k=f.length>1&&null!=f[1]?f[1].getMarkerScope().gMarker:void 0,d=null!=a.options?a.options:{},h=null!=a&&g.validateCoords(a.coords),m=h?g.createWindowOptions(k,a,b.html(),d):d,null!=j&&(n=new e({},a,m,i,j,k,b)),a.$on("$destroy",function(){return n.destroy()}),null!=f[1]&&(l=f[1].getMarkerScope(),l.$watch("coords",function(a,b){return g.validateCoords(a)?angular.equals(a,b)?void 0:n.getLatestPosition():n.hideWindow()},!0)),null!=g.onChildCreation&&null!=n?g.onChildCreation(n):void 0},d.defaultDelay+25)},f}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api").factory("Windows",["IWindow","WindowsParentModel",function(b,d){var e;return e=function(b){function e(b,c,d,f,g){this.link=a(this.link,this);var h;e.__super__.constructor.call(this,b,c,d,f),h=this,this.$interpolate=g,this.require=["^googleMap","^?markers"],this.template='',this.scope.idKey="=idkey",this.scope.doRebuildAll="=dorebuildall",this.scope.models="=models",this.$log.info(this)}return c(e,b),e.prototype.link=function(a,b,c,e){return new d(a,b,c,e,this.$timeout,this.$compile,this.$http,this.$templateCache,this.$interpolate)},e}(b)}])}.call(this),function(){angular.module("google-maps").directive("googleMap",["Map",function(a){return new a}])}.call(this),function(){angular.module("google-maps").directive("marker",["$timeout","Marker",function(a,b){return new b(a)}])}.call(this),function(){angular.module("google-maps").directive("markers",["$timeout","Markers",function(a,b){return new b(a)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps").directive("markerLabel",["$timeout","ILabel","MarkerLabelChildModel","GmapUtil",function(b,d,e,f){var g;return new(g=function(b){function d(b){this.link=a(this.link,this);var c;d.__super__.constructor.call(this,b),c=this,this.require="^marker",this.template='',this.$log.info(this)}return c(d,b),d.prototype.link=function(a,b,c,d){return this.$timeout(function(){var b,c;return c=d.getMarkerScope().gMarker,null!=c&&(b=new e(c,a)),a.$on("$destroy",function(){return b.destroy()})},f.defaultDelay+25)},d}(d))(b)}])}.call(this),function(){angular.module("google-maps").directive("polygon",["$log","$timeout","array-sync","GmapUtil",function(a,b,c,d){var e,f;return f=function(a){return angular.isDefined(a)&&null!==a&&a===!0||"1"===a||"y"===a||"true"===a},e={},{restrict:"ECA",replace:!0,require:"^googleMap",scope:{path:"=path",stroke:"=stroke",clickable:"=",draggable:"=",editable:"=",geodesic:"=",fill:"=",icons:"=icons",visible:"=","static":"=",events:"=",zIndex:"=zindex"},link:function(g,h,i,j){return angular.isUndefined(g.path)||null===g.path||!d.validatePath(g.path)?void a.error("polygon: no valid path attribute found"):b(function(){var a,b,h,k,l,m;if(b=function(a){var b;return b=angular.extend({},e,{map:l,path:a,strokeColor:g.stroke&&g.stroke.color,strokeOpacity:g.stroke&&g.stroke.opacity,strokeWeight:g.stroke&&g.stroke.weight,fillColor:g.fill&&g.fill.color,fillOpacity:g.fill&&g.fill.opacity}),angular.forEach({clickable:!0,draggable:!1,editable:!1,geodesic:!1,visible:!0,"static":!1,zIndex:0},function(a,c){return b[c]=angular.isUndefined(g[c])||null===g[c]?a:g[c]}),b["static"]&&(b.editable=!1),b},l=j.getMap(),m=new google.maps.Polygon(b(d.convertPathPoints(g.path))),f(i.fit)&&d.extendMapBounds(l,pathPoints),!g["static"]&&angular.isDefined(g.editable)&&g.$watch("editable",function(a,b){return a!==b?m.setEditable(a):void 0}),angular.isDefined(g.draggable)&&g.$watch("draggable",function(a,b){return a!==b?m.setDraggable(a):void 0}),angular.isDefined(g.visible)&&g.$watch("visible",function(a,b){return a!==b?m.setVisible(a):void 0}),angular.isDefined(g.geodesic)&&g.$watch("geodesic",function(a,c){return a!==c?m.setOptions(b(m.getPath())):void 0}),angular.isDefined(g.stroke)&&angular.isDefined(g.stroke.opacity)&&g.$watch("stroke.opacity",function(){return m.setOptions(b(m.getPath()))}),angular.isDefined(g.stroke)&&angular.isDefined(g.stroke.weight)&&g.$watch("stroke.weight",function(a,c){return a!==c?m.setOptions(b(m.getPath())):void 0}),angular.isDefined(g.stroke)&&angular.isDefined(g.stroke.color)&&g.$watch("stroke.color",function(a,c){return a!==c?m.setOptions(b(m.getPath())):void 0}),angular.isDefined(g.fill)&&angular.isDefined(g.fill.color)&&g.$watch("fill.color",function(a,c){return a!==c?m.setOptions(b(m.getPath())):void 0}),angular.isDefined(g.fill)&&angular.isDefined(g.fill.opacity)&&g.$watch("fill.opacity",function(a,c){return a!==c?m.setOptions(b(m.getPath())):void 0}),angular.isDefined(g.zIndex)&&g.$watch("zIndex",function(a,c){return a!==c?m.setOptions(b(m.getPath())):void 0}),angular.isDefined(g.events)&&null!==g.events&&angular.isObject(g.events)){k=function(a){return function(){return g.events[a].apply(g,[m,a,arguments])}};for(h in g.events)g.events.hasOwnProperty(h)&&angular.isFunction(g.events[h])&&m.addListener(h,k(h))}return a=c(m.getPath(),g,"path"),g.$on("$destroy",function(){return m.setMap(null),a?(a(),a=null):void 0})})}}}])}.call(this),function(){angular.module("google-maps").directive("circle",["$log","$timeout","GmapUtil",function(a,b,c){"use strict";var d;return d={},{restrict:"ECA",replace:!0,require:"^googleMap",scope:{center:"=center",radius:"=radius",stroke:"=stroke",fill:"=fill",clickable:"=",draggable:"=",editable:"=",geodesic:"=",icons:"=icons",visible:"="},link:function(e,f,g,h){return b(function(){var f,g,i;return f=function(){var b;return c.validateCoords(e.center)?(b=angular.extend({},d,{map:i,center:c.getCoords(e.center),radius:e.radius,strokeColor:e.stroke&&e.stroke.color,strokeOpacity:e.stroke&&e.stroke.opacity,strokeWeight:e.stroke&&e.stroke.weight,fillColor:e.fill&&e.fill.color,fillOpacity:e.fill&&e.fill.opacity}),angular.forEach({clickable:!0,draggable:!1,editable:!1,geodesic:!1,visible:!0},function(a,c){return b[c]=angular.isUndefined(e[c])||null===e[c]?a:e[c]}),b):void a.error("circle: no valid center attribute found")},i=h.getMap(),g=new google.maps.Circle(f()),e.$watchCollection("center",function(a,b){return a!==b?g.setOptions(f()):void 0}),e.$watchCollection("stroke",function(a,b){return a!==b?g.setOptions(f()):void 0}),e.$watchCollection("fill",function(a,b){return a!==b?g.setOptions(f()):void 0}),e.$watch("radius",function(a,b){return a!==b?g.setOptions(f()):void 0}),e.$watch("clickable",function(a,b){return a!==b?g.setOptions(f()):void 0}),e.$watch("editable",function(a,b){return a!==b?g.setOptions(f()):void 0}),e.$watch("draggable",function(a,b){return a!==b?g.setOptions(f()):void 0}),e.$watch("visible",function(a,b){return a!==b?g.setOptions(f()):void 0}),e.$watch("geodesic",function(a,b){return a!==b?g.setOptions(f()):void 0}),google.maps.event.addListener(g,"radius_changed",function(){return e.radius=g.getRadius(),b(function(){return e.$apply()})}),google.maps.event.addListener(g,"center_changed",function(){return angular.isDefined(e.center.type)?(e.center.coordinates[1]=g.getCenter().lat(),e.center.coordinates[0]=g.getCenter().lng()):(e.center.latitude=g.getCenter().lat(),e.center.longitude=g.getCenter().lng()),b(function(){return e.$apply()})}),e.$on("$destroy",function(){return g.setMap(null)})})}}}])}.call(this),function(){angular.module("google-maps").directive("polyline",["Polyline",function(a){return new a}])}.call(this),function(){angular.module("google-maps").directive("polylines",["Polylines",function(a){return new a}])}.call(this),function(){angular.module("google-maps").directive("rectangle",["$log","$timeout",function(a,b){var c,d,e,f,g;return g=function(a){return angular.isUndefined(a.sw.latitude)||angular.isUndefined(a.sw.longitude)||angular.isUndefined(a.ne.latitude)||angular.isUndefined(a.ne.longitude)?!1:!0},d=function(a){var b;return b=new google.maps.LatLngBounds(new google.maps.LatLng(a.sw.latitude,a.sw.longitude),new google.maps.LatLng(a.ne.latitude,a.ne.longitude))},e=function(a,b){return a.fitBounds(b)},f=function(a){return angular.isDefined(a)&&null!==a&&a===!0||"1"===a||"y"===a||"true"===a},c={},{restrict:"ECA",require:"^googleMap",replace:!0,scope:{bounds:"=",stroke:"=",clickable:"=",draggable:"=",editable:"=",fill:"=",visible:"="},link:function(h,i,j,k){return angular.isUndefined(h.bounds)||null===h.bounds||angular.isUndefined(h.bounds.sw)||null===h.bounds.sw||angular.isUndefined(h.bounds.ne)||null===h.bounds.ne||!g(h.bounds)?void a.error("rectangle: no valid bound attribute found"):b(function(){var b,g,i,l,m;return b=function(a){var b;return b=angular.extend({},c,{map:i,bounds:a,strokeColor:h.stroke&&h.stroke.color,strokeOpacity:h.stroke&&h.stroke.opacity,strokeWeight:h.stroke&&h.stroke.weight,fillColor:h.fill&&h.fill.color,fillOpacity:h.fill&&h.fill.opacity}),angular.forEach({clickable:!0,draggable:!1,editable:!1,visible:!0},function(a,c){return b[c]=angular.isUndefined(h[c])||null===h[c]?a:h[c]}),b},i=k.getMap(),l=new google.maps.Rectangle(b(d(h.bounds))),f(j.fit)&&e(i,bounds),g=!1,google.maps.event.addListener(l,"mousedown",function(){google.maps.event.addListener(l,"mousemove",function(){return g=!0,_.defer(function(){return h.$apply(function(a){return null!=a.dragging?a.dragging=g:void 0})})}),google.maps.event.addListener(l,"mouseup",function(){return google.maps.event.clearListeners(l,"mousemove"),google.maps.event.clearListeners(l,"mouseup"),g=!1,_.defer(function(){return h.$apply(function(a){return null!=a.dragging?a.dragging=g:void 0})})})}),m=!1,google.maps.event.addListener(l,"bounds_changed",function(){var a,b,c;return a=l.getBounds(),b=a.getNorthEast(),c=a.getSouthWest(),m?void 0:_.defer(function(){return h.$apply(function(a){l.dragging||null!==a.bounds&&void 0!==a.bounds&&void 0!==a.bounds&&(a.bounds.ne={latitude:b.lat(),longitude:b.lng()},a.bounds.sw={latitude:c.lat(),longitude:c.lng()})})})}),h.$watch("bounds",function(b,c){var d;if(!_.isEqual(b,c))return m=!0,g||((null==b.sw.latitude||null==b.sw.longitude||null==b.ne.latitude||null==b.ne.longitude)&&a.error("Invalid bounds for newValue: "+JSON.stringify(b)),d=new google.maps.LatLngBounds(new google.maps.LatLng(b.sw.latitude,b.sw.longitude),new google.maps.LatLng(b.ne.latitude,b.ne.longitude)),l.setBounds(d)),m=!1},!0),angular.isDefined(h.editable)&&h.$watch("editable",function(a){return l.setEditable(a)}),angular.isDefined(h.draggable)&&h.$watch("draggable",function(a){return l.setDraggable(a)}),angular.isDefined(h.visible)&&h.$watch("visible",function(a){return l.setVisible(a)}),angular.isDefined(h.stroke)&&(angular.isDefined(h.stroke.color)&&h.$watch("stroke.color",function(){return l.setOptions(b(l.getBounds()))}),angular.isDefined(h.stroke.weight)&&h.$watch("stroke.weight",function(){return l.setOptions(b(l.getBounds()))}),angular.isDefined(h.stroke.opacity)&&h.$watch("stroke.opacity",function(){return l.setOptions(b(l.getBounds()))})),angular.isDefined(h.fill)&&(angular.isDefined(h.fill.color)&&h.$watch("fill.color",function(){return l.setOptions(b(l.getBounds()))}),angular.isDefined(h.fill.opacity)&&h.$watch("fill.opacity",function(){return l.setOptions(b(l.getBounds()))})),h.$on("$destroy",function(){return l.setMap(null)})})}}}])}.call(this),function(){angular.module("google-maps").directive("window",["$timeout","$compile","$http","$templateCache","Window",function(a,b,c,d,e){return new e(a,b,c,d)}])}.call(this),function(){angular.module("google-maps").directive("windows",["$timeout","$compile","$http","$templateCache","$interpolate","Windows",function(a,b,c,d,e,f){return new f(a,b,c,d,e)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}};angular.module("google-maps").directive("layer",["$timeout","Logger","LayerParentModel",function(b,c,d){var e;return new(e=function(){function b(b){this.$timeout=b,this.link=a(this.link,this),this.$log=c,this.restrict="ECMA",this.require="^googleMap",this.priority=-1,this.transclude=!0,this.template='',this.replace=!0,this.scope={show:"=show",type:"=type",namespace:"=namespace",options:"=options",onCreated:"&oncreated"}}return b.prototype.link=function(a,b,c,e){return null!=c.oncreated?new d(a,b,c,e,this.$timeout,a.onCreated):new d(a,b,c,e,this.$timeout)},b}())(b)}])}.call(this),InfoBox.prototype=new google.maps.OverlayView,InfoBox.prototype.createInfoBoxDiv_=function(){var a,b,c,d=this,e=function(a){a.cancelBubble=!0,a.stopPropagation&&a.stopPropagation()},f=function(a){a.returnValue=!1,a.preventDefault&&a.preventDefault(),d.enableEventPropagation_||e(a)};if(!this.div_){if(this.div_=document.createElement("div"),this.setBoxStyle_(),"undefined"==typeof this.content_.nodeType?this.div_.innerHTML=this.getCloseBoxImg_()+this.content_:(this.div_.innerHTML=this.getCloseBoxImg_(),this.div_.appendChild(this.content_)),this.getPanes()[this.pane_].appendChild(this.div_),this.addClickHandler_(),this.div_.style.width?this.fixedWidthSet_=!0:0!==this.maxWidth_&&this.div_.offsetWidth>this.maxWidth_?(this.div_.style.width=this.maxWidth_,this.div_.style.overflow="auto",this.fixedWidthSet_=!0):(c=this.getBoxWidths_(),this.div_.style.width=this.div_.offsetWidth-c.left-c.right+"px",this.fixedWidthSet_=!1),this.panBox_(this.disableAutoPan_),!this.enableEventPropagation_){for(this.eventListeners_=[],b=["mousedown","mouseover","mouseout","mouseup","click","dblclick","touchstart","touchend","touchmove"],a=0;ag&&(d=o.x+k+i+m-g),this.alignBottom_?o.y<-j+n+l?e=o.y+j-n-l:o.y+j+n>h&&(e=o.y+j+n-h):o.y<-j+n?e=o.y+j-n:o.y+l+j+n>h&&(e=o.y+l+j+n-h),0!==d||0!==e){{b.getCenter()}b.panBy(d,e)}}},InfoBox.prototype.setBoxStyle_=function(){var a,b;if(this.div_){this.div_.className=this.boxClass_,this.div_.style.cssText="",b=this.boxStyle_;for(a in b)b.hasOwnProperty(a)&&(this.div_.style[a]=b[a]);"undefined"!=typeof this.div_.style.opacity&&""!==this.div_.style.opacity&&(this.div_.style.filter="alpha(opacity="+100*this.div_.style.opacity+")"),this.div_.style.position="absolute",this.div_.style.visibility="hidden",null!==this.zIndex_&&(this.div_.style.zIndex=this.zIndex_)}},InfoBox.prototype.getBoxWidths_=function(){var a,b={top:0,bottom:0,left:0,right:0},c=this.div_;return document.defaultView&&document.defaultView.getComputedStyle?(a=c.ownerDocument.defaultView.getComputedStyle(c,""),a&&(b.top=parseInt(a.borderTopWidth,10)||0,b.bottom=parseInt(a.borderBottomWidth,10)||0,b.left=parseInt(a.borderLeftWidth,10)||0,b.right=parseInt(a.borderRightWidth,10)||0)):document.documentElement.currentStyle&&c.currentStyle&&(b.top=parseInt(c.currentStyle.borderTopWidth,10)||0,b.bottom=parseInt(c.currentStyle.borderBottomWidth,10)||0,b.left=parseInt(c.currentStyle.borderLeftWidth,10)||0,b.right=parseInt(c.currentStyle.borderRightWidth,10)||0),b},InfoBox.prototype.onRemove=function(){this.div_&&(this.div_.parentNode.removeChild(this.div_),this.div_=null)},InfoBox.prototype.draw=function(){this.createInfoBoxDiv_();var a=this.getProjection().fromLatLngToDivPixel(this.position_);this.div_.style.left=a.x+this.pixelOffset_.width+"px",this.alignBottom_?this.div_.style.bottom=-(a.y+this.pixelOffset_.height)+"px":this.div_.style.top=a.y+this.pixelOffset_.height+"px",this.div_.style.visibility=this.isHidden_?"hidden":"visible"},InfoBox.prototype.setOptions=function(a){"undefined"!=typeof a.boxClass&&(this.boxClass_=a.boxClass,this.setBoxStyle_()),"undefined"!=typeof a.boxStyle&&(this.boxStyle_=a.boxStyle,this.setBoxStyle_()),"undefined"!=typeof a.content&&this.setContent(a.content),"undefined"!=typeof a.disableAutoPan&&(this.disableAutoPan_=a.disableAutoPan),"undefined"!=typeof a.maxWidth&&(this.maxWidth_=a.maxWidth),"undefined"!=typeof a.pixelOffset&&(this.pixelOffset_=a.pixelOffset),"undefined"!=typeof a.alignBottom&&(this.alignBottom_=a.alignBottom),"undefined"!=typeof a.position&&this.setPosition(a.position),"undefined"!=typeof a.zIndex&&this.setZIndex(a.zIndex),"undefined"!=typeof a.closeBoxMargin&&(this.closeBoxMargin_=a.closeBoxMargin),"undefined"!=typeof a.closeBoxURL&&(this.closeBoxURL_=a.closeBoxURL),"undefined"!=typeof a.infoBoxClearance&&(this.infoBoxClearance_=a.infoBoxClearance),"undefined"!=typeof a.isHidden&&(this.isHidden_=a.isHidden),"undefined"!=typeof a.visible&&(this.isHidden_=!a.visible),"undefined"!=typeof a.enableEventPropagation&&(this.enableEventPropagation_=a.enableEventPropagation),this.div_&&this.draw()},InfoBox.prototype.setContent=function(a){this.content_=a,this.div_&&(this.closeListener_&&(google.maps.event.removeListener(this.closeListener_),this.closeListener_=null),this.fixedWidthSet_||(this.div_.style.width=""),"undefined"==typeof a.nodeType?this.div_.innerHTML=this.getCloseBoxImg_()+a:(this.div_.innerHTML=this.getCloseBoxImg_(),this.div_.appendChild(a)),this.fixedWidthSet_||(this.div_.style.width=this.div_.offsetWidth+"px","undefined"==typeof a.nodeType?this.div_.innerHTML=this.getCloseBoxImg_()+a:(this.div_.innerHTML=this.getCloseBoxImg_(),this.div_.appendChild(a))),this.addClickHandler_()),google.maps.event.trigger(this,"content_changed")},InfoBox.prototype.setPosition=function(a){this.position_=a,this.div_&&this.draw(),google.maps.event.trigger(this,"position_changed")},InfoBox.prototype.setZIndex=function(a){this.zIndex_=a,this.div_&&(this.div_.style.zIndex=a),google.maps.event.trigger(this,"zindex_changed")},InfoBox.prototype.setVisible=function(a){this.isHidden_=!a,this.div_&&(this.div_.style.visibility=this.isHidden_?"hidden":"visible")},InfoBox.prototype.getContent=function(){return this.content_},InfoBox.prototype.getPosition=function(){return this.position_},InfoBox.prototype.getZIndex=function(){return this.zIndex_},InfoBox.prototype.getVisible=function(){var a;return a="undefined"==typeof this.getMap()||null===this.getMap()?!1:!this.isHidden_},InfoBox.prototype.show=function(){this.isHidden_=!1,this.div_&&(this.div_.style.visibility="visible")},InfoBox.prototype.hide=function(){this.isHidden_=!0,this.div_&&(this.div_.style.visibility="hidden")},InfoBox.prototype.open=function(a,b){var c=this;b&&(this.position_=b.getPosition(),this.moveListener_=google.maps.event.addListener(b,"position_changed",function(){c.setPosition(this.getPosition())})),this.setMap(a),this.div_&&this.panBox_()},InfoBox.prototype.close=function(){var a;if(this.closeListener_&&(google.maps.event.removeListener(this.closeListener_),this.closeListener_=null),this.eventListeners_){for(a=0;af&&g.getMap().setZoom(f+1)},100)),d.cancelBubble=!0,d.stopPropagation&&d.stopPropagation()}}),google.maps.event.addDomListener(this.div_,"mouseover",function(){var a=c.cluster_.getMarkerClusterer();google.maps.event.trigger(a,"mouseover",c.cluster_)}),google.maps.event.addDomListener(this.div_,"mouseout",function(){var a=c.cluster_.getMarkerClusterer();google.maps.event.trigger(a,"mouseout",c.cluster_)})},ClusterIcon.prototype.onRemove=function(){this.div_&&this.div_.parentNode&&(this.hide(),google.maps.event.removeListener(this.boundsChangedListener_),google.maps.event.clearInstanceListeners(this.div_),this.div_.parentNode.removeChild(this.div_),this.div_=null)},ClusterIcon.prototype.draw=function(){if(this.visible_){var a=this.getPosFromLatLng_(this.center_);this.div_.style.top=a.y+"px",this.div_.style.left=a.x+"px"}},ClusterIcon.prototype.hide=function(){this.div_&&(this.div_.style.display="none"),this.visible_=!1},ClusterIcon.prototype.show=function(){if(this.div_){var a="",b=this.backgroundPosition_.split(" "),c=parseInt(b[0].trim(),10),d=parseInt(b[1].trim(),10),e=this.getPosFromLatLng_(this.center_);this.div_.style.cssText=this.createCss(e),a="",this.div_.innerHTML=a+"
"+this.sums_.text+"
",this.div_.title="undefined"==typeof this.sums_.title||""===this.sums_.title?this.cluster_.getMarkerClusterer().getTitle():this.sums_.title,this.div_.style.display="" -}this.visible_=!0},ClusterIcon.prototype.useStyle=function(a){this.sums_=a;var b=Math.max(0,a.index-1);b=Math.min(this.styles_.length-1,b);var c=this.styles_[b];this.url_=c.url,this.height_=c.height,this.width_=c.width,this.anchorText_=c.anchorText||[0,0],this.anchorIcon_=c.anchorIcon||[parseInt(this.height_/2,10),parseInt(this.width_/2,10)],this.textColor_=c.textColor||"black",this.textSize_=c.textSize||11,this.textDecoration_=c.textDecoration||"none",this.fontWeight_=c.fontWeight||"bold",this.fontStyle_=c.fontStyle||"normal",this.fontFamily_=c.fontFamily||"Arial,sans-serif",this.backgroundPosition_=c.backgroundPosition||"0 0"},ClusterIcon.prototype.setCenter=function(a){this.center_=a},ClusterIcon.prototype.createCss=function(a){var b=[];return b.push("cursor: pointer;"),b.push("position: absolute; top: "+a.y+"px; left: "+a.x+"px;"),b.push("width: "+this.width_+"px; height: "+this.height_+"px;"),b.join("")},ClusterIcon.prototype.getPosFromLatLng_=function(a){var b=this.getProjection().fromLatLngToDivPixel(a);return b.x-=this.anchorIcon_[1],b.y-=this.anchorIcon_[0],b.x=parseInt(b.x,10),b.y=parseInt(b.y,10),b},Cluster.prototype.getSize=function(){return this.markers_.length},Cluster.prototype.getMarkers=function(){return this.markers_},Cluster.prototype.getCenter=function(){return this.center_},Cluster.prototype.getMap=function(){return this.map_},Cluster.prototype.getMarkerClusterer=function(){return this.markerClusterer_},Cluster.prototype.getBounds=function(){var a,b=new google.maps.LatLngBounds(this.center_,this.center_),c=this.getMarkers();for(a=0;ad)a.getMap()!==this.map_&&a.setMap(this.map_);else if(cb;b++)this.markers_[b].setMap(null);else a.setMap(null);return this.updateIcon_(),!0},Cluster.prototype.isMarkerInClusterBounds=function(a){return this.bounds_.contains(a.getPosition())},Cluster.prototype.calculateBounds_=function(){var a=new google.maps.LatLngBounds(this.center_,this.center_);this.bounds_=this.markerClusterer_.getExtendedBounds(a)},Cluster.prototype.updateIcon_=function(){var a=this.markers_.length,b=this.markerClusterer_.getMaxZoom();if(null!==b&&this.map_.getZoom()>b)return void this.clusterIcon_.hide();if(a0))for(a=0;ac&&(f=c,g=d));g&&g.isMarkerInClusterBounds(a)?g.addMarker(a):(d=new Cluster(this),d.addMarker(a),this.clusters_.push(d))},MarkerClusterer.prototype.createClusters_=function(a){var b,c,d,e=this;if(this.ready_){0===a&&(google.maps.event.trigger(this,"clusteringbegin",this),"undefined"!=typeof this.timerRefStatic&&(clearTimeout(this.timerRefStatic),delete this.timerRefStatic)),d=this.getMap().getZoom()>3?new google.maps.LatLngBounds(this.getMap().getBounds().getSouthWest(),this.getMap().getBounds().getNorthEast()):new google.maps.LatLngBounds(new google.maps.LatLng(85.02070771743472,-178.48388434375),new google.maps.LatLng(-85.08136444384544,178.00048865625));var f=this.getExtendedBounds(d),g=Math.min(a+this.batchSize_,this.markers_.length);for(b=a;g>b;b++)c=this.markers_[b],!c.isAdded&&this.isMarkerInBounds_(c,f)&&(!this.ignoreHidden_||this.ignoreHidden_&&c.getVisible())&&this.addToClosestCluster_(c);gd?Math.max(0,f+d):d}for(;f>e;){if(null!=c){if(c(a[e],b))return e}else if(_.isEqual(a[e],b))return e;e++}return-1},_["extends"]=function(a){return _.reduce(a,function(a,b){return _.extend(a,b)},{})},_.isNullOrUndefined=function(a){return _.isNull(a||_.isUndefined(a))}}.call(this),function(){angular.module("google-maps.providers".ns(),[]),angular.module("google-maps.wrapped".ns(),[]),angular.module("google-maps.extensions".ns(),["google-maps.wrapped".ns(),"google-maps.providers".ns()]),angular.module("google-maps.directives.api.utils".ns(),["google-maps.extensions".ns()]),angular.module("google-maps.directives.api.managers".ns(),[]),angular.module("google-maps.directives.api.options".ns(),["google-maps.directives.api.utils".ns()]),angular.module("google-maps.directives.api.options.builders".ns(),[]),angular.module("google-maps.directives.api.models.child".ns(),["google-maps.directives.api.utils".ns(),"google-maps.directives.api.options".ns(),"google-maps.directives.api.options.builders".ns()]),angular.module("google-maps.directives.api.models.parent".ns(),["google-maps.directives.api.managers".ns(),"google-maps.directives.api.models.child".ns(),"google-maps.providers".ns()]),angular.module("google-maps.directives.api".ns(),["google-maps.directives.api.models.parent".ns()]),angular.module("google-maps".ns(),["google-maps.directives.api".ns(),"google-maps.providers".ns()]).factory("debounce".ns(),["$timeout",function(a){return function(b){var c;return c=0,function(){var d,e,f;return f=this,d=arguments,c++,e=function(a){return function(){return a===c?b.apply(f,d):void 0}}(c),a(e,0,!0)}}}])}.call(this),function(){angular.module("google-maps.providers".ns()).factory("MapScriptLoader".ns(),["$q",function(a){return{load:function(b){var c,d,e,f;return c=a.defer(),angular.isDefined(window.google)&&angular.isDefined(window.google.maps)?(c.resolve(window.google.maps),c.promise):(e=b.callback="onGoogleMapsReady"+Math.round(1e3*Math.random()),window[e]=function(){window[e]=null,c.resolve(window.google.maps)},d=_.map(b,function(a,b){return b+"="+a}),d=d.join("&"),f=document.createElement("script"),f.type="text/javascript",f.src="https://maps.googleapis.com/maps/api/js?"+d,document.body.appendChild(f),c.promise)}}}]).provider("GoogleMapApi".ns(),function(){return this.options={v:"3.16",libraries:"places",language:"en",sensor:"false"},this.configure=function(a){angular.extend(this.options,a)},this.$get=["MapScriptLoader".ns(),function(a){return function(b){return a.promise=b.load(a.options),a.promise}}(this)],this})}.call(this),function(){angular.module("google-maps.extensions".ns()).service("ExtendGWin".ns(),function(){return{init:_.once(function(){return google||("undefined"!=typeof google&&null!==google?google.maps:void 0)||null!=google.maps.InfoWindow?(google.maps.InfoWindow.prototype._open=google.maps.InfoWindow.prototype.open,google.maps.InfoWindow.prototype._close=google.maps.InfoWindow.prototype.close,google.maps.InfoWindow.prototype._isOpen=!1,google.maps.InfoWindow.prototype.open=function(a,b,c){null==c&&(this._isOpen=!0,this._open(a,b,!0))},google.maps.InfoWindow.prototype.close=function(a){null==a&&(this._isOpen=!1,this._close(!0))},google.maps.InfoWindow.prototype.isOpen=function(a){return null==a&&(a=void 0),null==a?this._isOpen:this._isOpen=a},window.InfoBox&&(window.InfoBox.prototype._open=window.InfoBox.prototype.open,window.InfoBox.prototype._close=window.InfoBox.prototype.close,window.InfoBox.prototype._isOpen=!1,window.InfoBox.prototype.open=function(a,b){this._isOpen=!0,this._open(a,b)},window.InfoBox.prototype.close=function(){this._isOpen=!1,this._close()},window.InfoBox.prototype.isOpen=function(a){return null==a&&(a=void 0),null==a?this._isOpen:this._isOpen=a}),window.MarkerLabel_?(window.MarkerLabel_.prototype.setContent=function(){var a;a=this.marker_.get("labelContent"),a&&!_.isEqual(this.oldContent,a)&&("undefined"==typeof(null!=a?a.nodeType:void 0)?(this.labelDiv_.innerHTML=a,this.eventDiv_.innerHTML=this.labelDiv_.innerHTML,this.oldContent=a):(this.labelDiv_.innerHTML="",this.labelDiv_.appendChild(a),a=a.cloneNode(!0),this.eventDiv_.appendChild(a),this.oldContent=a))},window.MarkerLabel_.prototype.onRemove=function(){null!=this.labelDiv_.parentNode&&this.labelDiv_.parentNode.removeChild(this.labelDiv_),null!=this.eventDiv_.parentNode&&this.eventDiv_.parentNode.removeChild(this.eventDiv_),this.listeners_&&this.listeners_.length&&this.listeners_.forEach(function(a){return google.maps.event.removeListener(a)})}):void 0):void 0})}})}.call(this),function(){angular.module("google-maps.directives.api.utils".ns()).service("_sync".ns(),[function(){return{fakePromise:function(){var a;return a=void 0,{then:function(b){return a=b},resolve:function(){return a.apply(void 0,arguments)}}}}}]).factory("_async".ns(),[function(){var a,b,c,d,e;return a=20,e=function(a,b){return a.existingPieces=a.existingPieces?a.existingPieces.then(function(){return b()}):b()},b=function(a,c,d,e,f,g,h){var i,j,k;try{for(i=c&&c0?c(a,function(a){return h.push(b(a))},d,e,f,g).then(function(){return h}):Promise.resolve(h)},{each:c,map:d,waitOrGo:e,defaultChunkSize:a}}])}.call(this),function(){var a=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1};angular.module("google-maps.directives.api.utils".ns()).factory("BaseObject".ns(),function(){var b,c;return c=["extended","included"],b=function(){function b(){}return b.extend=function(b){var d,e,f;for(d in b)e=b[d],a.call(c,d)<0&&(this[d]=e);return null!=(f=b.extended)&&f.apply(this),this},b.include=function(b){var d,e,f;for(d in b)e=b[d],a.call(c,d)<0&&(this.prototype[d]=e);return null!=(f=b.included)&&f.apply(this),this},b}()})}.call(this),function(){angular.module("google-maps.directives.api.utils".ns()).factory("ChildEvents".ns(),function(){return{onChildCreation:function(){}}})}.call(this),function(){angular.module("google-maps.directives.api.utils".ns()).service("CtrlHandle".ns(),["$q",function(a){var b;return b={handle:function(b){return b.deferred=a.defer(),{getScope:function(){return b}}},mapPromise:function(a,b){var c;return c=b.getScope(),c.deferred.promise.then(function(b){return a.map=b}),c.deferred.promise}}}])}.call(this),function(){angular.module("google-maps.directives.api.utils".ns()).service("EventsHelper".ns(),["Logger".ns(),function(a){return{setEvents:function(b,c,d,e){return angular.isDefined(c.events)&&null!=c.events&&angular.isObject(c.events)?_.compact(_.map(c.events,function(f,g){var h;return e&&(h=_(e).contains(g)),c.events.hasOwnProperty(g)&&angular.isFunction(c.events[g])&&!h?google.maps.event.addListener(b,g,function(){return c.$apply(f.apply(c,[b,g,d,arguments]))}):a.info("EventHelper: invalid event listener "+g)})):void 0},removeEvents:function(a){return null!=a?a.forEach(function(a){return google.maps.event.removeListener(a)}):void 0}}}])}.call(this),function(){var a={}.hasOwnProperty,b=function(b,c){function d(){this.constructor=b}for(var e in c)a.call(c,e)&&(b[e]=c[e]);return d.prototype=c.prototype,b.prototype=new d,b.__super__=c.prototype,b};angular.module("google-maps.directives.api.utils".ns()).factory("FitHelper".ns(),["BaseObject".ns(),"Logger".ns(),"_async".ns(),function(a,c,d){var e;return e=function(a){function c(){return c.__super__.constructor.apply(this,arguments)}return b(c,a),c.prototype.fit=function(a,b){var c,e;return b&&a&&a.length>0?(c=new google.maps.LatLngBounds,e=!1,d.each(a,function(){return function(a){return a?(e||(e=!0),c.extend(a.getPosition())):void 0}}(this)).then(function(){return e?b.fitBounds(c):void 0})):void 0},c}(a)}])}.call(this),function(){angular.module("google-maps.directives.api.utils".ns()).service("GmapUtil".ns(),["Logger".ns(),"$compile",function(a,b){var c,d,e,f;return d=function(a){return Array.isArray(a)&&2===a.length?a[1]:angular.isDefined(a.type)&&"Point"===a.type?a.coordinates[1]:a.latitude},e=function(a){return Array.isArray(a)&&2===a.length?a[0]:angular.isDefined(a.type)&&"Point"===a.type?a.coordinates[0]:a.longitude},c=function(a){return a?Array.isArray(a)&&2===a.length?new google.maps.LatLng(a[1],a[0]):angular.isDefined(a.type)&&"Point"===a.type?new google.maps.LatLng(a.coordinates[1],a.coordinates[0]):new google.maps.LatLng(a.latitude,a.longitude):void 0},f=function(a){if(angular.isUndefined(a))return!1;if(_.isArray(a)){if(2===a.length)return!0}else if(null!=a&&(null!=a?a.type:void 0)&&"Point"===a.type&&_.isArray(a.coordinates)&&2===a.coordinates.length)return!0;return a&&angular.isDefined((null!=a?a.latitude:void 0)&&angular.isDefined(null!=a?a.longitude:void 0))?!0:!1},{setCoordsFromEvent:function(a,b){return a?(Array.isArray(a)&&2===a.length?(a[1]=b.lat(),a[0]=b.lng()):angular.isDefined(a.type)&&"Point"===a.type?(a.coordinates[1]=b.lat(),a.coordinates[0]=b.lng()):(a.latitude=b.lat(),a.longitude=b.lng()),a):void 0},getLabelPositionPoint:function(a){var b,c;return void 0===a?void 0:(a=/^([-\d\.]+)\s([-\d\.]+)$/.exec(a),b=parseFloat(a[1]),c=parseFloat(a[2]),null!=b&&null!=c?new google.maps.Point(b,c):void 0)},createWindowOptions:function(d,e,f,g){var h;return null!=f&&null!=g&&null!=b?(h=angular.extend({},g,{content:this.buildContent(e,g,f),position:null!=g.position?g.position:angular.isObject(d)?d.getPosition():c(e.coords)}),null!=d&&null==(null!=h?h.pixelOffset:void 0)&&(h.pixelOffset=null==h.boxClass?{height:-40,width:0}:{height:0,width:-2}),h):g?g:(a.error("infoWindow defaults not defined"),f?void 0:a.error("infoWindow content not defined"))},buildContent:function(a,c,d){var e,f;return null!=c.content?f=c.content:null!=b?(e=b(d)(a),e.length>0&&(f=e[0])):f=d,f},defaultDelay:50,isTrue:function(a){return angular.isDefined(a)&&null!==a&&a===!0||"1"===a||"y"===a||"true"===a},isFalse:function(a){return-1!==["false","FALSE",0,"n","N","no","NO"].indexOf(a)},getCoords:c,validateCoords:f,equalCoords:function(a,b){return d(a)===d(b)&&e(a)===e(b)},validatePath:function(a){var b,c,d,e;if(c=0,angular.isUndefined(a.type)){if(!Array.isArray(a)||a.length<2)return!1;for(;cthis.max?(this.max=a[0].length,this.index=b):void 0},e),d=a.coordinates[e.index],b=d[0],b.length<4)return!1}else{if("LineString"!==a.type)return!1;if(a.coordinates.length<2)return!1;b=a.coordinates}for(;cthis.max?(this.max=a[0].length,this.index=b):void 0},f),b=a.coordinates[f.index][0]):"LineString"===a.type&&(b=a.coordinates);cd;)l=j.getAt(d),h=a[d],"function"==typeof h.equals?h.equals(l)||(j.setAt(d,h),c=!0):(l.lat()!==h.latitude||l.lng()!==h.longitude)&&(j.setAt(d,new google.maps.LatLng(h.latitude,h.longitude)),c=!0),d++;for(;g>d;)h=a[d],j.push("function"==typeof h.lat&&"function"==typeof h.lng?h:new google.maps.LatLng(h.latitude,h.longitude)),c=!0,d++;for(;k>d;)j.pop(),c=!0,d++}return i=!1,c?e(j):void 0},h=function(a){var c,d,f,g,h,j,k,l,n;if(i=!0,k=b,d=!1,a){for("Polygon"===m.type?c=a.coordinates[0]:"LineString"===m.type&&(c=a.coordinates),f=0,l=k.getLength(),h=c.length,g=Math.min(l,h),j=void 0;g>f;)n=k.getAt(f),j=c[f],(n.lat()!==j[1]||n.lng()!==j[0])&&(k.setAt(f,new google.maps.LatLng(j[1],j[0])),d=!0),f++;for(;h>f;)j=c[f],k.push(new google.maps.LatLng(j[1],j[0])),d=!0,f++;for(;l>f;)k.pop(),d=!0,f++}return i=!1,d?e(k):void 0},c["static"]||(n=angular.isUndefined(m.type)?c.$watchCollection(d,k):c.$watch(d,h,!0)),function(){return l&&(l(),l=null),n?(n(),n=null):void 0}}}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.options.builders".ns()).service("CommonOptionsBuilder".ns(),["BaseObject".ns(),"Logger".ns(),function(b,d){var e;return e=function(b){function e(){return this.watchProps=a(this.watchProps,this),this.buildOpts=a(this.buildOpts,this),e.__super__.constructor.apply(this,arguments)}return c(e,b),e.prototype.props=["clickable","draggable","editable","visible",{prop:"stroke",isColl:!0}],e.prototype.buildOpts=function(a,b){var c,e,f,g,h,i;return null==a&&(a={}),null==b&&(b={}),this.scope?this.map?(c=_(this.scope).chain().keys().contains("model").value(),e=c?this.scope.model:this.scope,f=angular.extend(a,this.DEFAULTS,{map:this.map,strokeColor:null!=(g=e.stroke)?g.color:void 0,strokeOpacity:null!=(h=e.stroke)?h.opacity:void 0,strokeWeight:null!=(i=e.stroke)?i.weight:void 0}),angular.forEach(angular.extend(b,{clickable:!0,draggable:!1,editable:!1,"static":!1,fit:!1,visible:!0,zIndex:0}),function(){return function(a,b){return f[b]=angular.isUndefined(e[b]||null===e[b])?a:e[b]}}(this)),f["static"]&&(f.editable=!1),f):void d.error("this.map not defined in CommonOptionsBuilder can not buildOpts"):void d.error("this.scope not defined in CommonOptionsBuilder can not buildOpts")},e.prototype.watchProps=function(a){return null==a&&(a=this.props),a.forEach(function(a){return function(b){return null!=a.attrs[b]||null!=a.attrs[null!=b?b.prop:void 0]?(null!=b?b.isColl:void 0)?a.scope.$watchCollection(b.prop,a.setMyOptions):a.scope.$watch(b,a.setMyOptions):void 0}}(this))},e}(b)}])}.call(this),function(){var a={}.hasOwnProperty,b=function(b,c){function d(){this.constructor=b}for(var e in c)a.call(c,e)&&(b[e]=c[e]);return d.prototype=c.prototype,b.prototype=new d,b.__super__=c.prototype,b};angular.module("google-maps.directives.api.options.builders".ns()).factory("PolylineOptionsBuilder".ns(),["CommonOptionsBuilder".ns(),function(a){var c;return c=function(a){function c(){return c.__super__.constructor.apply(this,arguments)}return b(c,a),c.prototype.buildOpts=function(a){return c.__super__.buildOpts.call(this,{path:a},{geodesic:!1})},c}(a)}]).factory("ShapeOptionsBuilder".ns(),["CommonOptionsBuilder".ns(),function(a){var c;return c=function(a){function c(){return c.__super__.constructor.apply(this,arguments)}return b(c,a),c.prototype.buildOpts=function(a,b){var d,e;return a=angular.extend(a,{fillColor:null!=(d=this.scope.fill)?d.color:void 0,fillOpacity:null!=(e=this.scope.fill)?e.opacity:void 0}),c.__super__.buildOpts.call(this,a,b)},c}(a)}]).factory("PolygonOptionsBuilder".ns(),["ShapeOptionsBuilder".ns(),function(a){var c;return c=function(a){function c(){return c.__super__.constructor.apply(this,arguments)}return b(c,a),c.prototype.buildOpts=function(a){return c.__super__.buildOpts.call(this,{path:a},{geodesic:!1})},c}(a)}]).factory("RectangleOptionsBuilder".ns(),["ShapeOptionsBuilder".ns(),function(a){var c;return c=function(a){function c(){return c.__super__.constructor.apply(this,arguments)}return b(c,a),c.prototype.buildOpts=function(a){return c.__super__.buildOpts.call(this,{bounds:a})},c}(a)}]).factory("CircleOptionsBuilder".ns(),["ShapeOptionsBuilder".ns(),function(a){var c;return c=function(a){function c(){return c.__super__.constructor.apply(this,arguments)}return b(c,a),c.prototype.buildOpts=function(a,b){return c.__super__.buildOpts.call(this,{center:a,radius:b})},c}(a)}])}.call(this),function(){angular.module("google-maps.directives.api.options".ns()).service("MarkerOptions".ns(),["Logger".ns(),"GmapUtil".ns(),function(a,b){return _.extend(b,{createOptions:function(a,c,d,e){var f;return null==e&&(e=void 0),null==d&&(d={}),f=angular.extend({},d,{position:null!=d.position?d.position:b.getCoords(a),visible:null!=d.visible?d.visible:b.validateCoords(a)}),(null!=d.icon||null!=c)&&(f=angular.extend(f,{icon:null!=d.icon?d.icon:c})),null!=e&&(f.map=e),f},isLabel:function(a){return null!=a.labelContent||null!=a.labelAnchor||null!=a.labelClass||null!=a.labelStyle||null!=a.labelVisible?!0:!1}})}])}.call(this),function(){angular.module("google-maps.directives.api.models.child".ns()).factory("DrawFreeHandChildModel".ns(),["Logger".ns(),"$q",function(a,b){var c,d;return c=function(a,b,c){var d,e;return this.polys=b,e=new google.maps.Polyline({map:a,clickable:!1}),d=google.maps.event.addListener(a,"mousemove",function(a){return e.getPath().push(a.latLng)}),void google.maps.event.addListenerOnce(a,"mouseup",function(){var f;return google.maps.event.removeListener(d),f=e.getPath(),e.setMap(null),b.push(new google.maps.Polygon({map:a,path:f})),e=null,google.maps.event.clearListeners(a.getDiv(),"mousedown"),c() +})},d=function(d){var e,f;return this.map=d,f=function(a){return function(){var b;return null!=(b=a.deferred)&&b.resolve(),a.map.setOptions(a.oldOptions)}}(this),e=function(b){return function(){return a.info("disabling map move"),b.oldOptions=d.getOptions(),b.map.setOptions({draggable:!1,zoomControl:!1,scrollwheel:!1,disableDoubleClickZoom:!1})}}(this),this.engage=function(d){return function(g){return d.polys=g,d.deferred=b.defer(),e(),a.info("DrawFreeHandChildModel is engaged (drawing)."),google.maps.event.addDomListener(d.map.getDiv(),"mousedown",function(){return c(d.map,d.polys,f)}),d.deferred.promise}}(this),this}}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.child".ns()).factory("MarkerChildModel".ns(),["ModelKey".ns(),"GmapUtil".ns(),"Logger".ns(),"EventsHelper".ns(),"MarkerOptions".ns(),function(b,d,e,f,g){var h,i;return i=["coords","icon","options","fit"],h=function(b){function h(b,c,d,f,g,j,k,l,m){this.model=c,this.keys=d,this.gMap=f,this.defaults=g,this.doClick=j,this.gMarkerManager=k,this.doDrawSelf=null!=l?l:!0,this.trackModel=null!=m?m:!0,this.internalEvents=a(this.internalEvents,this),this.setLabelOptions=a(this.setLabelOptions,this),this.setOptions=a(this.setOptions,this),this.setIcon=a(this.setIcon,this),this.setCoords=a(this.setCoords,this),this.maybeSetScopeValue=a(this.maybeSetScopeValue,this),this.createMarker=a(this.createMarker,this),this.setMyScope=a(this.setMyScope,this),this.destroy=a(this.destroy,this),_.each(this.keys,function(a){return function(b,c){return a[c+"Key"]=_.isFunction(a.keys[c])?a.keys[c]():a.keys[c]}}(this)),this.idKey=this.idKeyKey||"id",null!=this.model[this.idKey]&&(this.id=this.model[this.idKey]),this.needRedraw=!1,this.deferred=Promise.defer(),h.__super__.constructor.call(this,b),this.setMyScope(this.model,void 0,!0),this.createMarker(this.model),this.trackModel?(this.scope.model=this.model,this.scope.$watch("model",function(a){return function(b,c){return b!==c?(a.setMyScope(b,c),a.needRedraw=!0):void 0}}(this),!0)):_.each(this.keys,function(a){return function(b,c){return a.scope.$watch(c,function(){return a.setMyScope(a.scope)})}}(this)),this.scope.$on("$destroy",function(a){return function(){return i(a)}}(this)),e.info(this)}var i;return c(h,b),h.include(d),h.include(f),h.include(g),i=function(a){return null!=(null!=a?a.gMarker:void 0)&&(a.removeEvents(a.externalListeners),a.removeEvents(a.internalListeners),null!=a?a.gMarker:void 0)?(null!=a&&a.gMarkerManager.remove(null!=a?a.gMarker:void 0,!0),delete a.gMarker):void 0},h.prototype.destroy=function(){return this.scope.$destroy()},h.prototype.setMyScope=function(a,b,c){return null==b&&(b=void 0),null==c&&(c=!1),this.maybeSetScopeValue("icon",a,b,this.iconKey,this.evalModelHandle,c,this.setIcon),this.maybeSetScopeValue("coords",a,b,this.coordsKey,this.evalModelHandle,c,this.setCoords),_.isFunction(this.clickKey)?this.scope.click=function(a){return function(){return a.clickKey(a.gMarker,"click",a.model,void 0)}}(this):(this.maybeSetScopeValue("click",a,b,this.clickKey,this.evalModelHandle,c),this.createMarker(a,b,c))},h.prototype.createMarker=function(a,b,c){return null==b&&(b=void 0),null==c&&(c=!1),this.maybeSetScopeValue("options",a,b,this.optionsKey,this.evalModelHandle,c,this.setOptions)},h.prototype.maybeSetScopeValue=function(a,b,c,d,e,f,g){var h,i;return null==g&&(g=void 0),void 0===c?(this.scope[a]=e(b,d),void(f||null!=g&&g(this.scope))):(i=e(c,d),h=e(b,d),h!==i&&(this.scope[a]=h,!f&&(null!=g&&g(this.scope),this.doDrawSelf))?this.gMarkerManager.draw():void 0)},h.prototype.setCoords=function(a){return a.$id===this.scope.$id&&void 0!==this.gMarker?null!=a.coords?this.validateCoords(this.scope.coords)?(this.gMarker.setPosition(this.getCoords(a.coords)),this.gMarker.setVisible(this.validateCoords(a.coords)),this.gMarkerManager.add(this.gMarker)):void e.debug("MarkerChild does not have coords yet. They may be defined later."):this.gMarkerManager.remove(this.gMarker):void 0},h.prototype.setIcon=function(a){return a.$id===this.scope.$id&&void 0!==this.gMarker?(this.gMarkerManager.remove(this.gMarker),this.gMarker.setIcon(a.icon),this.gMarkerManager.add(this.gMarker),this.gMarker.setPosition(this.getCoords(a.coords)),this.gMarker.setVisible(this.validateCoords(a.coords))):void 0},h.prototype.setOptions=function(a){var b;if(a.$id===this.scope.$id&&(null!=this.gMarker&&(this.gMarkerManager.remove(this.gMarker),delete this.gMarker),null!=(b=a.coords)?b:"function"==typeof a.icon?a.icon(null!=a.options):void 0))return this.opts=this.createOptions(a.coords,a.icon,a.options),delete this.gMarker,this.gMarker=this.isLabel(this.opts)?new MarkerWithLabel(this.setLabelOptions(this.opts)):new google.maps.Marker(this.opts),this.gMarker?this.deferred.resolve(this.gMarker):this.deferred.reject("gMarker is null"),this.model.fitKey&&this.gMarkerManager.fit(),this.externalListeners&&this.removeEvents(this.externalListeners),this.internalListeners&&this.removeEvents(this.internalListeners),this.externalListeners=this.setEvents(this.gMarker,this.scope,this.model,["dragend"]),this.internalListeners=this.setEvents(this.gMarker,{events:this.internalEvents(),$apply:function(){}},this.model),null!=this.id&&(this.gMarker.key=this.id),this.gMarkerManager.add(this.gMarker)},h.prototype.setLabelOptions=function(a){return a.labelAnchor=this.getLabelPositionPoint(a.labelAnchor),a},h.prototype.internalEvents=function(){return{dragend:function(a){return function(b,c,d,e){var f,g;return f=a.setCoordsFromEvent(a.modelOrKey(a.scope.model,a.coordsKey),a.gMarker.getPosition()),a.scope.model=a.setVal(d,a.coordsKey,f),null!=(null!=(g=a.scope.events)?g.dragend:void 0)&&a.scope.events.dragend(b,c,a.scope.model,e),a.scope.$apply()}}(this),click:function(a){return function(b,c,d,e){return a.doClick&&null!=a.scope.click?a.scope.$apply(a.scope.click(b,c,a.model,e)):void 0}}(this)}},h}(b)}])}.call(this),function(){var a={}.hasOwnProperty,b=function(b,c){function d(){this.constructor=b}for(var e in c)a.call(c,e)&&(b[e]=c[e]);return d.prototype=c.prototype,b.prototype=new d,b.__super__=c.prototype,b};angular.module("google-maps.directives.api".ns()).factory("PolygonChildModel".ns(),["PolygonOptionsBuilder".ns(),"Logger".ns(),"$timeout","array-sync".ns(),"GmapUtil".ns(),"EventsHelper".ns(),function(a,c,d,e,f,g){var h;return h=function(a){function d(a,b,d,f,h){var i,j,k;return this.scope=a,this.attrs=b,this.map=d,this.defaults=f,this.model=h,this.listeners=void 0,angular.isUndefined(a.path)||null===a.path||!this.validatePath(a.path)?void c.error("polygon: no valid path attribute found"):(j=this.convertPathPoints(a.path),k=new google.maps.Polygon(this.buildOpts(j)),a.fit&&this.extendMapBounds(this.map,j),!a["static"]&&angular.isDefined(a.editable)&&a.$watch("editable",function(a,b){return a!==b?k.setEditable(a):void 0}),angular.isDefined(a.draggable)&&a.$watch("draggable",function(a,b){return a!==b?k.setDraggable(a):void 0}),angular.isDefined(a.visible)&&a.$watch("visible",function(a,b){return a!==b?k.setVisible(a):void 0}),angular.isDefined(a.geodesic)&&a.$watch("geodesic",function(a){return function(b,c){return b!==c?k.setOptions(a.buildOpts(k.getPath())):void 0}}(this)),angular.isDefined(a.stroke)&&angular.isDefined(a.stroke.opacity)&&a.$watch("stroke.opacity",function(a){return function(){return k.setOptions(a.buildOpts(k.getPath()))}}(this)),angular.isDefined(a.stroke)&&angular.isDefined(a.stroke.weight)&&a.$watch("stroke.weight",function(a){return function(b,c){return b!==c?k.setOptions(a.buildOpts(k.getPath())):void 0}}(this)),angular.isDefined(a.stroke)&&angular.isDefined(a.stroke.color)&&a.$watch("stroke.color",function(a){return function(b,c){return b!==c?k.setOptions(a.buildOpts(k.getPath())):void 0}}(this)),angular.isDefined(a.fill)&&angular.isDefined(a.fill.color)&&a.$watch("fill.color",function(a){return function(b,c){return b!==c?k.setOptions(a.buildOpts(k.getPath())):void 0}}(this)),angular.isDefined(a.fill)&&angular.isDefined(a.fill.opacity)&&a.$watch("fill.opacity",function(a){return function(b,c){return b!==c?k.setOptions(a.buildOpts(k.getPath())):void 0}}(this)),angular.isDefined(a.zIndex)&&a.$watch("zIndex",function(a){return function(b,c){return b!==c?k.setOptions(a.buildOpts(k.getPath())):void 0}}(this)),angular.isDefined(a.events)&&null!==a.events&&angular.isObject(a.events)&&(this.listeners=g.setEvents(k,a,a)),i=e(k.getPath(),a,"path",function(b){return function(c){return a.fit?b.extendMapBounds(b.map,c):void 0}}(this)),void a.$on("$destroy",function(a){return function(){return k.setMap(null),a.removeEvents(a.listeners),i?(i(),i=null):void 0}}(this)))}return b(d,a),d.include(f),d.include(g),d}(a)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("PolylineChildModel".ns(),["PolylineOptionsBuilder".ns(),"Logger".ns(),"$timeout","array-sync".ns(),"GmapUtil".ns(),"EventsHelper".ns(),function(b,d,e,f,g,h){var i;return i=function(b){function e(b,c,e,g,h){var i;this.scope=b,this.attrs=c,this.map=e,this.defaults=g,this.model=h,this.clean=a(this.clean,this),i=function(a){return function(){var b;return b=a.convertPathPoints(a.scope.path),null!=a.polyline&&a.clean(),b.length>0&&(a.polyline=new google.maps.Polyline(a.buildOpts(b))),a.polyline?(a.scope.fit&&a.extendMapBounds(e,b),f(a.polyline.getPath(),a.scope,"path",function(b){return a.scope.fit?a.extendMapBounds(e,b):void 0}),a.listeners=a.model?a.setEvents(a.polyline,a.scope,a.model):a.setEvents(a.polyline,a.scope,a.scope)):void 0}}(this),i(),b.$watch("path",function(a){return function(b,c){return _.isEqual(b,c)&&a.polyline?void 0:i()}}(this)),!b["static"]&&angular.isDefined(b.editable)&&b.$watch("editable",function(a){return function(b,c){var d;return b!==c&&null!=(d=a.polyline)?d.setEditable(b):void 0}}(this)),angular.isDefined(b.draggable)&&b.$watch("draggable",function(a){return function(b,c){var d;return b!==c&&null!=(d=a.polyline)?d.setDraggable(b):void 0}}(this)),angular.isDefined(b.visible)&&b.$watch("visible",function(a){return function(b,c){var d;return b!==c&&null!=(d=a.polyline)?d.setVisible(b):void 0}}(this)),angular.isDefined(b.geodesic)&&b.$watch("geodesic",function(a){return function(b,c){var d;return b!==c&&null!=(d=a.polyline)?d.setOptions(a.buildOpts(a.polyline.getPath())):void 0}}(this)),angular.isDefined(b.stroke)&&angular.isDefined(b.stroke.weight)&&b.$watch("stroke.weight",function(a){return function(b,c){var d;return b!==c&&null!=(d=a.polyline)?d.setOptions(a.buildOpts(a.polyline.getPath())):void 0}}(this)),angular.isDefined(b.stroke)&&angular.isDefined(b.stroke.color)&&b.$watch("stroke.color",function(a){return function(b,c){var d;return b!==c&&null!=(d=a.polyline)?d.setOptions(a.buildOpts(a.polyline.getPath())):void 0}}(this)),angular.isDefined(b.stroke)&&angular.isDefined(b.stroke.opacity)&&b.$watch("stroke.opacity",function(a){return function(b,c){var d;return b!==c&&null!=(d=a.polyline)?d.setOptions(a.buildOpts(a.polyline.getPath())):void 0}}(this)),angular.isDefined(b.icons)&&b.$watch("icons",function(a){return function(b,c){var d;return b!==c&&null!=(d=a.polyline)?d.setOptions(a.buildOpts(a.polyline.getPath())):void 0}}(this)),b.$on("$destroy",function(a){return function(){return a.clean(),a.scope=null}}(this)),d.info(this)}return c(e,b),e.include(g),e.include(h),e.prototype.clean=function(){var a,b;return this.removeEvents(this.listeners),null!=(b=this.polyline)&&b.setMap(null),this.polyline=null,a?(a(),a=null):void 0},e.prototype.destroy=function(){return this.scope.$destroy()},e}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.child".ns()).factory("WindowChildModel".ns(),["BaseObject".ns(),"GmapUtil".ns(),"Logger".ns(),"$compile","$http","$templateCache",function(b,d,e,f,g,h){var i;return i=function(b){function i(b,c,d,f,g,h,i,j,k){this.model=b,this.scope=c,this.opts=d,this.isIconVisibleOnClick=f,this.mapCtrl=g,this.markerCtrl=h,this.element=i,this.needToManualDestroy=null!=j?j:!1,this.markerIsVisibleAfterWindowClose=null!=k?k:!0,this.getGWin=a(this.getGWin,this),this.destroy=a(this.destroy,this),this.remove=a(this.remove,this),this.getLatestPosition=a(this.getLatestPosition,this),this.hideWindow=a(this.hideWindow,this),this.showWindow=a(this.showWindow,this),this.handleClick=a(this.handleClick,this),this.watchOptions=a(this.watchOptions,this),this.watchCoords=a(this.watchCoords,this),this.createGWin=a(this.createGWin,this),this.watchElement=a(this.watchElement,this),this.watchAndDoShow=a(this.watchAndDoShow,this),this.doShow=a(this.doShow,this),this.googleMapsHandles=[],this.$log=e,this.createGWin(),null!=this.markerCtrl&&this.markerCtrl.setClickable(!0),this.watchElement(),this.watchOptions(),this.watchCoords(),this.watchAndDoShow(),this.scope.$on("$destroy",function(a){return function(){return a.destroy()}}(this)),this.$log.info(this)}return c(i,b),i.include(d),i.prototype.doShow=function(){return this.scope.show?this.showWindow():void 0},i.prototype.watchAndDoShow=function(){return null!=this.model.show&&(this.scope.show=this.model.show),this.scope.$watch("show",this.doShow,!0),this.doShow()},i.prototype.watchElement=function(){return this.scope.$watch(function(a){return function(){var b;if(a.element&&a.html)return a.html!==a.element.html()&&a.gWin?(null!=(b=a.opts)&&(b.content=void 0),a.remove(),a.createGWin()):void 0}}(this))},i.prototype.createGWin=function(){var a,b;return null==this.gWin&&(a={},null!=this.opts&&(this.scope.coords&&(this.opts.position=this.getCoords(this.scope.coords)),a=this.opts),this.element&&(this.html=_.isObject(this.element)?this.element.html():this.element),b=this.scope.options?this.scope.options:a,this.opts=this.createWindowOptions(this.markerCtrl,this.scope,this.html,b)),null==this.opts||this.gWin?void 0:(this.gWin=this.opts.boxClass&&window.InfoBox&&"function"==typeof window.InfoBox?new window.InfoBox(this.opts):new google.maps.InfoWindow(this.opts),this.handleClick(),this.doShow(),this.googleMapsHandles.push(google.maps.event.addListener(this.gWin,"closeclick",function(a){return function(){return a.markerCtrl&&(a.markerCtrl.setAnimation(a.oldMarkerAnimation),a.markerIsVisibleAfterWindowClose&&_.delay(function(){return a.markerCtrl.setVisible(!1),a.markerCtrl.setVisible(a.markerIsVisibleAfterWindowClose)},250)),a.gWin.isOpen(!1),null!=a.scope.closeClick?a.scope.$apply(a.scope.closeClick()):void 0}}(this))))},i.prototype.watchCoords=function(){var a;return a=null!=this.markerCtrl?this.scope.$parent:this.scope,a.$watch("coords",function(a){return function(b,c){var d;if(b!==c){if(null==b)return a.hideWindow();if(!a.validateCoords(b))return void a.$log.error("WindowChildMarker cannot render marker as scope.coords as no position on marker: "+JSON.stringify(a.model));if(d=a.getCoords(b),a.gWin.setPosition(d),a.opts)return a.opts.position=d}}}(this),!0)},i.prototype.watchOptions=function(){var a;return a=null!=this.markerCtrl?this.scope.$parent:this.scope,this.scope.$watch("options",function(a){return function(b,c){if(b!==c&&(a.opts=b,null!=a.gWin)){if(a.gWin.setOptions(a.opts),null!=a.opts.visible&&a.opts.visible)return a.showWindow();if(null!=a.opts.visible)return a.hideWindow()}}}(this),!0)},i.prototype.handleClick=function(a){var b;if(null!=this.gWin)return b=function(a){return function(){var b;return null==a.gWin&&a.createGWin(),b=a.markerCtrl.getPosition(),null!=a.gWin&&(a.gWin.setPosition(b),a.opts&&(a.opts.position=b),a.showWindow()),a.initialMarkerVisibility=a.markerCtrl.getVisible(),a.oldMarkerAnimation=a.markerCtrl.getAnimation(),a.markerCtrl.setVisible(a.isIconVisibleOnClick)}}(this),null!=this.markerCtrl?(a&&b(),this.googleMapsHandles.push(google.maps.event.addListener(this.markerCtrl,"click",b))):void 0},i.prototype.showWindow=function(){var a,b,c;return b=function(a){return function(){return null==a.gWin||a.gWin.isOpen()?void 0:a.gWin.open(a.mapCtrl)}}(this),this.scope.templateUrl?null!=this.gWin&&g.get(this.scope.templateUrl,{cache:h}).then(function(a){return function(b){var c,d;return d=a.scope.$new(),angular.isDefined(a.scope.templateParameter)&&(d.parameter=a.scope.templateParameter),c=f(b.data)(d),a.gWin.setContent(c[0])}}(this)):this.scope.template&&null!=this.gWin&&(c=this.scope.$new(),angular.isDefined(this.scope.templateParameter)&&(c.parameter=this.scope.templateParameter),a=f(this.scope.template)(c),this.gWin.setContent(a[0])),b()},i.prototype.hideWindow=function(){return null!=this.gWin&&this.gWin.isOpen()?this.gWin.close():void 0},i.prototype.getLatestPosition=function(a){return null==this.gWin||null==this.markerCtrl||a?a?this.gWin.setPosition(a):void 0:this.gWin.setPosition(this.markerCtrl.getPosition())},i.prototype.remove=function(){return this.hideWindow(),_.each(this.googleMapsHandles,function(a){return google.maps.event.removeListener(a)}),this.googleMapsHandles.length=0,delete this.gWin,delete this.opts},i.prototype.destroy=function(a){var b,c;return null==a&&(a=!1),this.remove(),null!=this.scope&&(null!=(c=this.scope)?c.$$destroyed:void 0)&&(this.needToManualDestroy||a)&&this.scope.$destroy(),b=void 0},i.prototype.getGWin=function(){return this.gWin},i}(b)}])}.call(this),function(){var a={}.hasOwnProperty,b=function(b,c){function d(){this.constructor=b}for(var e in c)a.call(c,e)&&(b[e]=c[e]);return d.prototype=c.prototype,b.prototype=new d,b.__super__=c.prototype,b};angular.module("google-maps.directives.api.models.parent".ns()).factory("CircleParentModel".ns(),["Logger".ns(),"$timeout","GmapUtil".ns(),"EventsHelper".ns(),"CircleOptionsBuilder".ns(),function(a,c,d,e,f){var g;return g=function(f){function g(b,e,f,g,h){var i,j;this.scope=b,this.attrs=f,this.map=g,this.DEFAULTS=h,i=new google.maps.Circle(this.buildOpts(d.getCoords(b.center),b.radius)),this.setMyOptions=function(a){return function(c,e){return _.isEqual(c,e)?void 0:i.setOptions(a.buildOpts(d.getCoords(b.center),b.radius))}}(this),this.props=this.props.concat([{prop:"center",isColl:!0},{prop:"fill",isColl:!0},"radius"]),this.watchProps(),j=this.setEvents(i,b,b),google.maps.event.addListener(i,"radius_changed",function(){return b.radius=i.getRadius(),c(function(){return b.$apply()})}),google.maps.event.addListener(i,"center_changed",function(){return angular.isDefined(b.center.type)?(b.center.coordinates[1]=i.getCenter().lat(),b.center.coordinates[0]=i.getCenter().lng()):(b.center.latitude=i.getCenter().lat(),b.center.longitude=i.getCenter().lng()),c(function(){return b.$apply()})}),b.$on("$destroy",function(a){return function(){return a.removeEvents(j),i.setMap(null)}}(this)),a.info(this)}return b(g,f),g.include(d),g.include(e),g}(f)}])}.call(this),function(){angular.module("google-maps.directives.api.models.parent".ns()).factory("DrawingManagerParentModel".ns(),["Logger".ns(),"$timeout",function(){var a;return a=function(){function a(a,b,c,d){var e;this.scope=a,this.attrs=c,this.map=d,e=new google.maps.drawing.DrawingManager(this.scope.options),e.setMap(this.map),null!=this.scope.control&&(this.scope.control.getDrawingManager=function(){return function(){return e}}(this)),!this.scope["static"]&&this.scope.options&&this.scope.$watch("options",function(){return function(a){return null!=e?e.setOptions(a):void 0}}(this),!0),a.$on("$destroy",function(){return function(){return e.setMap(null),e=null}}(this))}return a}()}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.parent".ns()).factory("IMarkerParentModel".ns(),["ModelKey".ns(),"Logger".ns(),function(b,d){var e;return e=function(b){function e(b,c,f,g){if(this.scope=b,this.element=c,this.attrs=f,this.map=g,this.onDestroy=a(this.onDestroy,this),this.onWatch=a(this.onWatch,this),this.watch=a(this.watch,this),this.validateScope=a(this.validateScope,this),e.__super__.constructor.call(this,this.scope),this.$log=d,!this.validateScope(b))throw new String("Unable to construct IMarkerParentModel due to invalid scope");this.doClick=angular.isDefined(f.click),null!=b.options&&(this.DEFAULTS=b.options),this.watch("coords",this.scope),this.watch("icon",this.scope),this.watch("options",this.scope),b.$on("$destroy",function(a){return function(){return a.onDestroy(b)}}(this))}return c(e,b),e.prototype.DEFAULTS={},e.prototype.validateScope=function(a){var b;return null==a?(this.$log.error(this.constructor.name+": invalid scope used"),!1):(b=null!=a.coords,b?b:(this.$log.error(this.constructor.name+": no valid coords attribute found"),!1))},e.prototype.watch=function(a,b){return b.$watch(a,function(c){return function(d,e){return _.isEqual(d,e)?void 0:c.onWatch(a,b,d,e)}}(this),!0)},e.prototype.onWatch=function(){},e.prototype.onDestroy=function(){throw new String("OnDestroy Not Implemented!!")},e}(b)}])}.call(this),function(){var a={}.hasOwnProperty,b=function(b,c){function d(){this.constructor=b}for(var e in c)a.call(c,e)&&(b[e]=c[e]);return d.prototype=c.prototype,b.prototype=new d,b.__super__=c.prototype,b};angular.module("google-maps.directives.api.models.parent".ns()).factory("IWindowParentModel".ns(),["ModelKey".ns(),"GmapUtil".ns(),"Logger".ns(),function(a,c,d){var e;return e=function(a){function e(a,b,c,f,g,h,i,j){e.__super__.constructor.call(this,a),this.$log=d,this.$timeout=g,this.$compile=h,this.$http=i,this.$templateCache=j,this.DEFAULTS={},null!=a.options&&(this.DEFAULTS=a.options)}return b(e,a),e.include(c),e}(a)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.parent".ns()).factory("LayerParentModel".ns(),["BaseObject".ns(),"Logger".ns(),"$timeout",function(b,d){var e;return e=function(b){function e(b,c,e,f,g,h){return this.scope=b,this.element=c,this.attrs=e,this.gMap=f,this.onLayerCreated=null!=g?g:void 0,this.$log=null!=h?h:d,this.createGoogleLayer=a(this.createGoogleLayer,this),null==this.attrs.type?void this.$log.info("type attribute for the layer directive is mandatory. Layer creation aborted!!"):(this.createGoogleLayer(),this.doShow=!0,angular.isDefined(this.attrs.show)&&(this.doShow=this.scope.show),this.doShow&&null!=this.gMap&&this.layer.setMap(this.gMap),this.scope.$watch("show",function(a){return function(b,c){return b!==c?(a.doShow=b,a.layer.setMap(b?a.gMap:null)):void 0}}(this),!0),this.scope.$watch("options",function(a){return function(b,c){return b!==c?(a.layer.setMap(null),a.layer=null,a.createGoogleLayer()):void 0}}(this),!0),void this.scope.$on("$destroy",function(a){return function(){return a.layer.setMap(null)}}(this)))}return c(e,b),e.prototype.createGoogleLayer=function(){var a;return this.layer=null==this.attrs.options?void 0===this.attrs.namespace?new google.maps[this.attrs.type]:new google.maps[this.attrs.namespace][this.attrs.type]:void 0===this.attrs.namespace?new google.maps[this.attrs.type](this.scope.options):new google.maps[this.attrs.namespace][this.attrs.type](this.scope.options),null!=this.layer&&null!=this.onLayerCreated&&(a=this.onLayerCreated(this.scope,this.layer))?a(this.layer):void 0},e}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.parent".ns()).factory("MapTypeParentModel".ns(),["BaseObject".ns(),"Logger".ns(),"$timeout",function(b,d){var e;return e=function(b){function e(b,c,e,f,g){return this.scope=b,this.element=c,this.attrs=e,this.gMap=f,this.$log=null!=g?g:d,this.hideOverlay=a(this.hideOverlay,this),this.showOverlay=a(this.showOverlay,this),this.refreshMapType=a(this.refreshMapType,this),this.createMapType=a(this.createMapType,this),null==this.attrs.options?void this.$log.info("options attribute for the map-type directive is mandatory. Map type creation aborted!!"):(this.id=this.gMap.overlayMapTypesCount=this.gMap.overlayMapTypesCount+1||0,this.doShow=!0,this.createMapType(),angular.isDefined(this.attrs.show)&&(this.doShow=this.scope.show),this.doShow&&null!=this.gMap&&this.showOverlay(),this.scope.$watch("show",function(a){return function(b,c){return b!==c?(a.doShow=b,b?a.showOverlay():a.hideOverlay()):void 0}}(this),!0),this.scope.$watch("options",function(a){return function(b,c){return _.isEqual(b,c)?void 0:a.refreshMapType()}}(this),!0),angular.isDefined(this.attrs.refresh)&&this.scope.$watch("refresh",function(a){return function(b,c){return _.isEqual(b,c)?void 0:a.refreshMapType()}}(this),!0),void this.scope.$on("$destroy",function(a){return function(){return a.hideOverlay(),a.mapType=null}}(this)))}return c(e,b),e.prototype.createMapType=function(){if(null!=this.scope.options.getTile)this.mapType=this.scope.options;else{if(null==this.scope.options.getTileUrl)return void this.$log.info("options should provide either getTile or getTileUrl methods. Map type creation aborted!!");this.mapType=new google.maps.ImageMapType(this.scope.options)}return this.attrs.id&&this.scope.id&&(this.gMap.mapTypes.set(this.scope.id,this.mapType),angular.isDefined(this.attrs.show)||(this.doShow=!1)),this.mapType.layerId=this.id},e.prototype.refreshMapType=function(){return this.hideOverlay(),this.mapType=null,this.createMapType(),this.doShow&&null!=this.gMap?this.showOverlay():void 0},e.prototype.showOverlay=function(){return this.gMap.overlayMapTypes.push(this.mapType)},e.prototype.hideOverlay=function(){var a;return a=!1,this.gMap.overlayMapTypes.forEach(function(b){return function(c,d){a||c.layerId!==b.id||(a=!0,b.gMap.overlayMapTypes.removeAt(d))}}(this))},e}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.parent".ns()).factory("MarkersParentModel".ns(),["IMarkerParentModel".ns(),"ModelsWatcher".ns(),"PropMap".ns(),"MarkerChildModel".ns(),"_async".ns(),"ClustererMarkerManager".ns(),"MarkerManager".ns(),"$timeout","IMarker".ns(),function(b,d,e,f,g,h,i,j,k){var l;return l=function(b){function j(b,c,d,f){this.onDestroy=a(this.onDestroy,this),this.newChildMarker=a(this.newChildMarker,this),this.updateChild=a(this.updateChild,this),this.pieceMeal=a(this.pieceMeal,this),this.reBuildMarkers=a(this.reBuildMarkers,this),this.createMarkersFromScratch=a(this.createMarkersFromScratch,this),this.validateScope=a(this.validateScope,this),this.onWatch=a(this.onWatch,this);var g;j.__super__.constructor.call(this,b,c,d,f),g=this,this.scope.markerModels=new e,this.$log.info(this),this.doRebuildAll=null!=this.scope.doRebuildAll?this.scope.doRebuildAll:!1,this.setIdKey(b),this.scope.$watch("doRebuildAll",function(a){return function(b,c){return b!==c?a.doRebuildAll=b:void 0}}(this)),this.watch("models",b),this.watch("doCluster",b),this.watch("clusterOptions",b),this.watch("clusterEvents",b),this.watch("fit",b),this.watch("idKey",b),this.gMarkerManager=void 0,this.createMarkersFromScratch(b)}return c(j,b),j.include(d),j.prototype.onWatch=function(a,b,c,d){return"idKey"===a&&c!==d&&(this.idKey=c),this.doRebuildAll?this.reBuildMarkers(b):this.pieceMeal(b)},j.prototype.validateScope=function(a){var b;return b=angular.isUndefined(a.models)||void 0===a.models,b&&this.$log.error(this.constructor.name+": no valid models attribute found"),j.__super__.validateScope.call(this,a)||b},j.prototype.createMarkersFromScratch=function(a){return a.doCluster?(a.clusterEvents&&(this.clusterInternalOptions=_.once(function(b){return function(){var c,d,e,f;return c=b,b.origClusterEvents?void 0:(b.origClusterEvents={click:null!=(d=a.clusterEvents)?d.click:void 0,mouseout:null!=(e=a.clusterEvents)?e.mouseout:void 0,mouseover:null!=(f=a.clusterEvents)?f.mouseover:void 0},_.extend(a.clusterEvents,{click:function(a){return c.maybeExecMappedEvent(a,"click")},mouseout:function(a){return c.maybeExecMappedEvent(a,"mouseout")},mouseover:function(a){return c.maybeExecMappedEvent(a,"mouseover")}}))}}(this))()),a.clusterOptions||a.clusterEvents?void 0===this.gMarkerManager?this.gMarkerManager=new h(this.map,void 0,a.clusterOptions,this.clusterInternalOptions):this.gMarkerManager.opt_options!==a.clusterOptions&&(this.gMarkerManager=new h(this.map,void 0,a.clusterOptions,this.clusterInternalOptions)):this.gMarkerManager=new h(this.map)):this.gMarkerManager=new i(this.map),g.waitOrGo(this,function(b){return function(){return g.each(a.models,function(c){return b.newChildMarker(c,a)},!1).then(function(){return b.gMarkerManager.draw(),a.fit?b.gMarkerManager.fit():void 0})}}(this)).then(function(a){return function(){return a.existingPieces=void 0}}(this))},j.prototype.reBuildMarkers=function(a){var b;if(a.doRebuild||void 0===a.doRebuild)return(null!=(b=this.scope.markerModels)?b.length:void 0)&&this.onDestroy(a),this.createMarkersFromScratch(a)},j.prototype.pieceMeal=function(a){var b;return b=null!=this.existingPieces?!1:g.defaultChunkSize,null!=this.scope.models&&this.scope.models.length>0&&this.scope.markerModels.length>0?this.figureOutState(this.idKey,a,this.scope.markerModels,this.modelKeyComparison,function(c){return function(d){var e;return e=d,g.waitOrGo(c,function(){return g.each(e.removals,function(a){return null!=a?(null!=a.destroy&&a.destroy(),c.scope.markerModels.remove(a.id)):void 0},b).then(function(){return g.each(e.adds,function(b){return c.newChildMarker(b,a)},b)}).then(function(){return g.each(e.updates,function(a){return c.updateChild(a.child,a.model)},b)}).then(function(){return(e.adds.length>0||e.removals.length>0||e.updates.length>0)&&(c.gMarkerManager.draw(),a.markerModels=c.scope.markerModels,a.fit)?c.gMarkerManager.fit():void 0})}).then(function(){return c.existingPieces=void 0})}}(this)):this.reBuildMarkers(a)},j.prototype.updateChild=function(a,b){return null==b[this.idKey]?void this.$log.error("Marker model has no id to assign a child to. This is required for performance. Please assign id, or redirect id to a different key."):a.setMyScope(b,a.model,!1)},j.prototype.newChildMarker=function(a,b){var c,d,e,g;return null==a[this.idKey]?void this.$log.error("Marker model has no id to assign a child to. This is required for performance. Please assign id, or redirect id to a different key."):(this.$log.info("child",c,"markers",this.scope.markerModels),d=b.$new(!1),d.events=b.events,g={},_.each(k.keys,function(a,c){return g[c]=b[c]}),c=new f(d,a,g,this.map,this.DEFAULTS,this.doClick,this.gMarkerManager,e=!1),this.scope.markerModels.put(a[this.idKey],c),c)},j.prototype.onDestroy=function(){return g.waitOrGo(this,function(a){return function(){return null!=a.gMarkerManager&&a.gMarkerManager.clear(),_.each(a.scope.markerModels.values(),function(a){return null!=a?a.destroy():void 0}),delete a.scope.markerModels,a.scope.markerModels=new e,Promise.resolve() +}}(this))},j.prototype.maybeExecMappedEvent=function(a,b){var c,d;return _.isFunction(null!=(d=this.scope.clusterEvents)?d[b]:void 0)&&(c=this.mapClusterToMarkerModels(a),this.origClusterEvents[b])?this.origClusterEvents[b](c.cluster,c.mapped):void 0},j.prototype.mapClusterToMarkerModels=function(a){var b,c;return b=a.getMarkers().values(),c=b.map(function(a){return function(b){return a.scope.markerModels[b.key].model}}(this)),{cluster:a,mapped:c}},j}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.parent".ns()).factory("PolylinesParentModel".ns(),["$timeout","Logger".ns(),"ModelKey".ns(),"ModelsWatcher".ns(),"PropMap".ns(),"PolylineChildModel".ns(),"_async".ns(),function(b,d,e,f,g,h,i){var j;return j=function(b){function e(b,c,f,h,i){var j;this.scope=b,this.element=c,this.attrs=f,this.gMap=h,this.defaults=i,this.modelKeyComparison=a(this.modelKeyComparison,this),this.setChildScope=a(this.setChildScope,this),this.createChild=a(this.createChild,this),this.pieceMeal=a(this.pieceMeal,this),this.createAllNew=a(this.createAllNew,this),this.watchIdKey=a(this.watchIdKey,this),this.createChildScopes=a(this.createChildScopes,this),this.watchOurScope=a(this.watchOurScope,this),this.watchDestroy=a(this.watchDestroy,this),this.rebuildAll=a(this.rebuildAll,this),this.doINeedToWipe=a(this.doINeedToWipe,this),this.watchModels=a(this.watchModels,this),this.watch=a(this.watch,this),e.__super__.constructor.call(this,b),j=this,this.$log=d,this.plurals=new g,this.scopePropNames=["path","stroke","clickable","draggable","editable","geodesic","icons","visible"],_.each(this.scopePropNames,function(a){return function(b){return a[b+"Key"]=void 0}}(this)),this.models=void 0,this.firstTime=!0,this.$log.info(this),this.watchOurScope(b),this.createChildScopes()}return c(e,b),e.include(f),e.prototype.watch=function(a,b,c){return a.$watch(b,function(a){return function(d,e){return d!==e?(a[c]="function"==typeof d?d():d,i.waitOrGo(a,function(){return i.each(_.values(a.plurals),function(d){return d.scope[b]="self"===a[c]?d:d[a[c]]})})):void 0}}(this))},e.prototype.watchModels=function(a){return a.$watch("models",function(b){return function(c,d){return _.isEqual(c,d)?void 0:b.doINeedToWipe(c)?b.rebuildAll(a,!0,!0):b.createChildScopes(!1)}}(this),!0)},e.prototype.doINeedToWipe=function(a){var b;return b=null!=a?0===a.length:!0,this.plurals.length>0&&b},e.prototype.rebuildAll=function(a,b,c){return i.waitOrGo(this,function(a){return function(){return i.each(a.plurals.values(),function(a){return a.destroy()}).then(function(){return c&&delete a.plurals,a.plurals=new g,b?a.createChildScopes():void 0})}}(this))},e.prototype.watchDestroy=function(a){return a.$on("$destroy",function(b){return function(){return b.rebuildAll(a,!1,!0)}}(this))},e.prototype.watchOurScope=function(a){return _.each(this.scopePropNames,function(b){return function(c){var d;return d=c+"Key",b[d]="function"==typeof a[c]?a[c]():a[c],b.watch(a,c,d)}}(this))},e.prototype.createChildScopes=function(a){return null==a&&(a=!0),angular.isUndefined(this.scope.models)?void this.$log.error("No models to create polylines from! I Need direct models!"):null!=this.gMap&&null!=this.scope.models?(this.watchIdKey(this.scope),a?this.createAllNew(this.scope,!1):this.pieceMeal(this.scope,!1)):void 0},e.prototype.watchIdKey=function(a){return this.setIdKey(a),a.$watch("idKey",function(b){return function(c,d){return c!==d&&null==c?(b.idKey=c,b.rebuildAll(a,!0,!0)):void 0}}(this))},e.prototype.createAllNew=function(a,b){return null==b&&(b=!1),this.models=a.models,this.firstTime&&(this.watchModels(a),this.watchDestroy(a)),i.waitOrGo(this,function(b){return function(){return i.each(a.models,function(a){return b.createChild(a,b.gMap)})}}(this)).then(function(a){return function(){return a.firstTime=!1,a.existingPieces=void 0}}(this))},e.prototype.pieceMeal=function(a,b){var c;return null==b&&(b=!0),c=null!=this.existingPieces?!1:i.defaultChunkSize,this.models=a.models,null!=a&&null!=a.models&&a.models.length>0&&this.plurals.length>0?this.figureOutState(this.idKey,a,this.plurals,this.modelKeyComparison,function(a){return function(b){var c;return c=b,i.waitOrGo(a,function(){return i.each(c.removals,function(b){var c;return c=a.plurals[b],null!=c?(c.destroy(),a.plurals.remove(b)):void 0}).then(function(){return i.each(c.adds,function(b){return a.createChild(b,a.gMap)})}).then(function(){return a.existingPieces=void 0})})}}(this)):this.rebuildAll(this.scope,!0,!0)},e.prototype.createChild=function(a,b){var c,d;return d=this.scope.$new(!1),this.setChildScope(d,a),d.$watch("model",function(a){return function(b,c){return b!==c?a.setChildScope(d,b):void 0}}(this),!0),d["static"]=this.scope["static"],c=new h(d,this.attrs,b,this.defaults,a),null==a[this.idKey]?void this.$log.error("Polyline model has no id to assign a child to. This is required for performance. Please assign id, or redirect id to a different key."):(this.plurals.put(a[this.idKey],c),c)},e.prototype.setChildScope=function(a,b){return _.each(this.scopePropNames,function(c){return function(d){var e,f;return e=d+"Key",f="self"===c[e]?b:b[c[e]],f!==a[d]?a[d]=f:void 0}}(this)),a.model=b},e.prototype.modelKeyComparison=function(a,b){return _.isEqual(this.evalModelHandle(a,this.scope.path),this.evalModelHandle(b,this.scope.path))},e}(e)}])}.call(this),function(){var a={}.hasOwnProperty,b=function(b,c){function d(){this.constructor=b}for(var e in c)a.call(c,e)&&(b[e]=c[e]);return d.prototype=c.prototype,b.prototype=new d,b.__super__=c.prototype,b};angular.module("google-maps.directives.api.models.parent".ns()).factory("RectangleParentModel".ns(),["Logger".ns(),"GmapUtil".ns(),"EventsHelper".ns(),"RectangleOptionsBuilder".ns(),function(a,c,d,e){var f;return f=function(e){function f(b,c,d,e,f){var g,h,i,j,k,l,m,n,o,p,q;this.scope=b,this.attrs=d,this.map=e,this.DEFAULTS=f,g=void 0,j=!1,n=[],m=void 0,k=function(a){return function(){return a.isTrue(d.fit)?a.fitMapBounds(a.map,g):void 0}}(this),i=function(c){return function(){var d,e;return null!=b.bounds&&null!=(null!=(d=b.bounds)?d.sw:void 0)&&null!=(null!=(e=b.bounds)?e.ne:void 0)&&c.validateBoundPoints(b.bounds)?(g=c.convertBoundPoints(b.bounds),a.info("new new bounds created: "+o)):null!=b.bounds.getNorthEast&&null!=b.bounds.getSouthWest?g=b.bounds:"undefined"!=typeof bound&&null!==bound?a.error("Invalid bounds for newValue: "+JSON.stringify(b.bounds)):void 0}}(this),i(),o=new google.maps.Rectangle(this.buildOpts(g)),a.info("rectangle created: "+o),p=!1,q=function(){return function(){var a,c,d;return a=o.getBounds(),c=a.getNorthEast(),d=a.getSouthWest(),p?void 0:_.defer(function(){return b.$apply(function(b){return null!=b.bounds&&null!=b.bounds.sw&&null!=b.bounds.ne&&(b.bounds.ne={latitude:c.lat(),longitude:c.lng()},b.bounds.sw={latitude:d.lat(),longitude:d.lng()}),null!=b.bounds.getNorthEast&&null!=b.bounds.getSouthWest?b.bounds=a:void 0})})}}(this),l=function(a){return function(){return k(),a.removeEvents(n),n.push(google.maps.event.addListener(o,"dragstart",function(){return j=!0})),n.push(google.maps.event.addListener(o,"dragend",function(){return j=!1,q()})),n.push(google.maps.event.addListener(o,"bounds_changed",function(){return j?void 0:q()}))}}(this),h=function(a){return function(){return a.removeEvents(n),null!=m&&a.removeEvents(m),o.setMap(null)}}(this),null!=g&&l(),b.$watch("bounds",function(a,b){var c;if(!(_.isEqual(a,b)&&null!=g||j))return p=!0,null==a?void h():(null==g?c=!0:k(),i(),o.setBounds(g),p=!1,c&&null!=g?l():void 0)},!0),this.setMyOptions=function(a){return function(b,c){return _.isEqual(b,c)||null==g||null==b?void 0:o.setOptions(a.buildOpts(g))}}(this),this.props.push("bounds"),this.watchProps(this.props),null!=d.events&&(m=this.setEvents(o,b,b),b.$watch("events",function(a){return function(c,d){return _.isEqual(c,d)?void 0:(null!=m&&a.removeEvents(m),m=a.setEvents(o,b,b))}}(this))),b.$on("$destroy",function(){return function(){return h()}}(this)),a.info(this)}return b(f,e),f.include(c),f.include(d),f}(e)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.parent".ns()).factory("SearchBoxParentModel".ns(),["BaseObject".ns(),"Logger".ns(),"EventsHelper".ns(),"$timeout","$http","$templateCache",function(b,d,e){var f;return f=function(b){function f(b,c,e,f,g,h,i){var j;return this.scope=b,this.element=c,this.attrs=e,this.gMap=f,this.ctrlPosition=g,this.template=h,this.$log=null!=i?i:d,this.getBounds=a(this.getBounds,this),this.setBounds=a(this.setBounds,this),this.createSearchBox=a(this.createSearchBox,this),this.addToParentDiv=a(this.addToParentDiv,this),this.addAsMapControl=a(this.addAsMapControl,this),this.init=a(this.init,this),null==this.attrs.template?void this.$log.error("template attribute for the search-box directive is mandatory. Places Search Box creation aborted!!"):(j=angular.element("
"),j.append(this.template),this.input=j.find("input")[0],void this.init())}return c(f,b),f.include(e),f.prototype.init=function(){return this.createSearchBox(),null!=this.attrs.parentdiv?this.addToParentDiv():this.addAsMapControl(),this.listener=google.maps.event.addListener(this.searchBox,"places_changed",function(a){return function(){return a.places=a.searchBox.getPlaces()}}(this)),this.listeners=this.setEvents(this.searchBox,this.scope,this.scope),this.$log.info(this),this.scope.$watch("options",function(a){return function(b){return angular.isObject(b)&&null!=b.bounds?a.setBounds(b.bounds):void 0}}(this),!0),this.scope.$on("$destroy",function(a){return function(){return a.searchBox=null}}(this))},f.prototype.addAsMapControl=function(){return this.gMap.controls[google.maps.ControlPosition[this.ctrlPosition]].push(this.input)},f.prototype.addToParentDiv=function(){return this.parentDiv=angular.element(document.getElementById(this.scope.parentdiv)),this.parentDiv.append(this.input)},f.prototype.createSearchBox=function(){return this.searchBox=new google.maps.places.SearchBox(this.input,this.scope.options)},f.prototype.setBounds=function(a){if(angular.isUndefined(a.isEmpty))this.$log.error("Error: SearchBoxParentModel setBounds. Bounds not an instance of LatLngBounds.");else if(a.isEmpty()===!1&&null!=this.searchBox)return this.searchBox.setBounds(a)},f.prototype.getBounds=function(){return this.searchBox.getBounds()},f}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api.models.parent".ns()).factory("WindowsParentModel".ns(),["IWindowParentModel".ns(),"ModelsWatcher".ns(),"PropMap".ns(),"WindowChildModel".ns(),"Linked".ns(),"_async".ns(),"Logger".ns(),"$timeout","$compile","$http","$templateCache","$interpolate",function(b,d,e,f,g,h,i,j,k,l,m,n){var o;return o=function(b){function o(b,c,d,f,h,i){var n;this.gMap=h,this.markersScope=i,this.interpolateContent=a(this.interpolateContent,this),this.setChildScope=a(this.setChildScope,this),this.createWindow=a(this.createWindow,this),this.setContentKeys=a(this.setContentKeys,this),this.pieceMealWindows=a(this.pieceMealWindows,this),this.createAllNewWindows=a(this.createAllNewWindows,this),this.watchIdKey=a(this.watchIdKey,this),this.createChildScopesWindows=a(this.createChildScopesWindows,this),this.watchOurScope=a(this.watchOurScope,this),this.watchDestroy=a(this.watchDestroy,this),this.rebuildAll=a(this.rebuildAll,this),this.doINeedToWipe=a(this.doINeedToWipe,this),this.watchModels=a(this.watchModels,this),this.go=a(this.go,this),o.__super__.constructor.call(this,b,c,d,f,j,k,l,m),n=this,this.windows=new e,this.scopePropNames=["coords","template","templateUrl","templateParameter","isIconVisibleOnClick","closeClick","options","show"],_.each(this.scopePropNames,function(a){return function(b){return a[b+"Key"]=void 0}}(this)),this.linked=new g(b,c,d,f),this.models=void 0,this.contentKeys=void 0,this.isIconVisibleOnClick=void 0,this.firstTime=!0,this.firstWatchModels=!0,this.$log.info(n),this.parentScope=void 0,this.go(b)}return c(o,b),o.include(d),o.prototype.go=function(a){return this.watchOurScope(a),this.doRebuildAll=null!=this.scope.doRebuildAll?this.scope.doRebuildAll:!1,a.$watch("doRebuildAll",function(a){return function(b,c){return b!==c?a.doRebuildAll=b:void 0}}(this)),this.createChildScopesWindows()},o.prototype.watchModels=function(a){return a.$watch("models",function(b){return function(c,d){var e;return!_.isEqual(c,d)||b.firstWatchModels?(b.firstWatchModels=!1,b.doRebuildAll||b.doINeedToWipe(c)?b.rebuildAll(a,!0,!0):(e=0===b.windows.length,null!=b.existingPieces?b.existingPieces.then(function(){return b.createChildScopesWindows(e)}):b.createChildScopesWindows(e))):void 0}}(this))},o.prototype.doINeedToWipe=function(a){var b;return b=null!=a?0===a.length:!0,this.windows.length>0&&b},o.prototype.rebuildAll=function(a,b,c){return h.waitOrGo(this,function(a){return function(){return h.each(a.windows.values(),function(a){return a.destroy()}).then(function(){return c&&delete a.windows,a.windows=new e,b&&a.createChildScopesWindows(),Promise.resolve()})}}(this))},o.prototype.watchDestroy=function(a){return a.$on("$destroy",function(b){return function(){return b.firstWatchModels=!0,b.firstTime=!0,b.rebuildAll(a,!1,!0)}}(this))},o.prototype.watchOurScope=function(a){return _.each(this.scopePropNames,function(b){return function(c){var d;return d=c+"Key",b[d]="function"==typeof a[c]?a[c]():a[c]}}(this))},o.prototype.createChildScopesWindows=function(a){var b,c,d;return null==a&&(a=!0),this.isIconVisibleOnClick=!0,angular.isDefined(this.linked.attrs.isiconvisibleonclick)&&(this.isIconVisibleOnClick=this.linked.scope.isIconVisibleOnClick),b=angular.isUndefined(this.linked.scope.models),!b||void 0!==this.markersScope&&void 0!==(null!=(c=this.markersScope)?c.markerModels:void 0)&&void 0!==(null!=(d=this.markersScope)?d.models:void 0)?null!=this.gMap?null!=this.linked.scope.models?(this.watchIdKey(this.linked.scope),a?this.createAllNewWindows(this.linked.scope,!1):this.pieceMealWindows(this.linked.scope,!1)):(this.parentScope=this.markersScope,this.watchIdKey(this.parentScope),a?this.createAllNewWindows(this.markersScope,!0,"markerModels",!1):this.pieceMealWindows(this.markersScope,!0,"markerModels",!1)):void 0:void this.$log.error("No models to create windows from! Need direct models or models derrived from markers!")},o.prototype.watchIdKey=function(a){return this.setIdKey(a),a.$watch("idKey",function(b){return function(c,d){return c!==d&&null==c?(b.idKey=c,b.rebuildAll(a,!0,!0)):void 0}}(this))},o.prototype.createAllNewWindows=function(a,b,c,d){return null==c&&(c="models"),null==d&&(d=!1),this.models=a.models,this.firstTime&&(this.watchModels(a),this.watchDestroy(a)),this.setContentKeys(a.models),h.waitOrGo(this,function(d){return function(){return h.each(a.models,function(e){var f,g;return f=b&&null!=(g=a[c][[e[d.idKey]]])?g.gMarker:void 0,d.createWindow(e,f,d.gMap)})}}(this)).then(function(a){return function(){return a.firstTime=!1}}(this))},o.prototype.pieceMealWindows=function(a,b,c,d){var e;return null==c&&(c="models"),null==d&&(d=!0),e=null!=this.existingPieces?!1:h.defaultChunkSize,this.models=a.models,null!=a&&null!=a.models&&a.models.length>0&&this.windows.length>0?this.figureOutState(this.idKey,a,this.windows,this.modelKeyComparison,function(b){return function(d){var f;return f=d,h.waitOrGo(b,function(){return h.each(f.removals,function(a){return null!=a&&(b.windows.remove(a.id),null!=a.destroy)?a.destroy(!0):void 0},e).then(function(){return h.each(f.adds,function(d){var e,f;if(e=null!=(f=a[c][d[b.idKey]])?f.gMarker:void 0,!e)throw"Gmarker undefined";return b.createWindow(d,e,b.gMap)},e)})}).then(function(){return b.existingPieces=void 0})["catch"](function(){return i.error("Error while pieceMealing Windows!")})}}(this)):this.rebuildAll(this.scope,!0,!0)},o.prototype.setContentKeys=function(a){return a.length>0?this.contentKeys=Object.keys(a[0]):void 0},o.prototype.createWindow=function(a,b,c){var d,e,g,h;return e=this.linked.scope.$new(!1),this.setChildScope(e,a),e.$watch("model",function(a){return function(b,c){var d;return b!==c&&(a.setChildScope(e,b),a.markersScope)?a.windows[b[a.idKey]].markerCtrl=null!=(d=a.markersScope.markerModels[b[a.idKey]])?d.gMarker:void 0:void 0}}(this),!0),g={html:function(b){return function(){return b.interpolateContent(b.linked.element.html(),a)}}(this)},this.DEFAULTS=this.markersScope?a[this.optionsKey]||{}:this.DEFAULTS,h=this.createWindowOptions(b,e,g.html(),this.DEFAULTS),d=new f(a,e,h,this.isIconVisibleOnClick,c,b,g,!1,!0),null==a[this.idKey]?void this.$log.error("Window model has no id to assign a child to. This is required for performance. Please assign id, or redirect id to a different key."):(this.windows.put(a[this.idKey],d),d)},o.prototype.setChildScope=function(a,b){return _.each(this.scopePropNames,function(c){return function(d){var e,f;return e=d+"Key",f="self"===c[e]?b:b[c[e]],f!==a[d]?a[d]=f:void 0}}(this)),a.model=b},o.prototype.interpolateContent=function(a,b){var c,d,e,f,g,h;if(void 0!==this.contentKeys&&0!==this.contentKeys.length){for(c=n(a),d={},h=this.contentKeys,f=0,g=h.length;g>f;f++)e=h[f],d[e]=b[e];return c(d)}},o}(b)}])}.call(this),function(){angular.module("google-maps.directives.api".ns()).factory("Circle".ns(),["ICircle".ns(),"CircleParentModel".ns(),function(a,b){return _.extend(a,{link:function(a,c,d,e){return e.getScope().deferred.promise.then(function(){return function(e){return new b(a,c,d,e)}}(this))}})}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("Control".ns(),["IControl".ns(),"$http","$templateCache","$compile","$controller","GoogleMapApi".ns(),function(b,d,e,f,g,h){var i;return i=function(i){function j(){this.link=a(this.link,this),j.__super__.constructor.call(this)}return c(j,i),j.prototype.link=function(a,c,i,j){return h.then(function(c){return function(h){var i,k;return angular.isUndefined(a.template)?void c.$log.error("mapControl: could not find a valid template property"):(i=angular.isDefined(a.index&&!isNaN(parseInt(a.index)))?parseInt(a.index):void 0,k=angular.isDefined(a.position)?a.position.toUpperCase().replace(/-/g,"_"):"TOP_CENTER",h.ControlPosition[k]?b.mapPromise(a,j).then(function(b){var h,j;return h=void 0,j=angular.element("
"),d.get(a.template,{cache:e}).success(function(b){var c,d;return d=a.$new(),j.append(b),i&&(j[0].index=i),angular.isDefined(a.controller)&&(c=g(a.controller,{$scope:d}),j.children().data("$ngControllerController",c)),h=f(j.contents())(d)}).error(function(){return c.$log.error("mapControl: template could not be found")}).then(function(){return b.controls[google.maps.ControlPosition[k]].push(h[0])})}):void c.$log.error("mapControl: invalid position property"))}}(this))},j}(b)}])}.call(this),function(){angular.module("google-maps.directives.api".ns()).factory("DrawingManager".ns(),["IDrawingManager".ns(),"DrawingManagerParentModel".ns(),function(a,b){return _.extend(a,{link:function(a,c,d,e){return e.getScope().deferred.promise.then(function(){return function(e){return new b(a,c,d,e)}}(this))}})}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("ApiFreeDrawPolygons".ns(),["Logger".ns(),"BaseObject".ns(),"CtrlHandle".ns(),"DrawFreeHandChildModel".ns(),function(b,d,e,f){var g;return g=function(d){function g(){return this.link=a(this.link,this),g.__super__.constructor.apply(this,arguments)}return c(g,d),g.include(e),g.prototype.restrict="EMA",g.prototype.replace=!0,g.prototype.require="^"+"GoogleMap".ns(),g.prototype.scope={polygons:"=",draw:"="},g.prototype.link=function(a,c,d,e){return this.mapPromise(a,e).then(function(){return function(c){var d,e;return a.polygons?_.isArray(a.polygons)?(d=new f(c,a.originalMapOpts),e=void 0,a.draw=function(){return"function"==typeof e&&e(),d.engage(a.polygons).then(function(){var b;return b=!0,e=a.$watch("polygons",function(a,c){var d;return b?void(b=!1):(d=_.differenceObjects(c,a),d.forEach(function(a){return a.setMap(null)}))})})}):b.error("Free Draw Polygons must be of type Array!"):b.error("No polygons to bind to!")}}(this))},g}(d)}])}.call(this),function(){angular.module("google-maps.directives.api".ns()).service("ICircle".ns(),[function(){var a;return a={},{restrict:"EA",replace:!0,require:"^"+"GoogleMap".ns(),scope:{center:"=center",radius:"=radius",stroke:"=stroke",fill:"=fill",clickable:"=",draggable:"=",editable:"=",geodesic:"=",icons:"=icons",visible:"=",events:"="}}}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("IControl".ns(),["BaseObject".ns(),"Logger".ns(),"CtrlHandle".ns(),function(b,d,e){var f;return f=function(b){function f(){this.link=a(this.link,this),this.restrict="EA",this.replace=!0,this.require="^"+"GoogleMap".ns(),this.scope={template:"@template",position:"@position",controller:"@controller",index:"@index"},this.$log=d}return c(f,b),f.extend(e),f.prototype.link=function(){throw new Exception("Not implemented!!")},f}(b)}])}.call(this),function(){angular.module("google-maps.directives.api".ns()).service("IDrawingManager".ns(),[function(){return{restrict:"EA",replace:!0,require:"^"+"GoogleMap".ns(),scope:{"static":"@",control:"=",options:"="}}}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("IMarker".ns(),["Logger".ns(),"BaseObject".ns(),"CtrlHandle".ns(),function(b,d,e){var f;return f=function(d){function f(){this.link=a(this.link,this),this.$log=b,this.restrict="EMA",this.require="^"+"GoogleMap".ns(),this.priority=-1,this.transclude=!0,this.replace=!0,this.scope=f.keys}return c(f,d),f.keys={coords:"=coords",icon:"=icon",click:"&click",options:"=options",events:"=events",fit:"=fit",idKey:"=idkey",control:"=control"},f.extend(e),f.prototype.link=function(a,b,c,d){if(!d)throw new Error("No Map Control! Marker Directive Must be inside the map!")},f}(d)}])}.call(this),function(){var a={}.hasOwnProperty,b=function(b,c){function d(){this.constructor=b}for(var e in c)a.call(c,e)&&(b[e]=c[e]);return d.prototype=c.prototype,b.prototype=new d,b.__super__=c.prototype,b};angular.module("google-maps.directives.api".ns()).factory("IPolygon".ns(),["GmapUtil".ns(),"BaseObject".ns(),"Logger".ns(),"CtrlHandle".ns(),function(a,c,d,e){var f;return f=function(c){function f(){}return b(f,c),f.include(a),f.extend(e),f.prototype.restrict="EMA",f.prototype.replace=!0,f.prototype.require="^"+"GoogleMap".ns(),f.prototype.scope={path:"=path",stroke:"=stroke",clickable:"=",draggable:"=",editable:"=",geodesic:"=",fill:"=",icons:"=icons",visible:"=","static":"=",events:"=",zIndex:"=zindex",fit:"=",control:"=control"},f.prototype.DEFAULTS={},f.prototype.$log=d,f}(c)}])}.call(this),function(){var a={}.hasOwnProperty,b=function(b,c){function d(){this.constructor=b}for(var e in c)a.call(c,e)&&(b[e]=c[e]);return d.prototype=c.prototype,b.prototype=new d,b.__super__=c.prototype,b};angular.module("google-maps.directives.api".ns()).factory("IPolyline".ns(),["GmapUtil".ns(),"BaseObject".ns(),"Logger".ns(),"CtrlHandle".ns(),function(a,c,d,e){var f;return f=function(c){function f(){}return b(f,c),f.include(a),f.extend(e),f.prototype.restrict="EMA",f.prototype.replace=!0,f.prototype.require="^"+"GoogleMap".ns(),f.prototype.scope={path:"=",stroke:"=",clickable:"=",draggable:"=",editable:"=",geodesic:"=",icons:"=",visible:"=","static":"=",fit:"=",events:"="},f.prototype.DEFAULTS={},f.prototype.$log=d,f}(c)}])}.call(this),function(){angular.module("google-maps.directives.api".ns()).service("IRectangle".ns(),[function(){"use strict";var a;return a={},{restrict:"EMA",require:"^"+"GoogleMap".ns(),replace:!0,scope:{bounds:"=",stroke:"=",clickable:"=",draggable:"=",editable:"=",fill:"=",visible:"=",events:"="}}}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("IWindow".ns(),["BaseObject".ns(),"ChildEvents".ns(),"Logger".ns(),function(b,d,e){var f;return f=function(b){function f(){this.link=a(this.link,this),this.restrict="EMA",this.template=void 0,this.transclude=!0,this.priority=-100,this.require="^"+"GoogleMap".ns(),this.replace=!0,this.scope={coords:"=coords",template:"=template",templateUrl:"=templateurl",templateParameter:"=templateparameter",isIconVisibleOnClick:"=isiconvisibleonclick",closeClick:"&closeclick",options:"=options",control:"=control",show:"=show"},this.$log=e}return c(f,b),f.include(d),f.prototype.link=function(){throw new Exception("Not Implemented!!")},f}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("Map".ns(),["$timeout","$q","Logger".ns(),"GmapUtil".ns(),"BaseObject".ns(),"CtrlHandle".ns(),"IsReady".ns(),"uuid".ns(),"ExtendGWin".ns(),"ExtendMarkerClusterer".ns(),"GoogleMapsUtilV3".ns(),"GoogleMapApi".ns(),function(b,d,e,f,g,h,i,j,k,l,m,n){"use strict";var o,p,q;return o=void 0,q=[m,k,l],p=function(b){function d(){this.link=a(this.link,this);var b,c;b=function(a){var b;return b=h.handle(a),a.ctrlType="Map",a.deferred.promise.then(function(){return q.forEach(function(a){return a.init()})}),b.getMap=function(){return a.map},_.extend(this,b)},this.controller=["$scope",b],c=this}return c(d,b),d.include(f),d.prototype.restrict="EMA",d.prototype.transclude=!0,d.prototype.replace=!1,d.prototype.template='
',d.prototype.scope={center:"=",zoom:"=",dragging:"=",control:"=",options:"=",events:"=",styles:"=",bounds:"="},d.prototype.link=function(a,b,c){return n.then(function(d){return function(f){var g,h,k,l,m,n,p,q,r,s,t;if(o={mapTypeId:f.MapTypeId.ROADMAP},r=i.spawn(),p=function(){return r.deferred.resolve({instance:r.instance,map:t})},!d.validateCoords(a.center))return void e.error("angular-google-maps: could not find a valid center property");if(!angular.isDefined(a.zoom))return void e.error("angular-google-maps: map zoom property not set");if(h=angular.element(b),h.addClass("angular-google-map"),n={options:{}},c.options&&(n.options=a.options),c.styles&&(n.styles=a.styles),c.type&&(s=c.type.toUpperCase(),google.maps.MapTypeId.hasOwnProperty(s)?n.mapTypeId=google.maps.MapTypeId[c.type.toUpperCase()]:e.error("angular-google-maps: invalid map type '"+c.type+"'")),m=angular.extend({},o,n,{center:d.getCoords(a.center),zoom:a.zoom,bounds:a.bounds}),t=new google.maps.Map(h.find("div")[1],m),t["_id".ns()]=j.generate(),g=!1,t?(a.deferred.resolve(t),p()):google.maps.event.addListener(t,"tilesloaded ",function(b){return a.deferred.resolve(b),p()}),google.maps.event.addListener(t,"dragstart",function(){return g=!0,_.defer(function(){return a.$apply(function(a){return null!=a.dragging?a.dragging=g:void 0})})}),google.maps.event.addListener(t,"dragend",function(){return g=!1,_.defer(function(){return a.$apply(function(a){return null!=a.dragging?a.dragging=g:void 0})})}),google.maps.event.addListener(t,"drag",function(){var b;return b=t.center,_.defer(function(){return a.$apply(function(a){return angular.isDefined(a.center.type)?(a.center.coordinates[1]=b.lat(),a.center.coordinates[0]=b.lng()):(a.center.latitude=b.lat(),a.center.longitude=b.lng())})})}),google.maps.event.addListener(t,"zoom_changed",function(){return a.zoom!==t.zoom?_.defer(function(){return a.$apply(function(a){return a.zoom=t.zoom})}):void 0}),q=!1,google.maps.event.addListener(t,"center_changed",function(){var b;return b=t.center,q?void 0:_.defer(function(){return a.$apply(function(a){if(!t.dragging)if(angular.isDefined(a.center.type)){if(a.center.coordinates[1]!==b.lat()&&(a.center.coordinates[1]=b.lat()),a.center.coordinates[0]!==b.lng())return a.center.coordinates[0]=b.lng()}else if(a.center.latitude!==b.lat()&&(a.center.latitude=b.lat()),a.center.longitude!==b.lng())return a.center.longitude=b.lng()})})}),google.maps.event.addListener(t,"idle",function(){var b,c,d;return b=t.getBounds(),c=b.getNorthEast(),d=b.getSouthWest(),_.defer(function(){return a.$apply(function(a){return null!==a.bounds&&void 0!==a.bounds&&void 0!==a.bounds?(a.bounds.northeast={latitude:c.lat(),longitude:c.lng()},a.bounds.southwest={latitude:d.lat(),longitude:d.lng()}):void 0})})}),angular.isDefined(a.events)&&null!==a.events&&angular.isObject(a.events)){l=function(b){return function(){return a.events[b].apply(a,[t,b,arguments])}};for(k in a.events)a.events.hasOwnProperty(k)&&angular.isFunction(a.events[k])&&google.maps.event.addListener(t,k,l(k))}return t.getOptions=function(){return m},a.map=t,null!=c.control&&null!=a.control&&(a.control.refresh=function(a){var b;if(null!=t)return google.maps.event.trigger(t,"resize"),null!=(null!=a?a.latitude:void 0)&&null!=(null!=a?a.latitude:void 0)?(b=d.getCoords(a),d.isTrue(c.pan)?t.panTo(b):t.setCenter(b)):void 0},a.control.getGMap=function(){return t},a.control.getMapOptions=function(){return m}),a.$watch("center",function(b){var f;return f=d.getCoords(b),f.lat()!==t.center.lat()||f.lng()!==t.center.lng()?(q=!0,g||(d.validateCoords(b)||e.error("Invalid center for newValue: "+JSON.stringify(b)),d.isTrue(c.pan)&&a.zoom===t.zoom?t.panTo(f):t.setCenter(f)),q=!1):void 0},!0),a.$watch("zoom",function(a){return a!==t.zoom?_.defer(function(){return t.setZoom(a)}):void 0}),a.$watch("bounds",function(a,b){var c,d,f;if(a!==b)return null==a.northeast.latitude||null==a.northeast.longitude||null==a.southwest.latitude||null==a.southwest.longitude?void e.error("Invalid map bounds for new value: "+JSON.stringify(a)):(d=new google.maps.LatLng(a.northeast.latitude,a.northeast.longitude),f=new google.maps.LatLng(a.southwest.latitude,a.southwest.longitude),c=new google.maps.LatLngBounds(f,d),t.fitBounds(c))}),a.$watch("options",function(a,b){return _.isEqual(a,b)||(n.options=a,null==t)?void 0:t.setOptions(n)},!0),a.$watch("styles",function(a,b){return _.isEqual(a,b)||(n.styles=a,null==t)?void 0:t.setOptions(n)},!0)}}(this))},d}(g)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments) +}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("Marker".ns(),["IMarker".ns(),"MarkerChildModel".ns(),"MarkerManager".ns(),function(b,d,e){var f;return f=function(f){function g(){this.link=a(this.link,this),g.__super__.constructor.call(this),this.template='',this.$log.info(this)}return c(g,f),g.prototype.controller=["$scope","$element",function(a,c){return a.ctrlType="Marker",_.extend(g,b.handle(a,c))}],g.prototype.link=function(a,c,f,g){var h;return a.fit&&(h=!0),b.mapPromise(a,g).then(function(c){return function(f){var g,h,i,j;return c.gMarkerManager||(c.gMarkerManager=new e(f)),i=_.keys(b.keys),i=_.object(i,i),c.promise=new d(a,a,i,f,{},g=!0,c.gMarkerManager,h=!1,j=!1).deferred.promise.then(function(b){return a.deferred.resolve(b)}),null!=a.control?a.control.getGMarkers=c.gMarkerManager.getGMarkers:void 0}}(this))},g}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("Markers".ns(),["IMarker".ns(),"MarkersParentModel".ns(),"_sync".ns(),function(b,d){var e;return e=function(e){function f(b){this.link=a(this.link,this),f.__super__.constructor.call(this,b),this.template='',this.scope=_.extend(this.scope||{},{idKey:"=idkey",doRebuildAll:"=dorebuildall",models:"=models",doCluster:"=docluster",clusterOptions:"=clusteroptions",clusterEvents:"=clusterevents"}),this.$log.info(this)}return c(f,e),f.prototype.controller=["$scope","$element",function(a,c){return a.ctrlType="Markers",_.extend(this,b.handle(a,c))}],f.prototype.link=function(a,c,e,f){var g,h;return g=void 0,h=function(){return function(){return null!=a.control&&(a.control.getGMarkers=function(){var a;return null!=(a=g.gMarkerManager)?a.getGMarkers():void 0},a.control.getChildMarkers=function(){return g.markerModels}),a.deferred.resolve()}}(this),b.mapPromise(a,f).then(function(){return function(b){return g=new d(a,c,e,b),g.existingPieces.then(function(){return h()})}}(this))},f}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("Polygon".ns(),["IPolygon".ns(),"$timeout","array-sync".ns(),"PolygonChildModel".ns(),function(b,d,e,f){var g;return g=function(d){function e(){return this.link=a(this.link,this),e.__super__.constructor.apply(this,arguments)}return c(e,d),e.prototype.link=function(a,c,d,e){var g,h;return g=[],h=b.mapPromise(a,e),null!=a.control&&(a.control.getInstance=this,a.control.polygons=g,a.control.promise=h),h.then(function(b){return function(c){return g.push(new f(a,d,c,b.DEFAULTS))}}(this))},e}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("Polyline".ns(),["IPolyline".ns(),"$timeout","array-sync".ns(),"PolylineChildModel".ns(),function(b,d,e,f){var g;return g=function(d){function e(){return this.link=a(this.link,this),e.__super__.constructor.apply(this,arguments)}return c(e,d),e.prototype.link=function(a,c,d,e){return angular.isUndefined(a.path)||null===a.path||!this.validatePath(a.path)?void this.$log.error("polyline: no valid path attribute found"):b.mapPromise(a,e).then(function(b){return function(c){return new f(a,d,c,b.DEFAULTS)}}(this))},e}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("Polylines".ns(),["IPolyline".ns(),"$timeout","array-sync".ns(),"PolylinesParentModel".ns(),function(b,d,e,f){var g;return g=function(b){function d(){this.link=a(this.link,this),d.__super__.constructor.call(this),this.scope.idKey="=idkey",this.scope.models="=models",this.$log.info(this)}return c(d,b),d.prototype.link=function(a,b,c,d){return angular.isUndefined(a.path)||null===a.path?void this.$log.error("polylines: no valid path attribute found"):a.models?d.getScope().deferred.promise.then(function(d){return function(e){return new f(a,b,c,e,d.DEFAULTS)}}(this)):void this.$log.error("polylines: no models found to create from")},d}(b)}])}.call(this),function(){angular.module("google-maps.directives.api".ns()).factory("Rectangle".ns(),["Logger".ns(),"GmapUtil".ns(),"IRectangle".ns(),"RectangleParentModel".ns(),function(a,b,c,d){return _.extend(c,{link:function(a,b,c,e){return e.getScope().deferred.promise.then(function(){return function(e){return new d(a,b,c,e)}}(this))}})}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("Window".ns(),["IWindow".ns(),"GmapUtil".ns(),"WindowChildModel".ns(),function(b,d,e){var f;return f=function(b){function f(){this.link=a(this.link,this),f.__super__.constructor.call(this),this.require=["^"+"GoogleMap".ns(),"^?"+"Marker".ns()],this.template='',this.$log.info(this),this.childWindows=[]}return c(f,b),f.include(d),f.prototype.link=function(a,b,c,d){var e,f,g;return e=d[0].getScope(),f=d.length>1&&null!=d[1]?d[1]:void 0,g=null!=f?f.getScope():void 0,e.deferred.promise.then(function(d){return function(e){var h;return h=!0,angular.isDefined(c.isiconvisibleonclick)&&(h=a.isIconVisibleOnClick),f?g.deferred.promise.then(function(c){return d.init(a,b,h,e,g,c)}):void d.init(a,b,h,e)}}(this))},f.prototype.init=function(a,b,c,d,f,g){var h,i,j,k;return i=null!=a.options?a.options:{},j=null!=a&&this.validateCoords(a.coords),null!=f&&f.$watch("coords",function(a){return function(b,c){return null==g||h.markerCtrl||(h.markerCtrl=g,h.handleClick(!0)),a.validateCoords(b)?angular.equals(b,c)?void 0:h.getLatestPosition(a.getCoords(b)):h.hideWindow()}}(this),!0),k=j?this.createWindowOptions(g,a,b.html(),i):i,null!=d&&(h=new e({},a,k,c,d,g,b),this.childWindows.push(h),a.$on("$destroy",function(a){return function(){return a.childWindows=_.withoutObjects(a.childWindows,[h],function(a,b){return a.scope.$id===b.scope.$id})}}(this))),null!=a.control&&(a.control.getGWindows=function(a){return function(){return a.childWindows.map(function(a){return a.gWin})}}(this),a.control.getChildWindows=function(a){return function(){return a.childWindows}}(this),a.control.showWindow=function(a){return function(){return a.childWindows.map(function(a){return a.showWindow()})}}(this),a.control.hideWindow=function(a){return function(){return a.childWindows.map(function(a){return a.hideWindow()})}}(this)),null!=this.onChildCreation&&null!=h?this.onChildCreation(h):void 0},f}(b)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}},b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};angular.module("google-maps.directives.api".ns()).factory("Windows".ns(),["IWindow".ns(),"WindowsParentModel".ns(),function(b,d){var e;return e=function(b){function e(){this.init=a(this.init,this),this.link=a(this.link,this),e.__super__.constructor.call(this),this.require=["^"+"GoogleMap".ns(),"^?"+"Markers".ns()],this.template='',this.scope.idKey="=idkey",this.scope.doRebuildAll="=dorebuildall",this.scope.models="=models",this.$log.debug(this)}return c(e,b),e.prototype.link=function(a,b,c,d){var e,f,g;return e=d[0].getScope(),f=d.length>1&&null!=d[1]?d[1]:void 0,g=null!=f?f.getScope():void 0,e.deferred.promise.then(function(e){return function(f){var h,i;return h=(null!=g&&null!=(i=g.deferred)?i.promise:void 0)||Promise.resolve(),h.then(function(){var h,i;return h=null!=(i=e.parentModel)?i.existingPieces:void 0,h?h.then(function(){return e.init(a,b,c,d,f,g)}):e.init(a,b,c,d,f,g)})}}(this))},e.prototype.init=function(a,b,c,e,f,g){var h;return h=new d(a,b,c,e,f,g),null!=a.control?(a.control.getGWindows=function(){return function(){return h.windows.map(function(a){return a.gWin})}}(this),a.control.getChildWindows=function(){return function(){return h.windows}}(this)):void 0},e}(b)}])}.call(this),function(){angular.module("google-maps".ns()).directive("GoogleMap".ns(),["Map".ns(),function(a){return new a}])}.call(this),function(){angular.module("google-maps".ns()).directive("Marker".ns(),["$timeout","Marker".ns(),function(a,b){return new b(a)}])}.call(this),function(){angular.module("google-maps".ns()).directive("Markers".ns(),["$timeout","Markers".ns(),function(a,b){return new b(a)}])}.call(this),function(){angular.module("google-maps".ns()).directive("Polygon".ns(),["Polygon".ns(),function(a){return new a}])}.call(this),function(){angular.module("google-maps".ns()).directive("Circle".ns(),["Circle".ns(),function(a){return a}])}.call(this),function(){angular.module("google-maps".ns()).directive("Polyline".ns(),["Polyline".ns(),function(a){return new a}])}.call(this),function(){angular.module("google-maps".ns()).directive("Polylines".ns(),["Polylines".ns(),function(a){return new a}])}.call(this),function(){angular.module("google-maps".ns()).directive("Rectangle".ns(),["Logger".ns(),"Rectangle".ns(),function(a,b){return b}])}.call(this),function(){angular.module("google-maps".ns()).directive("Window".ns(),["$timeout","$compile","$http","$templateCache","Window".ns(),function(a,b,c,d,e){return new e(a,b,c,d)}])}.call(this),function(){angular.module("google-maps".ns()).directive("Windows".ns(),["$timeout","$compile","$http","$templateCache","$interpolate","Windows".ns(),function(a,b,c,d,e,f){return new f(a,b,c,d,e)}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}};angular.module("google-maps".ns()).directive("Layer".ns(),["$timeout","Logger".ns(),"LayerParentModel".ns(),function(b,c,d){var e;return new(e=function(){function b(){this.link=a(this.link,this),this.$log=c,this.restrict="EMA",this.require="^"+"GoogleMap".ns(),this.priority=-1,this.transclude=!0,this.template='',this.replace=!0,this.scope={show:"=show",type:"=type",namespace:"=namespace",options:"=options",onCreated:"&oncreated"}}return b.prototype.link=function(a,b,c,e){return e.getScope().deferred.promise.then(function(){return function(e){return null!=a.onCreated?new d(a,b,c,e,a.onCreated):new d(a,b,c,e)}}(this))},b}())}])}.call(this),function(){angular.module("google-maps".ns()).directive("MapControl".ns(),["Control".ns(),function(a){return new a}])}.call(this),function(){angular.module("google-maps".ns()).directive("DrawingManager".ns(),["DrawingManager".ns(),function(a){return a}])}.call(this),function(){angular.module("google-maps".ns()).directive("FreeDrawPolygons".ns(),["ApiFreeDrawPolygons".ns(),function(a){return new a}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}};angular.module("google-maps".ns()).directive("MapType".ns(),["$timeout","Logger".ns(),"MapTypeParentModel".ns(),function(b,c,d){var e;return new(e=function(){function b(){this.link=a(this.link,this),this.$log=c,this.restrict="EMA",this.require="^"+"GoogleMap".ns(),this.priority=-1,this.transclude=!0,this.template='',this.replace=!0,this.scope={show:"=show",options:"=options",refresh:"=refresh",id:"@"}}return b.prototype.link=function(a,b,c,e){return e.getScope().deferred.promise.then(function(){return function(e){return new d(a,b,c,e)}}(this))},b}())}])}.call(this),function(){var a=function(a,b){return function(){return a.apply(b,arguments)}};angular.module("google-maps".ns()).directive("SearchBox".ns(),["GoogleMapApi".ns(),"Logger".ns(),"SearchBoxParentModel".ns(),"$http","$templateCache",function(b,c,d,e,f){var g;return new(g=function(){function g(){this.link=a(this.link,this),this.$log=c,this.restrict="EMA",this.require="^"+"GoogleMap".ns(),this.priority=-1,this.transclude=!0,this.template='',this.replace=!0,this.scope={template:"=template",position:"=position",options:"=options",events:"=events",parentdiv:"=parentdiv"}}return g.prototype.link=function(a,c,g,h){return b.then(function(b){return function(i){return e.get(a.template,{cache:f}).success(function(e){return h.getScope().deferred.promise.then(function(f){var h;return h=angular.isDefined(a.position)?a.position.toUpperCase().replace(/-/g,"_"):"TOP_LEFT",i.ControlPosition[h]?new d(a,c,g,f,h,e):void b.$log.error("searchBox: invalid position property")})})}}(this))},g}())}])}.call(this),angular.module("google-maps.wrapped".ns()).service("uuid".ns(),function(){function a(){}return a.generate=function(){var b=a._gri,c=a._ha;return c(b(32),8)+"-"+c(b(16),4)+"-"+c(16384|b(12),4)+"-"+c(32768|b(14),4)+"-"+c(b(48),12)},a._gri=function(a){return 0>a?0/0:30>=a?0|Math.random()*(1<=a?(0|1073741824*Math.random())+1073741824*(0|Math.random()*(1<0;d>>>=1,e+=e)1&d&&(c=e+c);return c},a}),angular.module("google-maps.wrapped".ns()).service("GoogleMapsUtilV3".ns(),function(){return{init:_.once(function(){function a(a){a=a||{},google.maps.OverlayView.apply(this,arguments),this.content_=a.content||"",this.disableAutoPan_=a.disableAutoPan||!1,this.maxWidth_=a.maxWidth||0,this.pixelOffset_=a.pixelOffset||new google.maps.Size(0,0),this.position_=a.position||new google.maps.LatLng(0,0),this.zIndex_=a.zIndex||null,this.boxClass_=a.boxClass||"infoBox",this.boxStyle_=a.boxStyle||{},this.closeBoxMargin_=a.closeBoxMargin||"2px",this.closeBoxURL_=a.closeBoxURL||"http://www.google.com/intl/en_us/mapfiles/close.gif",""===a.closeBoxURL&&(this.closeBoxURL_=""),this.infoBoxClearance_=a.infoBoxClearance||new google.maps.Size(1,1),"undefined"==typeof a.visible&&(a.visible="undefined"==typeof a.isHidden?!0:!a.isHidden),this.isHidden_=!a.visible,this.alignBottom_=a.alignBottom||!1,this.pane_=a.pane||"floatPane",this.enableEventPropagation_=a.enableEventPropagation||!1,this.div_=null,this.closeListener_=null,this.moveListener_=null,this.contextListener_=null,this.eventListeners_=null,this.fixedWidthSet_=null}function b(a,c){a.getMarkerClusterer().extend(b,google.maps.OverlayView),this.cluster_=a,this.className_=a.getMarkerClusterer().getClusterClass(),this.styles_=c,this.center_=null,this.div_=null,this.sums_=null,this.visible_=!1,this.setMap(a.getMap())}function c(a){this.markerClusterer_=a,this.map_=a.getMap(),this.gridSize_=a.getGridSize(),this.minClusterSize_=a.getMinimumClusterSize(),this.averageCenter_=a.getAverageCenter(),this.markers_=[],this.center_=null,this.bounds_=null,this.clusterIcon_=new b(this,a.getStyles())}function d(a,b,c){this.extend(d,google.maps.OverlayView),b=b||[],c=c||{},this.markers_=[],this.clusters_=[],this.listeners_=[],this.activeMap_=null,this.ready_=!1,this.gridSize_=c.gridSize||60,this.minClusterSize_=c.minimumClusterSize||2,this.maxZoom_=c.maxZoom||null,this.styles_=c.styles||[],this.title_=c.title||"",this.zoomOnClick_=!0,void 0!==c.zoomOnClick&&(this.zoomOnClick_=c.zoomOnClick),this.averageCenter_=!1,void 0!==c.averageCenter&&(this.averageCenter_=c.averageCenter),this.ignoreHidden_=!1,void 0!==c.ignoreHidden&&(this.ignoreHidden_=c.ignoreHidden),this.enableRetinaIcons_=!1,void 0!==c.enableRetinaIcons&&(this.enableRetinaIcons_=c.enableRetinaIcons),this.imagePath_=c.imagePath||d.IMAGE_PATH,this.imageExtension_=c.imageExtension||d.IMAGE_EXTENSION,this.imageSizes_=c.imageSizes||d.IMAGE_SIZES,this.calculator_=c.calculator||d.CALCULATOR,this.batchSize_=c.batchSize||d.BATCH_SIZE,this.batchSizeIE_=c.batchSizeIE||d.BATCH_SIZE_IE,this.clusterClass_=c.clusterClass||"cluster",-1!==navigator.userAgent.toLowerCase().indexOf("msie")&&(this.batchSize_=this.batchSizeIE_),this.setupStyles_(),this.addMarkers(b,!0),this.setMap(a)}function e(a,b){function c(){}c.prototype=b.prototype,a.superClass_=b.prototype,a.prototype=new c,a.prototype.constructor=a}function f(a,b){this.marker_=a,this.handCursorURL_=a.handCursorURL,this.labelDiv_=document.createElement("div"),this.labelDiv_.style.cssText="position: absolute; overflow: hidden;",this.eventDiv_=document.createElement("div"),this.eventDiv_.style.cssText=this.labelDiv_.style.cssText,this.eventDiv_.setAttribute("onselectstart","return false;"),this.eventDiv_.setAttribute("ondragstart","return false;"),this.crossDiv_=f.getSharedCross(b)}function g(a){a=a||{},a.labelContent=a.labelContent||"",a.labelAnchor=a.labelAnchor||new google.maps.Point(0,0),a.labelClass=a.labelClass||"markerLabels",a.labelStyle=a.labelStyle||{},a.labelInBackground=a.labelInBackground||!1,"undefined"==typeof a.labelVisible&&(a.labelVisible=!0),"undefined"==typeof a.raiseOnDrag&&(a.raiseOnDrag=!0),"undefined"==typeof a.clickable&&(a.clickable=!0),"undefined"==typeof a.draggable&&(a.draggable=!1),"undefined"==typeof a.optimized&&(a.optimized=!1),a.crossImage=a.crossImage||"http"+("https:"===document.location.protocol?"s":"")+"://maps.gstatic.com/intl/en_us/mapfiles/drag_cross_67_16.png",a.handCursor=a.handCursor||"http"+("https:"===document.location.protocol?"s":"")+"://maps.gstatic.com/intl/en_us/mapfiles/closedhand_8_8.cur",a.optimized=!1,this.label=new f(this,a.crossImage,a.handCursor),google.maps.Marker.apply(this,arguments)}a.prototype=new google.maps.OverlayView,a.prototype.createInfoBoxDiv_=function(){var a,b,c,d=this,e=function(a){a.cancelBubble=!0,a.stopPropagation&&a.stopPropagation()},f=function(a){a.returnValue=!1,a.preventDefault&&a.preventDefault(),d.enableEventPropagation_||e(a)};if(!this.div_){if(this.div_=document.createElement("div"),this.setBoxStyle_(),"undefined"==typeof this.content_.nodeType?this.div_.innerHTML=this.getCloseBoxImg_()+this.content_:(this.div_.innerHTML=this.getCloseBoxImg_(),this.div_.appendChild(this.content_)),this.getPanes()[this.pane_].appendChild(this.div_),this.addClickHandler_(),this.div_.style.width?this.fixedWidthSet_=!0:0!==this.maxWidth_&&this.div_.offsetWidth>this.maxWidth_?(this.div_.style.width=this.maxWidth_,this.div_.style.overflow="auto",this.fixedWidthSet_=!0):(c=this.getBoxWidths_(),this.div_.style.width=this.div_.offsetWidth-c.left-c.right+"px",this.fixedWidthSet_=!1),this.panBox_(this.disableAutoPan_),!this.enableEventPropagation_){for(this.eventListeners_=[],b=["mousedown","mouseover","mouseout","mouseup","click","dblclick","touchstart","touchend","touchmove"],a=0;ag&&(d=o.x+k+i+m-g),this.alignBottom_?o.y<-j+n+l?e=o.y+j-n-l:o.y+j+n>h&&(e=o.y+j+n-h):o.y<-j+n?e=o.y+j-n:o.y+l+j+n>h&&(e=o.y+l+j+n-h),0!==d||0!==e){{b.getCenter()}b.panBy(d,e)}}},a.prototype.setBoxStyle_=function(){var a,b;if(this.div_){this.div_.className=this.boxClass_,this.div_.style.cssText="",b=this.boxStyle_;for(a in b)b.hasOwnProperty(a)&&(this.div_.style[a]=b[a]);"undefined"!=typeof this.div_.style.opacity&&""!==this.div_.style.opacity&&(this.div_.style.filter="alpha(opacity="+100*this.div_.style.opacity+")"),this.div_.style.position="absolute",this.div_.style.visibility="hidden",null!==this.zIndex_&&(this.div_.style.zIndex=this.zIndex_)}},a.prototype.getBoxWidths_=function(){var a,b={top:0,bottom:0,left:0,right:0},c=this.div_;return document.defaultView&&document.defaultView.getComputedStyle?(a=c.ownerDocument.defaultView.getComputedStyle(c,""),a&&(b.top=parseInt(a.borderTopWidth,10)||0,b.bottom=parseInt(a.borderBottomWidth,10)||0,b.left=parseInt(a.borderLeftWidth,10)||0,b.right=parseInt(a.borderRightWidth,10)||0)):document.documentElement.currentStyle&&c.currentStyle&&(b.top=parseInt(c.currentStyle.borderTopWidth,10)||0,b.bottom=parseInt(c.currentStyle.borderBottomWidth,10)||0,b.left=parseInt(c.currentStyle.borderLeftWidth,10)||0,b.right=parseInt(c.currentStyle.borderRightWidth,10)||0),b},a.prototype.onRemove=function(){this.div_&&(this.div_.parentNode.removeChild(this.div_),this.div_=null)},a.prototype.draw=function(){this.createInfoBoxDiv_();var a=this.getProjection().fromLatLngToDivPixel(this.position_);this.div_.style.left=a.x+this.pixelOffset_.width+"px",this.alignBottom_?this.div_.style.bottom=-(a.y+this.pixelOffset_.height)+"px":this.div_.style.top=a.y+this.pixelOffset_.height+"px",this.div_.style.visibility=this.isHidden_?"hidden":"visible"},a.prototype.setOptions=function(a){"undefined"!=typeof a.boxClass&&(this.boxClass_=a.boxClass,this.setBoxStyle_()),"undefined"!=typeof a.boxStyle&&(this.boxStyle_=a.boxStyle,this.setBoxStyle_()),"undefined"!=typeof a.content&&this.setContent(a.content),"undefined"!=typeof a.disableAutoPan&&(this.disableAutoPan_=a.disableAutoPan),"undefined"!=typeof a.maxWidth&&(this.maxWidth_=a.maxWidth),"undefined"!=typeof a.pixelOffset&&(this.pixelOffset_=a.pixelOffset),"undefined"!=typeof a.alignBottom&&(this.alignBottom_=a.alignBottom),"undefined"!=typeof a.position&&this.setPosition(a.position),"undefined"!=typeof a.zIndex&&this.setZIndex(a.zIndex),"undefined"!=typeof a.closeBoxMargin&&(this.closeBoxMargin_=a.closeBoxMargin),"undefined"!=typeof a.closeBoxURL&&(this.closeBoxURL_=a.closeBoxURL),"undefined"!=typeof a.infoBoxClearance&&(this.infoBoxClearance_=a.infoBoxClearance),"undefined"!=typeof a.isHidden&&(this.isHidden_=a.isHidden),"undefined"!=typeof a.visible&&(this.isHidden_=!a.visible),"undefined"!=typeof a.enableEventPropagation&&(this.enableEventPropagation_=a.enableEventPropagation),this.div_&&this.draw()},a.prototype.setContent=function(a){this.content_=a,this.div_&&(this.closeListener_&&(google.maps.event.removeListener(this.closeListener_),this.closeListener_=null),this.fixedWidthSet_||(this.div_.style.width=""),"undefined"==typeof a.nodeType?this.div_.innerHTML=this.getCloseBoxImg_()+a:(this.div_.innerHTML=this.getCloseBoxImg_(),this.div_.appendChild(a)),this.fixedWidthSet_||(this.div_.style.width=this.div_.offsetWidth+"px","undefined"==typeof a.nodeType?this.div_.innerHTML=this.getCloseBoxImg_()+a:(this.div_.innerHTML=this.getCloseBoxImg_(),this.div_.appendChild(a))),this.addClickHandler_()),google.maps.event.trigger(this,"content_changed")},a.prototype.setPosition=function(a){this.position_=a,this.div_&&this.draw(),google.maps.event.trigger(this,"position_changed")},a.prototype.setZIndex=function(a){this.zIndex_=a,this.div_&&(this.div_.style.zIndex=a),google.maps.event.trigger(this,"zindex_changed")},a.prototype.setVisible=function(a){this.isHidden_=!a,this.div_&&(this.div_.style.visibility=this.isHidden_?"hidden":"visible")},a.prototype.getContent=function(){return this.content_},a.prototype.getPosition=function(){return this.position_},a.prototype.getZIndex=function(){return this.zIndex_},a.prototype.getVisible=function(){var a;return a="undefined"==typeof this.getMap()||null===this.getMap()?!1:!this.isHidden_},a.prototype.show=function(){this.isHidden_=!1,this.div_&&(this.div_.style.visibility="visible")},a.prototype.hide=function(){this.isHidden_=!0,this.div_&&(this.div_.style.visibility="hidden")},a.prototype.open=function(a,b){var c=this;b&&(this.position_=b.getPosition(),this.moveListener_=google.maps.event.addListener(b,"position_changed",function(){c.setPosition(this.getPosition())})),this.setMap(a),this.div_&&this.panBox_()},a.prototype.close=function(){var a;if(this.closeListener_&&(google.maps.event.removeListener(this.closeListener_),this.closeListener_=null),this.eventListeners_){for(a=0;af&&g.getMap().setZoom(f+1)},100)),d.cancelBubble=!0,d.stopPropagation&&d.stopPropagation()}}),google.maps.event.addDomListener(this.div_,"mouseover",function(){var a=c.cluster_.getMarkerClusterer();google.maps.event.trigger(a,"mouseover",c.cluster_)}),google.maps.event.addDomListener(this.div_,"mouseout",function(){var a=c.cluster_.getMarkerClusterer();google.maps.event.trigger(a,"mouseout",c.cluster_)})},b.prototype.onRemove=function(){this.div_&&this.div_.parentNode&&(this.hide(),google.maps.event.removeListener(this.boundsChangedListener_),google.maps.event.clearInstanceListeners(this.div_),this.div_.parentNode.removeChild(this.div_),this.div_=null)},b.prototype.draw=function(){if(this.visible_){var a=this.getPosFromLatLng_(this.center_);this.div_.style.top=a.y+"px",this.div_.style.left=a.x+"px"}},b.prototype.hide=function(){this.div_&&(this.div_.style.display="none"),this.visible_=!1},b.prototype.show=function(){if(this.div_){var a="",b=this.backgroundPosition_.split(" "),c=parseInt(b[0].trim(),10),d=parseInt(b[1].trim(),10),e=this.getPosFromLatLng_(this.center_);this.div_.style.cssText=this.createCss(e),a="",this.div_.innerHTML=a+"
"+this.sums_.text+"
",this.div_.title="undefined"==typeof this.sums_.title||""===this.sums_.title?this.cluster_.getMarkerClusterer().getTitle():this.sums_.title,this.div_.style.display=""}this.visible_=!0},b.prototype.useStyle=function(a){this.sums_=a;var b=Math.max(0,a.index-1);b=Math.min(this.styles_.length-1,b);var c=this.styles_[b];this.url_=c.url,this.height_=c.height,this.width_=c.width,this.anchorText_=c.anchorText||[0,0],this.anchorIcon_=c.anchorIcon||[parseInt(this.height_/2,10),parseInt(this.width_/2,10)],this.textColor_=c.textColor||"black",this.textSize_=c.textSize||11,this.textDecoration_=c.textDecoration||"none",this.fontWeight_=c.fontWeight||"bold",this.fontStyle_=c.fontStyle||"normal",this.fontFamily_=c.fontFamily||"Arial,sans-serif",this.backgroundPosition_=c.backgroundPosition||"0 0"},b.prototype.setCenter=function(a){this.center_=a},b.prototype.createCss=function(a){var b=[];return b.push("cursor: pointer;"),b.push("position: absolute; top: "+a.y+"px; left: "+a.x+"px;"),b.push("width: "+this.width_+"px; height: "+this.height_+"px;"),b.join("")},b.prototype.getPosFromLatLng_=function(a){var b=this.getProjection().fromLatLngToDivPixel(a);return b.x-=this.anchorIcon_[1],b.y-=this.anchorIcon_[0],b.x=parseInt(b.x,10),b.y=parseInt(b.y,10),b},c.prototype.getSize=function(){return this.markers_.length},c.prototype.getMarkers=function(){return this.markers_},c.prototype.getCenter=function(){return this.center_},c.prototype.getMap=function(){return this.map_},c.prototype.getMarkerClusterer=function(){return this.markerClusterer_},c.prototype.getBounds=function(){var a,b=new google.maps.LatLngBounds(this.center_,this.center_),c=this.getMarkers();for(a=0;ad)a.getMap()!==this.map_&&a.setMap(this.map_);else if(cb;b++)this.markers_[b].setMap(null);else a.setMap(null);return this.updateIcon_(),!0},c.prototype.isMarkerInClusterBounds=function(a){return this.bounds_.contains(a.getPosition())},c.prototype.calculateBounds_=function(){var a=new google.maps.LatLngBounds(this.center_,this.center_);this.bounds_=this.markerClusterer_.getExtendedBounds(a)},c.prototype.updateIcon_=function(){var a=this.markers_.length,b=this.markerClusterer_.getMaxZoom();if(null!==b&&this.map_.getZoom()>b)return void this.clusterIcon_.hide();if(a0))for(a=0;ad&&(g=d,h=e));h&&h.isMarkerInClusterBounds(a)?h.addMarker(a):(e=new c(this),e.addMarker(a),this.clusters_.push(e))},d.prototype.createClusters_=function(a){var b,c,d,e=this;if(this.ready_){0===a&&(google.maps.event.trigger(this,"clusteringbegin",this),"undefined"!=typeof this.timerRefStatic&&(clearTimeout(this.timerRefStatic),delete this.timerRefStatic)),d=this.getMap().getZoom()>3?new google.maps.LatLngBounds(this.getMap().getBounds().getSouthWest(),this.getMap().getBounds().getNorthEast()):new google.maps.LatLngBounds(new google.maps.LatLng(85.02070771743472,-178.48388434375),new google.maps.LatLng(-85.08136444384544,178.00048865625));var f=this.getExtendedBounds(d),g=Math.min(a+this.batchSize_,this.markers_.length);for(b=a;g>b;b++)c=this.markers_[b],!c.isAdded&&this.isMarkerInBounds_(c,f)&&(!this.ignoreHidden_||this.ignoreHidden_&&c.getVisible())&&this.addToClosestCluster_(c);gc?a.getMap()!==this.map_&&a.setMap(this.map_):b3?new google.maps.LatLngBounds(this.getMap().getBounds().getSouthWest(),this.getMap().getBounds().getNorthEast()):new google.maps.LatLngBounds(new google.maps.LatLng(85.02070771743472,-178.48388434375),new google.maps.LatLng(-85.08136444384544,178.00048865625));var f=this.getExtendedBounds(d),g=Math.min(a+this.batchSize_,this.markers_.length);for(b=a;g>b;b++)c=this.markers_.values()[b],!c.isAdded&&this.isMarkerInBounds_(c,f)&&(!this.ignoreHidden_||this.ignoreHidden_&&c.getVisible())&&this.addToClosestCluster_(c);if(gc&&(f=c,g=d));g&&g.isMarkerInClusterBounds(a)?g.addMarker(a):(d=new NgMapCluster(this),d.addMarker(a),this.clusters_.push(d))},c.prototype.redraw_=function(){this.createClusters_(0)},c.prototype.resetViewport_=function(a){var b;for(b=0;b + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.Promise=e():"undefined"!=typeof global?global.Promise=e():"undefined"!=typeof self&&(self.Promise=e())}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise) { +var SomePromiseArray = Promise._SomePromiseArray; +function Promise$_Any(promises) { + var ret = new SomePromiseArray(promises); + var promise = ret.promise(); + if (promise.isRejected()) { + return promise; + } + ret.setHowMany(1); + ret.setUnwrap(); + ret.init(); + return promise; +} + +Promise.any = function Promise$Any(promises) { + return Promise$_Any(promises); +}; + +Promise.prototype.any = function Promise$any() { + return Promise$_Any(this); +}; + +}; + +},{}],2:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +var schedule = require("./schedule.js"); +var Queue = require("./queue.js"); +var errorObj = require("./util.js").errorObj; +var tryCatch1 = require("./util.js").tryCatch1; +var _process = typeof process !== "undefined" ? process : void 0; + +function Async() { + this._isTickUsed = false; + this._schedule = schedule; + this._length = 0; + this._lateBuffer = new Queue(16); + this._functionBuffer = new Queue(65536); + var self = this; + this.consumeFunctionBuffer = function Async$consumeFunctionBuffer() { + self._consumeFunctionBuffer(); + }; +} + +Async.prototype.haveItemsQueued = function Async$haveItemsQueued() { + return this._length > 0; +}; + +Async.prototype.invokeLater = function Async$invokeLater(fn, receiver, arg) { + if (_process !== void 0 && + _process.domain != null && + !fn.domain) { + fn = _process.domain.bind(fn); + } + this._lateBuffer.push(fn, receiver, arg); + this._queueTick(); +}; + +Async.prototype.invoke = function Async$invoke(fn, receiver, arg) { + if (_process !== void 0 && + _process.domain != null && + !fn.domain) { + fn = _process.domain.bind(fn); + } + var functionBuffer = this._functionBuffer; + functionBuffer.push(fn, receiver, arg); + this._length = functionBuffer.length(); + this._queueTick(); +}; + +Async.prototype._consumeFunctionBuffer = +function Async$_consumeFunctionBuffer() { + var functionBuffer = this._functionBuffer; + while (functionBuffer.length() > 0) { + var fn = functionBuffer.shift(); + var receiver = functionBuffer.shift(); + var arg = functionBuffer.shift(); + fn.call(receiver, arg); + } + this._reset(); + this._consumeLateBuffer(); +}; + +Async.prototype._consumeLateBuffer = function Async$_consumeLateBuffer() { + var buffer = this._lateBuffer; + while(buffer.length() > 0) { + var fn = buffer.shift(); + var receiver = buffer.shift(); + var arg = buffer.shift(); + var res = tryCatch1(fn, receiver, arg); + if (res === errorObj) { + this._queueTick(); + if (fn.domain != null) { + fn.domain.emit("error", res.e); + } else { + throw res.e; + } + } + } +}; + +Async.prototype._queueTick = function Async$_queue() { + if (!this._isTickUsed) { + this._schedule(this.consumeFunctionBuffer); + this._isTickUsed = true; + } +}; + +Async.prototype._reset = function Async$_reset() { + this._isTickUsed = false; + this._length = 0; +}; + +module.exports = new Async(); + +},{"./queue.js":25,"./schedule.js":28,"./util.js":35}],3:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +var Promise = require("./promise.js")(); +module.exports = Promise; +},{"./promise.js":20}],4:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +var cr = Object.create; +if (cr) { + var callerCache = cr(null); + var getterCache = cr(null); + callerCache[" size"] = getterCache[" size"] = 0; +} + +module.exports = function(Promise) { +var util = require("./util.js"); +var canEvaluate = util.canEvaluate; +var isIdentifier = util.isIdentifier; + +function makeMethodCaller (methodName) { + return new Function("obj", " \n\ + 'use strict' \n\ + var len = this.length; \n\ + switch(len) { \n\ + case 1: return obj.methodName(this[0]); \n\ + case 2: return obj.methodName(this[0], this[1]); \n\ + case 3: return obj.methodName(this[0], this[1], this[2]); \n\ + case 0: return obj.methodName(); \n\ + default: return obj.methodName.apply(obj, this); \n\ + } \n\ + ".replace(/methodName/g, methodName)); +} + +function makeGetter (propertyName) { + return new Function("obj", " \n\ + 'use strict'; \n\ + return obj.propertyName; \n\ + ".replace("propertyName", propertyName)); +} + +function getCompiled(name, compiler, cache) { + var ret = cache[name]; + if (typeof ret !== "function") { + if (!isIdentifier(name)) { + return null; + } + ret = compiler(name); + cache[name] = ret; + cache[" size"]++; + if (cache[" size"] > 512) { + var keys = Object.keys(cache); + for (var i = 0; i < 256; ++i) delete cache[keys[i]]; + cache[" size"] = keys.length - 256; + } + } + return ret; +} + +function getMethodCaller(name) { + return getCompiled(name, makeMethodCaller, callerCache); +} + +function getGetter(name) { + return getCompiled(name, makeGetter, getterCache); +} + +function caller(obj) { + return obj[this.pop()].apply(obj, this); +} +Promise.prototype.call = function Promise$call(methodName) { + var $_len = arguments.length;var args = new Array($_len - 1); for(var $_i = 1; $_i < $_len; ++$_i) {args[$_i - 1] = arguments[$_i];} + if (canEvaluate) { + var maybeCaller = getMethodCaller(methodName); + if (maybeCaller !== null) { + return this._then(maybeCaller, void 0, void 0, args, void 0); + } + } + args.push(methodName); + return this._then(caller, void 0, void 0, args, void 0); +}; + +function namedGetter(obj) { + return obj[this]; +} +function indexedGetter(obj) { + return obj[this]; +} +Promise.prototype.get = function Promise$get(propertyName) { + var isIndex = (typeof propertyName === "number"); + var getter; + if (!isIndex) { + if (canEvaluate) { + var maybeGetter = getGetter(propertyName); + getter = maybeGetter !== null ? maybeGetter : namedGetter; + } else { + getter = namedGetter; + } + } else { + getter = indexedGetter; + } + return this._then(getter, void 0, void 0, propertyName, void 0); +}; +}; + +},{"./util.js":35}],5:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise, INTERNAL) { +var errors = require("./errors.js"); +var canAttach = errors.canAttach; +var async = require("./async.js"); +var CancellationError = errors.CancellationError; + +Promise.prototype._cancel = function Promise$_cancel(reason) { + if (!this.isCancellable()) return this; + var parent; + var promiseToReject = this; + while ((parent = promiseToReject._cancellationParent) !== void 0 && + parent.isCancellable()) { + promiseToReject = parent; + } + this._unsetCancellable(); + promiseToReject._attachExtraTrace(reason); + promiseToReject._rejectUnchecked(reason); +}; + +Promise.prototype.cancel = function Promise$cancel(reason) { + if (!this.isCancellable()) return this; + reason = reason !== void 0 + ? (canAttach(reason) ? reason : new Error(reason + "")) + : new CancellationError(); + async.invokeLater(this._cancel, this, reason); + return this; +}; + +Promise.prototype.cancellable = function Promise$cancellable() { + if (this._cancellable()) return this; + this._setCancellable(); + this._cancellationParent = void 0; + return this; +}; + +Promise.prototype.uncancellable = function Promise$uncancellable() { + var ret = new Promise(INTERNAL); + ret._propagateFrom(this, 2 | 4); + ret._follow(this); + ret._unsetCancellable(); + return ret; +}; + +Promise.prototype.fork = +function Promise$fork(didFulfill, didReject, didProgress) { + var ret = this._then(didFulfill, didReject, didProgress, + void 0, void 0); + + ret._setCancellable(); + ret._cancellationParent = void 0; + return ret; +}; +}; + +},{"./async.js":2,"./errors.js":10}],6:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function() { +var inherits = require("./util.js").inherits; +var defineProperty = require("./es5.js").defineProperty; + +var rignore = new RegExp( + "\\b(?:[a-zA-Z0-9.]+\\$_\\w+|" + + "tryCatch(?:1|2|3|4|Apply)|new \\w*PromiseArray|" + + "\\w*PromiseArray\\.\\w*PromiseArray|" + + "setTimeout|CatchFilter\\$_\\w+|makeNodePromisified|processImmediate|" + + "process._tickCallback|nextTick|Async\\$\\w+)\\b" +); + +var rtraceline = null; +var formatStack = null; + +function formatNonError(obj) { + var str; + if (typeof obj === "function") { + str = "[function " + + (obj.name || "anonymous") + + "]"; + } else { + str = obj.toString(); + var ruselessToString = /\[object [a-zA-Z0-9$_]+\]/; + if (ruselessToString.test(str)) { + try { + var newStr = JSON.stringify(obj); + str = newStr; + } + catch(e) { + + } + } + if (str.length === 0) { + str = "(empty array)"; + } + } + return ("(<" + snip(str) + ">, no stack trace)"); +} + +function snip(str) { + var maxChars = 41; + if (str.length < maxChars) { + return str; + } + return str.substr(0, maxChars - 3) + "..."; +} + +function CapturedTrace(ignoreUntil, isTopLevel) { + this.captureStackTrace(CapturedTrace, isTopLevel); + +} +inherits(CapturedTrace, Error); + +CapturedTrace.prototype.captureStackTrace = +function CapturedTrace$captureStackTrace(ignoreUntil, isTopLevel) { + captureStackTrace(this, ignoreUntil, isTopLevel); +}; + +CapturedTrace.possiblyUnhandledRejection = +function CapturedTrace$PossiblyUnhandledRejection(reason) { + if (typeof console === "object") { + var message; + if (typeof reason === "object" || typeof reason === "function") { + var stack = reason.stack; + message = "Possibly unhandled " + formatStack(stack, reason); + } else { + message = "Possibly unhandled " + String(reason); + } + if (typeof console.error === "function" || + typeof console.error === "object") { + console.error(message); + } else if (typeof console.log === "function" || + typeof console.log === "object") { + console.log(message); + } + } +}; + +CapturedTrace.combine = function CapturedTrace$Combine(current, prev) { + var currentLastIndex = current.length - 1; + var currentLastLine = current[currentLastIndex]; + var commonRootMeetPoint = -1; + for (var i = prev.length - 1; i >= 0; --i) { + if (prev[i] === currentLastLine) { + commonRootMeetPoint = i; + break; + } + } + + for (var i = commonRootMeetPoint; i >= 0; --i) { + var line = prev[i]; + if (current[currentLastIndex] === line) { + current.pop(); + currentLastIndex--; + } else { + break; + } + } + + current.push("From previous event:"); + var lines = current.concat(prev); + + var ret = []; + + for (var i = 0, len = lines.length; i < len; ++i) { + + if (((rignore.test(lines[i]) && rtraceline.test(lines[i])) || + (i > 0 && !rtraceline.test(lines[i])) && + lines[i] !== "From previous event:") + ) { + continue; + } + ret.push(lines[i]); + } + return ret; +}; + +CapturedTrace.protectErrorMessageNewlines = function(stack) { + for (var i = 0; i < stack.length; ++i) { + if (rtraceline.test(stack[i])) { + break; + } + } + + if (i <= 1) return; + + var errorMessageLines = []; + for (var j = 0; j < i; ++j) { + errorMessageLines.push(stack.shift()); + } + stack.unshift(errorMessageLines.join("\u0002\u0000\u0001")); +}; + +CapturedTrace.isSupported = function CapturedTrace$IsSupported() { + return typeof captureStackTrace === "function"; +}; + +var captureStackTrace = (function stackDetection() { + if (typeof Error.stackTraceLimit === "number" && + typeof Error.captureStackTrace === "function") { + rtraceline = /^\s*at\s*/; + formatStack = function(stack, error) { + if (typeof stack === "string") return stack; + + if (error.name !== void 0 && + error.message !== void 0) { + return error.name + ". " + error.message; + } + return formatNonError(error); + + + }; + var captureStackTrace = Error.captureStackTrace; + return function CapturedTrace$_captureStackTrace( + receiver, ignoreUntil) { + captureStackTrace(receiver, ignoreUntil); + }; + } + var err = new Error(); + + if (typeof err.stack === "string" && + typeof "".startsWith === "function" && + (err.stack.startsWith("stackDetection@")) && + stackDetection.name === "stackDetection") { + + defineProperty(Error, "stackTraceLimit", { + writable: true, + enumerable: false, + configurable: false, + value: 25 + }); + rtraceline = /@/; + var rline = /[@\n]/; + + formatStack = function(stack, error) { + if (typeof stack === "string") { + return (error.name + ". " + error.message + "\n" + stack); + } + + if (error.name !== void 0 && + error.message !== void 0) { + return error.name + ". " + error.message; + } + return formatNonError(error); + }; + + return function captureStackTrace(o) { + var stack = new Error().stack; + var split = stack.split(rline); + var len = split.length; + var ret = ""; + for (var i = 0; i < len; i += 2) { + ret += split[i]; + ret += "@"; + ret += split[i + 1]; + ret += "\n"; + } + o.stack = ret; + }; + } else { + formatStack = function(stack, error) { + if (typeof stack === "string") return stack; + + if ((typeof error === "object" || + typeof error === "function") && + error.name !== void 0 && + error.message !== void 0) { + return error.name + ". " + error.message; + } + return formatNonError(error); + }; + + return null; + } +})(); + +return CapturedTrace; +}; + +},{"./es5.js":12,"./util.js":35}],7:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(NEXT_FILTER) { +var util = require("./util.js"); +var errors = require("./errors.js"); +var tryCatch1 = util.tryCatch1; +var errorObj = util.errorObj; +var keys = require("./es5.js").keys; +var TypeError = errors.TypeError; + +function CatchFilter(instances, callback, promise) { + this._instances = instances; + this._callback = callback; + this._promise = promise; +} + +function CatchFilter$_safePredicate(predicate, e) { + var safeObject = {}; + var retfilter = tryCatch1(predicate, safeObject, e); + + if (retfilter === errorObj) return retfilter; + + var safeKeys = keys(safeObject); + if (safeKeys.length) { + errorObj.e = new TypeError( + "Catch filter must inherit from Error " + + "or be a simple predicate function"); + return errorObj; + } + return retfilter; +} + +CatchFilter.prototype.doFilter = function CatchFilter$_doFilter(e) { + var cb = this._callback; + var promise = this._promise; + var boundTo = promise._boundTo; + for (var i = 0, len = this._instances.length; i < len; ++i) { + var item = this._instances[i]; + var itemIsErrorType = item === Error || + (item != null && item.prototype instanceof Error); + + if (itemIsErrorType && e instanceof item) { + var ret = tryCatch1(cb, boundTo, e); + if (ret === errorObj) { + NEXT_FILTER.e = ret.e; + return NEXT_FILTER; + } + return ret; + } else if (typeof item === "function" && !itemIsErrorType) { + var shouldHandle = CatchFilter$_safePredicate(item, e); + if (shouldHandle === errorObj) { + var trace = errors.canAttach(errorObj.e) + ? errorObj.e + : new Error(errorObj.e + ""); + this._promise._attachExtraTrace(trace); + e = errorObj.e; + break; + } else if (shouldHandle) { + var ret = tryCatch1(cb, boundTo, e); + if (ret === errorObj) { + NEXT_FILTER.e = ret.e; + return NEXT_FILTER; + } + return ret; + } + } + } + NEXT_FILTER.e = e; + return NEXT_FILTER; +}; + +return CatchFilter; +}; + +},{"./errors.js":10,"./es5.js":12,"./util.js":35}],8:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +var util = require("./util.js"); +var isPrimitive = util.isPrimitive; +var wrapsPrimitiveReceiver = util.wrapsPrimitiveReceiver; + +module.exports = function(Promise) { +var returner = function Promise$_returner() { + return this; +}; +var thrower = function Promise$_thrower() { + throw this; +}; + +var wrapper = function Promise$_wrapper(value, action) { + if (action === 1) { + return function Promise$_thrower() { + throw value; + }; + } else if (action === 2) { + return function Promise$_returner() { + return value; + }; + } +}; + + +Promise.prototype["return"] = +Promise.prototype.thenReturn = +function Promise$thenReturn(value) { + if (wrapsPrimitiveReceiver && isPrimitive(value)) { + return this._then( + wrapper(value, 2), + void 0, + void 0, + void 0, + void 0 + ); + } + return this._then(returner, void 0, void 0, value, void 0); +}; + +Promise.prototype["throw"] = +Promise.prototype.thenThrow = +function Promise$thenThrow(reason) { + if (wrapsPrimitiveReceiver && isPrimitive(reason)) { + return this._then( + wrapper(reason, 1), + void 0, + void 0, + void 0, + void 0 + ); + } + return this._then(thrower, void 0, void 0, reason, void 0); +}; +}; + +},{"./util.js":35}],9:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise, INTERNAL) { +var PromiseReduce = Promise.reduce; + +Promise.prototype.each = function Promise$each(fn) { + return PromiseReduce(this, fn, null, INTERNAL); +}; + +Promise.each = function Promise$Each(promises, fn) { + return PromiseReduce(promises, fn, null, INTERNAL); +}; +}; + +},{}],10:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +var Objectfreeze = require("./es5.js").freeze; +var util = require("./util.js"); +var inherits = util.inherits; +var notEnumerableProp = util.notEnumerableProp; + +function markAsOriginatingFromRejection(e) { + try { + notEnumerableProp(e, "isOperational", true); + } + catch(ignore) {} +} + +function originatesFromRejection(e) { + if (e == null) return false; + return ((e instanceof OperationalError) || + e["isOperational"] === true); +} + +function isError(obj) { + return obj instanceof Error; +} + +function canAttach(obj) { + return isError(obj); +} + +function subError(nameProperty, defaultMessage) { + function SubError(message) { + if (!(this instanceof SubError)) return new SubError(message); + this.message = typeof message === "string" ? message : defaultMessage; + this.name = nameProperty; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + } + inherits(SubError, Error); + return SubError; +} + +var _TypeError, _RangeError; +var CancellationError = subError("CancellationError", "cancellation error"); +var TimeoutError = subError("TimeoutError", "timeout error"); +var AggregateError = subError("AggregateError", "aggregate error"); +try { + _TypeError = TypeError; + _RangeError = RangeError; +} catch(e) { + _TypeError = subError("TypeError", "type error"); + _RangeError = subError("RangeError", "range error"); +} + +var methods = ("join pop push shift unshift slice filter forEach some " + + "every map indexOf lastIndexOf reduce reduceRight sort reverse").split(" "); + +for (var i = 0; i < methods.length; ++i) { + if (typeof Array.prototype[methods[i]] === "function") { + AggregateError.prototype[methods[i]] = Array.prototype[methods[i]]; + } +} + +AggregateError.prototype.length = 0; +AggregateError.prototype["isOperational"] = true; +var level = 0; +AggregateError.prototype.toString = function() { + var indent = Array(level * 4 + 1).join(" "); + var ret = "\n" + indent + "AggregateError of:" + "\n"; + level++; + indent = Array(level * 4 + 1).join(" "); + for (var i = 0; i < this.length; ++i) { + var str = this[i] === this ? "[Circular AggregateError]" : this[i] + ""; + var lines = str.split("\n"); + for (var j = 0; j < lines.length; ++j) { + lines[j] = indent + lines[j]; + } + str = lines.join("\n"); + ret += str + "\n"; + } + level--; + return ret; +}; + +function OperationalError(message) { + this.name = "OperationalError"; + this.message = message; + this.cause = message; + this["isOperational"] = true; + + if (message instanceof Error) { + this.message = message.message; + this.stack = message.stack; + } else if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + +} +inherits(OperationalError, Error); + +var key = "__BluebirdErrorTypes__"; +var errorTypes = Error[key]; +if (!errorTypes) { + errorTypes = Objectfreeze({ + CancellationError: CancellationError, + TimeoutError: TimeoutError, + OperationalError: OperationalError, + RejectionError: OperationalError, + AggregateError: AggregateError + }); + notEnumerableProp(Error, key, errorTypes); +} + +module.exports = { + Error: Error, + TypeError: _TypeError, + RangeError: _RangeError, + CancellationError: errorTypes.CancellationError, + OperationalError: errorTypes.OperationalError, + TimeoutError: errorTypes.TimeoutError, + AggregateError: errorTypes.AggregateError, + originatesFromRejection: originatesFromRejection, + markAsOriginatingFromRejection: markAsOriginatingFromRejection, + canAttach: canAttach +}; + +},{"./es5.js":12,"./util.js":35}],11:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise) { +var TypeError = require('./errors.js').TypeError; + +function apiRejection(msg) { + var error = new TypeError(msg); + var ret = Promise.rejected(error); + var parent = ret._peekContext(); + if (parent != null) { + parent._attachExtraTrace(error); + } + return ret; +} + +return apiRejection; +}; + +},{"./errors.js":10}],12:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +var isES5 = (function(){ + "use strict"; + return this === void 0; +})(); + +if (isES5) { + module.exports = { + freeze: Object.freeze, + defineProperty: Object.defineProperty, + keys: Object.keys, + getPrototypeOf: Object.getPrototypeOf, + isArray: Array.isArray, + isES5: isES5 + }; +} else { + var has = {}.hasOwnProperty; + var str = {}.toString; + var proto = {}.constructor.prototype; + + var ObjectKeys = function ObjectKeys(o) { + var ret = []; + for (var key in o) { + if (has.call(o, key)) { + ret.push(key); + } + } + return ret; + } + + var ObjectDefineProperty = function ObjectDefineProperty(o, key, desc) { + o[key] = desc.value; + return o; + } + + var ObjectFreeze = function ObjectFreeze(obj) { + return obj; + } + + var ObjectGetPrototypeOf = function ObjectGetPrototypeOf(obj) { + try { + return Object(obj).constructor.prototype; + } + catch (e) { + return proto; + } + } + + var ArrayIsArray = function ArrayIsArray(obj) { + try { + return str.call(obj) === "[object Array]"; + } + catch(e) { + return false; + } + } + + module.exports = { + isArray: ArrayIsArray, + keys: ObjectKeys, + defineProperty: ObjectDefineProperty, + freeze: ObjectFreeze, + getPrototypeOf: ObjectGetPrototypeOf, + isES5: isES5 + }; +} + +},{}],13:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise, INTERNAL) { +var PromiseMap = Promise.map; + +Promise.prototype.filter = function Promise$filter(fn, options) { + return PromiseMap(this, fn, options, INTERNAL); +}; + +Promise.filter = function Promise$Filter(promises, fn, options) { + return PromiseMap(promises, fn, options, INTERNAL); +}; +}; + +},{}],14:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise, NEXT_FILTER, cast) { +var util = require("./util.js"); +var wrapsPrimitiveReceiver = util.wrapsPrimitiveReceiver; +var isPrimitive = util.isPrimitive; +var thrower = util.thrower; + +function returnThis() { + return this; +} +function throwThis() { + throw this; +} +function return$(r) { + return function Promise$_returner() { + return r; + }; +} +function throw$(r) { + return function Promise$_thrower() { + throw r; + }; +} +function promisedFinally(ret, reasonOrValue, isFulfilled) { + var then; + if (wrapsPrimitiveReceiver && isPrimitive(reasonOrValue)) { + then = isFulfilled ? return$(reasonOrValue) : throw$(reasonOrValue); + } else { + then = isFulfilled ? returnThis : throwThis; + } + return ret._then(then, thrower, void 0, reasonOrValue, void 0); +} + +function finallyHandler(reasonOrValue) { + var promise = this.promise; + var handler = this.handler; + + var ret = promise._isBound() + ? handler.call(promise._boundTo) + : handler(); + + if (ret !== void 0) { + var maybePromise = cast(ret, void 0); + if (maybePromise instanceof Promise) { + return promisedFinally(maybePromise, reasonOrValue, + promise.isFulfilled()); + } + } + + if (promise.isRejected()) { + NEXT_FILTER.e = reasonOrValue; + return NEXT_FILTER; + } else { + return reasonOrValue; + } +} + +function tapHandler(value) { + var promise = this.promise; + var handler = this.handler; + + var ret = promise._isBound() + ? handler.call(promise._boundTo, value) + : handler(value); + + if (ret !== void 0) { + var maybePromise = cast(ret, void 0); + if (maybePromise instanceof Promise) { + return promisedFinally(maybePromise, value, true); + } + } + return value; +} + +Promise.prototype._passThroughHandler = +function Promise$_passThroughHandler(handler, isFinally) { + if (typeof handler !== "function") return this.then(); + + var promiseAndHandler = { + promise: this, + handler: handler + }; + + return this._then( + isFinally ? finallyHandler : tapHandler, + isFinally ? finallyHandler : void 0, void 0, + promiseAndHandler, void 0); +}; + +Promise.prototype.lastly = +Promise.prototype["finally"] = function Promise$finally(handler) { + return this._passThroughHandler(handler, true); +}; + +Promise.prototype.tap = function Promise$tap(handler) { + return this._passThroughHandler(handler, false); +}; +}; + +},{"./util.js":35}],15:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise, apiRejection, INTERNAL, cast) { +var errors = require("./errors.js"); +var TypeError = errors.TypeError; +var deprecated = require("./util.js").deprecated; +var util = require("./util.js"); +var errorObj = util.errorObj; +var tryCatch1 = util.tryCatch1; +var yieldHandlers = []; + +function promiseFromYieldHandler(value, yieldHandlers) { + var _errorObj = errorObj; + var _Promise = Promise; + var len = yieldHandlers.length; + for (var i = 0; i < len; ++i) { + var result = tryCatch1(yieldHandlers[i], void 0, value); + if (result === _errorObj) { + return _Promise.reject(_errorObj.e); + } + var maybePromise = cast(result, promiseFromYieldHandler); + if (maybePromise instanceof _Promise) return maybePromise; + } + return null; +} + +function PromiseSpawn(generatorFunction, receiver, yieldHandler) { + var promise = this._promise = new Promise(INTERNAL); + promise._setTrace(void 0); + this._generatorFunction = generatorFunction; + this._receiver = receiver; + this._generator = void 0; + this._yieldHandlers = typeof yieldHandler === "function" + ? [yieldHandler].concat(yieldHandlers) + : yieldHandlers; +} + +PromiseSpawn.prototype.promise = function PromiseSpawn$promise() { + return this._promise; +}; + +PromiseSpawn.prototype._run = function PromiseSpawn$_run() { + this._generator = this._generatorFunction.call(this._receiver); + this._receiver = + this._generatorFunction = void 0; + this._next(void 0); +}; + +PromiseSpawn.prototype._continue = function PromiseSpawn$_continue(result) { + if (result === errorObj) { + this._generator = void 0; + var trace = errors.canAttach(result.e) + ? result.e : new Error(result.e + ""); + this._promise._attachExtraTrace(trace); + this._promise._reject(result.e, trace); + return; + } + + var value = result.value; + if (result.done === true) { + this._generator = void 0; + if (!this._promise._tryFollow(value)) { + this._promise._fulfill(value); + } + } else { + var maybePromise = cast(value, void 0); + if (!(maybePromise instanceof Promise)) { + maybePromise = + promiseFromYieldHandler(maybePromise, this._yieldHandlers); + if (maybePromise === null) { + this._throw(new TypeError("A value was yielded that could not be treated as a promise")); + return; + } + } + maybePromise._then( + this._next, + this._throw, + void 0, + this, + null + ); + } +}; + +PromiseSpawn.prototype._throw = function PromiseSpawn$_throw(reason) { + if (errors.canAttach(reason)) + this._promise._attachExtraTrace(reason); + this._continue( + tryCatch1(this._generator["throw"], this._generator, reason) + ); +}; + +PromiseSpawn.prototype._next = function PromiseSpawn$_next(value) { + this._continue( + tryCatch1(this._generator.next, this._generator, value) + ); +}; + +Promise.coroutine = +function Promise$Coroutine(generatorFunction, options) { + if (typeof generatorFunction !== "function") { + throw new TypeError("generatorFunction must be a function"); + } + var yieldHandler = Object(options).yieldHandler; + var PromiseSpawn$ = PromiseSpawn; + return function () { + var generator = generatorFunction.apply(this, arguments); + var spawn = new PromiseSpawn$(void 0, void 0, yieldHandler); + spawn._generator = generator; + spawn._next(void 0); + return spawn.promise(); + }; +}; + +Promise.coroutine.addYieldHandler = function(fn) { + if (typeof fn !== "function") throw new TypeError("fn must be a function"); + yieldHandlers.push(fn); +}; + +Promise.spawn = function Promise$Spawn(generatorFunction) { + deprecated("Promise.spawn is deprecated. Use Promise.coroutine instead."); + if (typeof generatorFunction !== "function") { + return apiRejection("generatorFunction must be a function"); + } + var spawn = new PromiseSpawn(generatorFunction, this); + var ret = spawn.promise(); + spawn._run(Promise.spawn); + return ret; +}; +}; + +},{"./errors.js":10,"./util.js":35}],16:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = +function(Promise, PromiseArray, cast, INTERNAL) { +var util = require("./util.js"); +var canEvaluate = util.canEvaluate; +var tryCatch1 = util.tryCatch1; +var errorObj = util.errorObj; + + +if (canEvaluate) { + var thenCallback = function(i) { + return new Function("value", "holder", " \n\ + 'use strict'; \n\ + holder.pIndex = value; \n\ + holder.checkFulfillment(this); \n\ + ".replace(/Index/g, i)); + }; + + var caller = function(count) { + var values = []; + for (var i = 1; i <= count; ++i) values.push("holder.p" + i); + return new Function("holder", " \n\ + 'use strict'; \n\ + var callback = holder.fn; \n\ + return callback(values); \n\ + ".replace(/values/g, values.join(", "))); + }; + var thenCallbacks = []; + var callers = [void 0]; + for (var i = 1; i <= 5; ++i) { + thenCallbacks.push(thenCallback(i)); + callers.push(caller(i)); + } + + var Holder = function(total, fn) { + this.p1 = this.p2 = this.p3 = this.p4 = this.p5 = null; + this.fn = fn; + this.total = total; + this.now = 0; + }; + + Holder.prototype.callers = callers; + Holder.prototype.checkFulfillment = function(promise) { + var now = this.now; + now++; + var total = this.total; + if (now >= total) { + var handler = this.callers[total]; + var ret = tryCatch1(handler, void 0, this); + if (ret === errorObj) { + promise._rejectUnchecked(ret.e); + } else if (!promise._tryFollow(ret)) { + promise._fulfillUnchecked(ret); + } + } else { + this.now = now; + } + }; +} + +function reject(reason) { + this._reject(reason); +} + +Promise.join = function Promise$Join() { + var last = arguments.length - 1; + var fn; + if (last > 0 && typeof arguments[last] === "function") { + fn = arguments[last]; + if (last < 6 && canEvaluate) { + var ret = new Promise(INTERNAL); + ret._setTrace(void 0); + var holder = new Holder(last, fn); + var callbacks = thenCallbacks; + for (var i = 0; i < last; ++i) { + var maybePromise = cast(arguments[i], void 0); + if (maybePromise instanceof Promise) { + if (maybePromise.isPending()) { + maybePromise._then(callbacks[i], reject, + void 0, ret, holder); + } else if (maybePromise.isFulfilled()) { + callbacks[i].call(ret, + maybePromise._settledValue, holder); + } else { + ret._reject(maybePromise._settledValue); + maybePromise._unsetRejectionIsUnhandled(); + } + } else { + callbacks[i].call(ret, maybePromise, holder); + } + } + return ret; + } + } + var $_len = arguments.length;var args = new Array($_len); for(var $_i = 0; $_i < $_len; ++$_i) {args[$_i] = arguments[$_i];} + var ret = new PromiseArray(args).promise(); + return fn !== void 0 ? ret.spread(fn) : ret; +}; + +}; + +},{"./util.js":35}],17:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise, PromiseArray, apiRejection, cast, INTERNAL) { +var util = require("./util.js"); +var tryCatch3 = util.tryCatch3; +var errorObj = util.errorObj; +var PENDING = {}; +var EMPTY_ARRAY = []; + +function MappingPromiseArray(promises, fn, limit, _filter) { + this.constructor$(promises); + this._callback = fn; + this._preservedValues = _filter === INTERNAL + ? new Array(this.length()) + : null; + this._limit = limit; + this._inFlight = 0; + this._queue = limit >= 1 ? [] : EMPTY_ARRAY; + this._init$(void 0, -2); +} +util.inherits(MappingPromiseArray, PromiseArray); + +MappingPromiseArray.prototype._init = function MappingPromiseArray$_init() {}; + +MappingPromiseArray.prototype._promiseFulfilled = +function MappingPromiseArray$_promiseFulfilled(value, index) { + var values = this._values; + if (values === null) return; + + var length = this.length(); + var preservedValues = this._preservedValues; + var limit = this._limit; + if (values[index] === PENDING) { + values[index] = value; + if (limit >= 1) { + this._inFlight--; + this._drainQueue(); + if (this._isResolved()) return; + } + } else { + if (limit >= 1 && this._inFlight >= limit) { + values[index] = value; + this._queue.push(index); + return; + } + if (preservedValues !== null) preservedValues[index] = value; + + var callback = this._callback; + var receiver = this._promise._boundTo; + var ret = tryCatch3(callback, receiver, value, index, length); + if (ret === errorObj) return this._reject(ret.e); + + var maybePromise = cast(ret, void 0); + if (maybePromise instanceof Promise) { + if (maybePromise.isPending()) { + if (limit >= 1) this._inFlight++; + values[index] = PENDING; + return maybePromise._proxyPromiseArray(this, index); + } else if (maybePromise.isFulfilled()) { + ret = maybePromise.value(); + } else { + maybePromise._unsetRejectionIsUnhandled(); + return this._reject(maybePromise.reason()); + } + } + values[index] = ret; + } + var totalResolved = ++this._totalResolved; + if (totalResolved >= length) { + if (preservedValues !== null) { + this._filter(values, preservedValues); + } else { + this._resolve(values); + } + + } +}; + +MappingPromiseArray.prototype._drainQueue = +function MappingPromiseArray$_drainQueue() { + var queue = this._queue; + var limit = this._limit; + var values = this._values; + while (queue.length > 0 && this._inFlight < limit) { + var index = queue.pop(); + this._promiseFulfilled(values[index], index); + } +}; + +MappingPromiseArray.prototype._filter = +function MappingPromiseArray$_filter(booleans, values) { + var len = values.length; + var ret = new Array(len); + var j = 0; + for (var i = 0; i < len; ++i) { + if (booleans[i]) ret[j++] = values[i]; + } + ret.length = j; + this._resolve(ret); +}; + +MappingPromiseArray.prototype.preservedValues = +function MappingPromiseArray$preserveValues() { + return this._preservedValues; +}; + +function map(promises, fn, options, _filter) { + var limit = typeof options === "object" && options !== null + ? options.concurrency + : 0; + limit = typeof limit === "number" && + isFinite(limit) && limit >= 1 ? limit : 0; + return new MappingPromiseArray(promises, fn, limit, _filter); +} + +Promise.prototype.map = function Promise$map(fn, options) { + if (typeof fn !== "function") return apiRejection("fn must be a function"); + + return map(this, fn, options, null).promise(); +}; + +Promise.map = function Promise$Map(promises, fn, options, _filter) { + if (typeof fn !== "function") return apiRejection("fn must be a function"); + return map(promises, fn, options, _filter).promise(); +}; + + +}; + +},{"./util.js":35}],18:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise) { +var util = require("./util.js"); +var async = require("./async.js"); +var tryCatch2 = util.tryCatch2; +var tryCatch1 = util.tryCatch1; +var errorObj = util.errorObj; + +function thrower(r) { + throw r; +} + +function Promise$_spreadAdapter(val, receiver) { + if (!util.isArray(val)) return Promise$_successAdapter(val, receiver); + var ret = util.tryCatchApply(this, [null].concat(val), receiver); + if (ret === errorObj) { + async.invokeLater(thrower, void 0, ret.e); + } +} + +function Promise$_successAdapter(val, receiver) { + var nodeback = this; + var ret = val === void 0 + ? tryCatch1(nodeback, receiver, null) + : tryCatch2(nodeback, receiver, null, val); + if (ret === errorObj) { + async.invokeLater(thrower, void 0, ret.e); + } +} +function Promise$_errorAdapter(reason, receiver) { + var nodeback = this; + var ret = tryCatch1(nodeback, receiver, reason); + if (ret === errorObj) { + async.invokeLater(thrower, void 0, ret.e); + } +} + +Promise.prototype.nodeify = function Promise$nodeify(nodeback, options) { + if (typeof nodeback == "function") { + var adapter = Promise$_successAdapter; + if (options !== void 0 && Object(options).spread) { + adapter = Promise$_spreadAdapter; + } + this._then( + adapter, + Promise$_errorAdapter, + void 0, + nodeback, + this._boundTo + ); + } + return this; +}; +}; + +},{"./async.js":2,"./util.js":35}],19:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise, PromiseArray) { +var util = require("./util.js"); +var async = require("./async.js"); +var errors = require("./errors.js"); +var tryCatch1 = util.tryCatch1; +var errorObj = util.errorObj; + +Promise.prototype.progressed = function Promise$progressed(handler) { + return this._then(void 0, void 0, handler, void 0, void 0); +}; + +Promise.prototype._progress = function Promise$_progress(progressValue) { + if (this._isFollowingOrFulfilledOrRejected()) return; + this._progressUnchecked(progressValue); + +}; + +Promise.prototype._clearFirstHandlerData$Base = +Promise.prototype._clearFirstHandlerData; +Promise.prototype._clearFirstHandlerData = +function Promise$_clearFirstHandlerData() { + this._clearFirstHandlerData$Base(); + this._progressHandler0 = void 0; +}; + +Promise.prototype._progressHandlerAt = +function Promise$_progressHandlerAt(index) { + return index === 0 + ? this._progressHandler0 + : this[(index << 2) + index - 5 + 2]; +}; + +Promise.prototype._doProgressWith = +function Promise$_doProgressWith(progression) { + var progressValue = progression.value; + var handler = progression.handler; + var promise = progression.promise; + var receiver = progression.receiver; + + var ret = tryCatch1(handler, receiver, progressValue); + if (ret === errorObj) { + if (ret.e != null && + ret.e.name !== "StopProgressPropagation") { + var trace = errors.canAttach(ret.e) + ? ret.e : new Error(ret.e + ""); + promise._attachExtraTrace(trace); + promise._progress(ret.e); + } + } else if (ret instanceof Promise) { + ret._then(promise._progress, null, null, promise, void 0); + } else { + promise._progress(ret); + } +}; + + +Promise.prototype._progressUnchecked = +function Promise$_progressUnchecked(progressValue) { + if (!this.isPending()) return; + var len = this._length(); + var progress = this._progress; + for (var i = 0; i < len; i++) { + var handler = this._progressHandlerAt(i); + var promise = this._promiseAt(i); + if (!(promise instanceof Promise)) { + var receiver = this._receiverAt(i); + if (typeof handler === "function") { + handler.call(receiver, progressValue, promise); + } else if (receiver instanceof Promise && receiver._isProxied()) { + receiver._progressUnchecked(progressValue); + } else if (receiver instanceof PromiseArray) { + receiver._promiseProgressed(progressValue, promise); + } + continue; + } + + if (typeof handler === "function") { + async.invoke(this._doProgressWith, this, { + handler: handler, + promise: promise, + receiver: this._receiverAt(i), + value: progressValue + }); + } else { + async.invoke(progress, promise, progressValue); + } + } +}; +}; + +},{"./async.js":2,"./errors.js":10,"./util.js":35}],20:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +var old; +if (typeof Promise !== "undefined") old = Promise; +function noConflict(bluebird) { + try { if (Promise === bluebird) Promise = old; } + catch (e) {} + return bluebird; +} +module.exports = function() { +var util = require("./util.js"); +var async = require("./async.js"); +var errors = require("./errors.js"); + +var INTERNAL = function(){}; +var APPLY = {}; +var NEXT_FILTER = {e: null}; + +var cast = require("./thenables.js")(Promise, INTERNAL); +var PromiseArray = require("./promise_array.js")(Promise, INTERNAL, cast); +var CapturedTrace = require("./captured_trace.js")(); +var CatchFilter = require("./catch_filter.js")(NEXT_FILTER); +var PromiseResolver = require("./promise_resolver.js"); + +var isArray = util.isArray; + +var errorObj = util.errorObj; +var tryCatch1 = util.tryCatch1; +var tryCatch2 = util.tryCatch2; +var tryCatchApply = util.tryCatchApply; +var RangeError = errors.RangeError; +var TypeError = errors.TypeError; +var CancellationError = errors.CancellationError; +var TimeoutError = errors.TimeoutError; +var OperationalError = errors.OperationalError; +var originatesFromRejection = errors.originatesFromRejection; +var markAsOriginatingFromRejection = errors.markAsOriginatingFromRejection; +var canAttach = errors.canAttach; +var thrower = util.thrower; +var apiRejection = require("./errors_api_rejection")(Promise); + + +var makeSelfResolutionError = function Promise$_makeSelfResolutionError() { + return new TypeError("circular promise resolution chain"); +}; + +function Promise(resolver) { + if (typeof resolver !== "function") { + throw new TypeError("the promise constructor requires a resolver function"); + } + if (this.constructor !== Promise) { + throw new TypeError("the promise constructor cannot be invoked directly"); + } + this._bitField = 0; + this._fulfillmentHandler0 = void 0; + this._rejectionHandler0 = void 0; + this._promise0 = void 0; + this._receiver0 = void 0; + this._settledValue = void 0; + this._boundTo = void 0; + if (resolver !== INTERNAL) this._resolveFromResolver(resolver); +} + +function returnFirstElement(elements) { + return elements[0]; +} + +Promise.prototype.bind = function Promise$bind(thisArg) { + var maybePromise = cast(thisArg, void 0); + var ret = new Promise(INTERNAL); + if (maybePromise instanceof Promise) { + var binder = maybePromise.then(function(thisArg) { + ret._setBoundTo(thisArg); + }); + var p = Promise.all([this, binder]).then(returnFirstElement); + ret._follow(p); + } else { + ret._follow(this); + ret._setBoundTo(thisArg); + } + ret._propagateFrom(this, 2 | 1); + return ret; +}; + +Promise.prototype.toString = function Promise$toString() { + return "[object Promise]"; +}; + +Promise.prototype.caught = Promise.prototype["catch"] = +function Promise$catch(fn) { + var len = arguments.length; + if (len > 1) { + var catchInstances = new Array(len - 1), + j = 0, i; + for (i = 0; i < len - 1; ++i) { + var item = arguments[i]; + if (typeof item === "function") { + catchInstances[j++] = item; + } else { + var catchFilterTypeError = + new TypeError( + "A catch filter must be an error constructor " + + "or a filter function"); + + this._attachExtraTrace(catchFilterTypeError); + return Promise.reject(catchFilterTypeError); + } + } + catchInstances.length = j; + fn = arguments[i]; + + this._resetTrace(); + var catchFilter = new CatchFilter(catchInstances, fn, this); + return this._then(void 0, catchFilter.doFilter, void 0, + catchFilter, void 0); + } + return this._then(void 0, fn, void 0, void 0, void 0); +}; + +function reflect() { + return new Promise.PromiseInspection(this); +} + +Promise.prototype.reflect = function Promise$reflect() { + return this._then(reflect, reflect, void 0, this, void 0); +}; + +Promise.prototype.then = +function Promise$then(didFulfill, didReject, didProgress) { + return this._then(didFulfill, didReject, didProgress, + void 0, void 0); +}; + + +Promise.prototype.done = +function Promise$done(didFulfill, didReject, didProgress) { + var promise = this._then(didFulfill, didReject, didProgress, + void 0, void 0); + promise._setIsFinal(); +}; + +Promise.prototype.spread = function Promise$spread(didFulfill, didReject) { + return this._then(didFulfill, didReject, void 0, + APPLY, void 0); +}; + +Promise.prototype.isCancellable = function Promise$isCancellable() { + return !this.isResolved() && + this._cancellable(); +}; + +Promise.prototype.toJSON = function Promise$toJSON() { + var ret = { + isFulfilled: false, + isRejected: false, + fulfillmentValue: void 0, + rejectionReason: void 0 + }; + if (this.isFulfilled()) { + ret.fulfillmentValue = this._settledValue; + ret.isFulfilled = true; + } else if (this.isRejected()) { + ret.rejectionReason = this._settledValue; + ret.isRejected = true; + } + return ret; +}; + +Promise.prototype.all = function Promise$all() { + return new PromiseArray(this).promise(); +}; + + +Promise.is = function Promise$Is(val) { + return val instanceof Promise; +}; + +Promise.all = function Promise$All(promises) { + return new PromiseArray(promises).promise(); +}; + +Promise.prototype.error = function Promise$_error(fn) { + return this.caught(originatesFromRejection, fn); +}; + +Promise.prototype._resolveFromSyncValue = +function Promise$_resolveFromSyncValue(value) { + if (value === errorObj) { + this._cleanValues(); + this._setRejected(); + var reason = value.e; + this._settledValue = reason; + this._tryAttachExtraTrace(reason); + this._ensurePossibleRejectionHandled(); + } else { + var maybePromise = cast(value, void 0); + if (maybePromise instanceof Promise) { + this._follow(maybePromise); + } else { + this._cleanValues(); + this._setFulfilled(); + this._settledValue = value; + } + } +}; + +Promise.method = function Promise$_Method(fn) { + if (typeof fn !== "function") { + throw new TypeError("fn must be a function"); + } + return function Promise$_method() { + var value; + switch(arguments.length) { + case 0: value = tryCatch1(fn, this, void 0); break; + case 1: value = tryCatch1(fn, this, arguments[0]); break; + case 2: value = tryCatch2(fn, this, arguments[0], arguments[1]); break; + default: + var $_len = arguments.length;var args = new Array($_len); for(var $_i = 0; $_i < $_len; ++$_i) {args[$_i] = arguments[$_i];} + value = tryCatchApply(fn, args, this); break; + } + var ret = new Promise(INTERNAL); + ret._setTrace(void 0); + ret._resolveFromSyncValue(value); + return ret; + }; +}; + +Promise.attempt = Promise["try"] = function Promise$_Try(fn, args, ctx) { + if (typeof fn !== "function") { + return apiRejection("fn must be a function"); + } + var value = isArray(args) + ? tryCatchApply(fn, args, ctx) + : tryCatch1(fn, ctx, args); + + var ret = new Promise(INTERNAL); + ret._setTrace(void 0); + ret._resolveFromSyncValue(value); + return ret; +}; + +Promise.defer = Promise.pending = function Promise$Defer() { + var promise = new Promise(INTERNAL); + promise._setTrace(void 0); + return new PromiseResolver(promise); +}; + +Promise.bind = function Promise$Bind(thisArg) { + var maybePromise = cast(thisArg, void 0); + var ret = new Promise(INTERNAL); + ret._setTrace(void 0); + + if (maybePromise instanceof Promise) { + var p = maybePromise.then(function(thisArg) { + ret._setBoundTo(thisArg); + }); + ret._follow(p); + } else { + ret._setBoundTo(thisArg); + ret._setFulfilled(); + } + return ret; +}; + +Promise.cast = function Promise$_Cast(obj) { + var ret = cast(obj, void 0); + if (!(ret instanceof Promise)) { + var val = ret; + ret = new Promise(INTERNAL); + ret._setTrace(void 0); + ret._setFulfilled(); + ret._cleanValues(); + ret._settledValue = val; + } + return ret; +}; + +Promise.resolve = Promise.fulfilled = Promise.cast; + +Promise.reject = Promise.rejected = function Promise$Reject(reason) { + var ret = new Promise(INTERNAL); + ret._setTrace(void 0); + markAsOriginatingFromRejection(reason); + ret._cleanValues(); + ret._setRejected(); + ret._settledValue = reason; + if (!canAttach(reason)) { + var trace = new Error(reason + ""); + ret._setCarriedStackTrace(trace); + } + ret._ensurePossibleRejectionHandled(); + return ret; +}; + +Promise.onPossiblyUnhandledRejection = +function Promise$OnPossiblyUnhandledRejection(fn) { + CapturedTrace.possiblyUnhandledRejection = typeof fn === "function" + ? fn : void 0; +}; + +var unhandledRejectionHandled; +Promise.onUnhandledRejectionHandled = +function Promise$onUnhandledRejectionHandled(fn) { + unhandledRejectionHandled = typeof fn === "function" ? fn : void 0; +}; + +var debugging = false || !!( + typeof process !== "undefined" && + typeof process.execPath === "string" && + typeof process.env === "object" && + (process.env["BLUEBIRD_DEBUG"] || + process.env["NODE_ENV"] === "development") +); + + +Promise.longStackTraces = function Promise$LongStackTraces() { + if (async.haveItemsQueued() && + debugging === false + ) { + throw new Error("cannot enable long stack traces after promises have been created"); + } + debugging = CapturedTrace.isSupported(); +}; + +Promise.hasLongStackTraces = function Promise$HasLongStackTraces() { + return debugging && CapturedTrace.isSupported(); +}; + +Promise.prototype._then = +function Promise$_then( + didFulfill, + didReject, + didProgress, + receiver, + internalData +) { + var haveInternalData = internalData !== void 0; + var ret = haveInternalData ? internalData : new Promise(INTERNAL); + + if (!haveInternalData) { + if (debugging) { + var haveSameContext = this._peekContext() === this._traceParent; + ret._traceParent = haveSameContext ? this._traceParent : this; + } + ret._propagateFrom(this, 7); + } + + var callbackIndex = + this._addCallbacks(didFulfill, didReject, didProgress, ret, receiver); + + if (this.isResolved()) { + async.invoke(this._queueSettleAt, this, callbackIndex); + } + + return ret; +}; + +Promise.prototype._length = function Promise$_length() { + return this._bitField & 262143; +}; + +Promise.prototype._isFollowingOrFulfilledOrRejected = +function Promise$_isFollowingOrFulfilledOrRejected() { + return (this._bitField & 939524096) > 0; +}; + +Promise.prototype._isFollowing = function Promise$_isFollowing() { + return (this._bitField & 536870912) === 536870912; +}; + +Promise.prototype._setLength = function Promise$_setLength(len) { + this._bitField = (this._bitField & -262144) | + (len & 262143); +}; + +Promise.prototype._setFulfilled = function Promise$_setFulfilled() { + this._bitField = this._bitField | 268435456; +}; + +Promise.prototype._setRejected = function Promise$_setRejected() { + this._bitField = this._bitField | 134217728; +}; + +Promise.prototype._setFollowing = function Promise$_setFollowing() { + this._bitField = this._bitField | 536870912; +}; + +Promise.prototype._setIsFinal = function Promise$_setIsFinal() { + this._bitField = this._bitField | 33554432; +}; + +Promise.prototype._isFinal = function Promise$_isFinal() { + return (this._bitField & 33554432) > 0; +}; + +Promise.prototype._cancellable = function Promise$_cancellable() { + return (this._bitField & 67108864) > 0; +}; + +Promise.prototype._setCancellable = function Promise$_setCancellable() { + this._bitField = this._bitField | 67108864; +}; + +Promise.prototype._unsetCancellable = function Promise$_unsetCancellable() { + this._bitField = this._bitField & (~67108864); +}; + +Promise.prototype._setRejectionIsUnhandled = +function Promise$_setRejectionIsUnhandled() { + this._bitField = this._bitField | 2097152; +}; + +Promise.prototype._unsetRejectionIsUnhandled = +function Promise$_unsetRejectionIsUnhandled() { + this._bitField = this._bitField & (~2097152); + if (this._isUnhandledRejectionNotified()) { + this._unsetUnhandledRejectionIsNotified(); + this._notifyUnhandledRejectionIsHandled(); + } +}; + +Promise.prototype._isRejectionUnhandled = +function Promise$_isRejectionUnhandled() { + return (this._bitField & 2097152) > 0; +}; + +Promise.prototype._setUnhandledRejectionIsNotified = +function Promise$_setUnhandledRejectionIsNotified() { + this._bitField = this._bitField | 524288; +}; + +Promise.prototype._unsetUnhandledRejectionIsNotified = +function Promise$_unsetUnhandledRejectionIsNotified() { + this._bitField = this._bitField & (~524288); +}; + +Promise.prototype._isUnhandledRejectionNotified = +function Promise$_isUnhandledRejectionNotified() { + return (this._bitField & 524288) > 0; +}; + +Promise.prototype._setCarriedStackTrace = +function Promise$_setCarriedStackTrace(capturedTrace) { + this._bitField = this._bitField | 1048576; + this._fulfillmentHandler0 = capturedTrace; +}; + +Promise.prototype._unsetCarriedStackTrace = +function Promise$_unsetCarriedStackTrace() { + this._bitField = this._bitField & (~1048576); + this._fulfillmentHandler0 = void 0; +}; + +Promise.prototype._isCarryingStackTrace = +function Promise$_isCarryingStackTrace() { + return (this._bitField & 1048576) > 0; +}; + +Promise.prototype._getCarriedStackTrace = +function Promise$_getCarriedStackTrace() { + return this._isCarryingStackTrace() + ? this._fulfillmentHandler0 + : void 0; +}; + +Promise.prototype._receiverAt = function Promise$_receiverAt(index) { + var ret = index === 0 + ? this._receiver0 + : this[(index << 2) + index - 5 + 4]; + if (this._isBound() && ret === void 0) { + return this._boundTo; + } + return ret; +}; + +Promise.prototype._promiseAt = function Promise$_promiseAt(index) { + return index === 0 + ? this._promise0 + : this[(index << 2) + index - 5 + 3]; +}; + +Promise.prototype._fulfillmentHandlerAt = +function Promise$_fulfillmentHandlerAt(index) { + return index === 0 + ? this._fulfillmentHandler0 + : this[(index << 2) + index - 5 + 0]; +}; + +Promise.prototype._rejectionHandlerAt = +function Promise$_rejectionHandlerAt(index) { + return index === 0 + ? this._rejectionHandler0 + : this[(index << 2) + index - 5 + 1]; +}; + +Promise.prototype._addCallbacks = function Promise$_addCallbacks( + fulfill, + reject, + progress, + promise, + receiver +) { + var index = this._length(); + + if (index >= 262143 - 5) { + index = 0; + this._setLength(0); + } + + if (index === 0) { + this._promise0 = promise; + if (receiver !== void 0) this._receiver0 = receiver; + if (typeof fulfill === "function" && !this._isCarryingStackTrace()) + this._fulfillmentHandler0 = fulfill; + if (typeof reject === "function") this._rejectionHandler0 = reject; + if (typeof progress === "function") this._progressHandler0 = progress; + } else { + var base = (index << 2) + index - 5; + this[base + 3] = promise; + this[base + 4] = receiver; + this[base + 0] = typeof fulfill === "function" + ? fulfill : void 0; + this[base + 1] = typeof reject === "function" + ? reject : void 0; + this[base + 2] = typeof progress === "function" + ? progress : void 0; + } + this._setLength(index + 1); + return index; +}; + +Promise.prototype._setProxyHandlers = +function Promise$_setProxyHandlers(receiver, promiseSlotValue) { + var index = this._length(); + + if (index >= 262143 - 5) { + index = 0; + this._setLength(0); + } + if (index === 0) { + this._promise0 = promiseSlotValue; + this._receiver0 = receiver; + } else { + var base = (index << 2) + index - 5; + this[base + 3] = promiseSlotValue; + this[base + 4] = receiver; + this[base + 0] = + this[base + 1] = + this[base + 2] = void 0; + } + this._setLength(index + 1); +}; + +Promise.prototype._proxyPromiseArray = +function Promise$_proxyPromiseArray(promiseArray, index) { + this._setProxyHandlers(promiseArray, index); +}; + +Promise.prototype._proxyPromise = function Promise$_proxyPromise(promise) { + promise._setProxied(); + this._setProxyHandlers(promise, -15); +}; + +Promise.prototype._setBoundTo = function Promise$_setBoundTo(obj) { + if (obj !== void 0) { + this._bitField = this._bitField | 8388608; + this._boundTo = obj; + } else { + this._bitField = this._bitField & (~8388608); + } +}; + +Promise.prototype._isBound = function Promise$_isBound() { + return (this._bitField & 8388608) === 8388608; +}; + +Promise.prototype._resolveFromResolver = +function Promise$_resolveFromResolver(resolver) { + var promise = this; + this._setTrace(void 0); + this._pushContext(); + + function Promise$_resolver(val) { + if (promise._tryFollow(val)) { + return; + } + promise._fulfill(val); + } + function Promise$_rejecter(val) { + var trace = canAttach(val) ? val : new Error(val + ""); + promise._attachExtraTrace(trace); + markAsOriginatingFromRejection(val); + promise._reject(val, trace === val ? void 0 : trace); + } + var r = tryCatch2(resolver, void 0, Promise$_resolver, Promise$_rejecter); + this._popContext(); + + if (r !== void 0 && r === errorObj) { + var e = r.e; + var trace = canAttach(e) ? e : new Error(e + ""); + promise._reject(e, trace); + } +}; + +Promise.prototype._spreadSlowCase = +function Promise$_spreadSlowCase(targetFn, promise, values, boundTo) { + var promiseForAll = new PromiseArray(values).promise(); + var promise2 = promiseForAll._then(function() { + return targetFn.apply(boundTo, arguments); + }, void 0, void 0, APPLY, void 0); + promise._follow(promise2); +}; + +Promise.prototype._callSpread = +function Promise$_callSpread(handler, promise, value) { + var boundTo = this._boundTo; + if (isArray(value)) { + for (var i = 0, len = value.length; i < len; ++i) { + if (cast(value[i], void 0) instanceof Promise) { + this._spreadSlowCase(handler, promise, value, boundTo); + return; + } + } + } + promise._pushContext(); + return tryCatchApply(handler, value, boundTo); +}; + +Promise.prototype._callHandler = +function Promise$_callHandler( + handler, receiver, promise, value) { + var x; + if (receiver === APPLY && !this.isRejected()) { + x = this._callSpread(handler, promise, value); + } else { + promise._pushContext(); + x = tryCatch1(handler, receiver, value); + } + promise._popContext(); + return x; +}; + +Promise.prototype._settlePromiseFromHandler = +function Promise$_settlePromiseFromHandler( + handler, receiver, value, promise +) { + if (!(promise instanceof Promise)) { + handler.call(receiver, value, promise); + return; + } + if (promise.isResolved()) return; + var x = this._callHandler(handler, receiver, promise, value); + if (promise._isFollowing()) return; + + if (x === errorObj || x === promise || x === NEXT_FILTER) { + var err = x === promise + ? makeSelfResolutionError() + : x.e; + var trace = canAttach(err) ? err : new Error(err + ""); + if (x !== NEXT_FILTER) promise._attachExtraTrace(trace); + promise._rejectUnchecked(err, trace); + } else { + var castValue = cast(x, promise); + if (castValue instanceof Promise) { + if (castValue.isRejected() && + !castValue._isCarryingStackTrace() && + !canAttach(castValue._settledValue)) { + var trace = new Error(castValue._settledValue + ""); + promise._attachExtraTrace(trace); + castValue._setCarriedStackTrace(trace); + } + promise._follow(castValue); + promise._propagateFrom(castValue, 1); + } else { + promise._fulfillUnchecked(x); + } + } +}; + +Promise.prototype._follow = +function Promise$_follow(promise) { + this._setFollowing(); + + if (promise.isPending()) { + this._propagateFrom(promise, 1); + promise._proxyPromise(this); + } else if (promise.isFulfilled()) { + this._fulfillUnchecked(promise._settledValue); + } else { + this._rejectUnchecked(promise._settledValue, + promise._getCarriedStackTrace()); + } + + if (promise._isRejectionUnhandled()) promise._unsetRejectionIsUnhandled(); + + if (debugging && + promise._traceParent == null) { + promise._traceParent = this; + } +}; + +Promise.prototype._tryFollow = +function Promise$_tryFollow(value) { + if (this._isFollowingOrFulfilledOrRejected() || + value === this) { + return false; + } + var maybePromise = cast(value, void 0); + if (!(maybePromise instanceof Promise)) { + return false; + } + this._follow(maybePromise); + return true; +}; + +Promise.prototype._resetTrace = function Promise$_resetTrace() { + if (debugging) { + this._trace = new CapturedTrace(this._peekContext() === void 0); + } +}; + +Promise.prototype._setTrace = function Promise$_setTrace(parent) { + if (debugging) { + var context = this._peekContext(); + this._traceParent = context; + var isTopLevel = context === void 0; + if (parent !== void 0 && + parent._traceParent === context) { + this._trace = parent._trace; + } else { + this._trace = new CapturedTrace(isTopLevel); + } + } + return this; +}; + +Promise.prototype._tryAttachExtraTrace = +function Promise$_tryAttachExtraTrace(error) { + if (canAttach(error)) { + this._attachExtraTrace(error); + } +}; + +Promise.prototype._attachExtraTrace = +function Promise$_attachExtraTrace(error) { + if (debugging) { + var promise = this; + var stack = error.stack; + stack = typeof stack === "string" ? stack.split("\n") : []; + CapturedTrace.protectErrorMessageNewlines(stack); + var headerLineCount = 1; + var combinedTraces = 1; + while(promise != null && + promise._trace != null) { + stack = CapturedTrace.combine( + stack, + promise._trace.stack.split("\n") + ); + promise = promise._traceParent; + combinedTraces++; + } + + var stackTraceLimit = Error.stackTraceLimit || 10; + var max = (stackTraceLimit + headerLineCount) * combinedTraces; + var len = stack.length; + if (len > max) { + stack.length = max; + } + + if (len > 0) + stack[0] = stack[0].split("\u0002\u0000\u0001").join("\n"); + + if (stack.length <= headerLineCount) { + error.stack = "(No stack trace)"; + } else { + error.stack = stack.join("\n"); + } + } +}; + +Promise.prototype._cleanValues = function Promise$_cleanValues() { + if (this._cancellable()) { + this._cancellationParent = void 0; + } +}; + +Promise.prototype._propagateFrom = +function Promise$_propagateFrom(parent, flags) { + if ((flags & 1) > 0 && parent._cancellable()) { + this._setCancellable(); + this._cancellationParent = parent; + } + if ((flags & 4) > 0) { + this._setBoundTo(parent._boundTo); + } + if ((flags & 2) > 0) { + this._setTrace(parent); + } +}; + +Promise.prototype._fulfill = function Promise$_fulfill(value) { + if (this._isFollowingOrFulfilledOrRejected()) return; + this._fulfillUnchecked(value); +}; + +Promise.prototype._reject = +function Promise$_reject(reason, carriedStackTrace) { + if (this._isFollowingOrFulfilledOrRejected()) return; + this._rejectUnchecked(reason, carriedStackTrace); +}; + +Promise.prototype._settlePromiseAt = function Promise$_settlePromiseAt(index) { + var handler = this.isFulfilled() + ? this._fulfillmentHandlerAt(index) + : this._rejectionHandlerAt(index); + + var value = this._settledValue; + var receiver = this._receiverAt(index); + var promise = this._promiseAt(index); + + if (typeof handler === "function") { + this._settlePromiseFromHandler(handler, receiver, value, promise); + } else { + var done = false; + var isFulfilled = this.isFulfilled(); + if (receiver !== void 0) { + if (receiver instanceof Promise && + receiver._isProxied()) { + receiver._unsetProxied(); + + if (isFulfilled) receiver._fulfillUnchecked(value); + else receiver._rejectUnchecked(value, + this._getCarriedStackTrace()); + done = true; + } else if (receiver instanceof PromiseArray) { + if (isFulfilled) receiver._promiseFulfilled(value, promise); + else receiver._promiseRejected(value, promise); + done = true; + } + } + + if (!done) { + if (isFulfilled) promise._fulfill(value); + else promise._reject(value, this._getCarriedStackTrace()); + } + } + + if (index >= 4) { + this._queueGC(); + } +}; + +Promise.prototype._isProxied = function Promise$_isProxied() { + return (this._bitField & 4194304) === 4194304; +}; + +Promise.prototype._setProxied = function Promise$_setProxied() { + this._bitField = this._bitField | 4194304; +}; + +Promise.prototype._unsetProxied = function Promise$_unsetProxied() { + this._bitField = this._bitField & (~4194304); +}; + +Promise.prototype._isGcQueued = function Promise$_isGcQueued() { + return (this._bitField & -1073741824) === -1073741824; +}; + +Promise.prototype._setGcQueued = function Promise$_setGcQueued() { + this._bitField = this._bitField | -1073741824; +}; + +Promise.prototype._unsetGcQueued = function Promise$_unsetGcQueued() { + this._bitField = this._bitField & (~-1073741824); +}; + +Promise.prototype._queueGC = function Promise$_queueGC() { + if (this._isGcQueued()) return; + this._setGcQueued(); + async.invokeLater(this._gc, this, void 0); +}; + +Promise.prototype._gc = function Promise$gc() { + var len = this._length() * 5 - 5; + for (var i = 0; i < len; i++) { + delete this[i]; + } + this._clearFirstHandlerData(); + this._setLength(0); + this._unsetGcQueued(); +}; + +Promise.prototype._clearFirstHandlerData = +function Promise$_clearFirstHandlerData() { + this._fulfillmentHandler0 = void 0; + this._rejectionHandler0 = void 0; + this._promise0 = void 0; + this._receiver0 = void 0; +}; + +Promise.prototype._queueSettleAt = function Promise$_queueSettleAt(index) { + if (this._isRejectionUnhandled()) this._unsetRejectionIsUnhandled(); + async.invoke(this._settlePromiseAt, this, index); +}; + +Promise.prototype._fulfillUnchecked = +function Promise$_fulfillUnchecked(value) { + if (!this.isPending()) return; + if (value === this) { + var err = makeSelfResolutionError(); + this._attachExtraTrace(err); + return this._rejectUnchecked(err, void 0); + } + this._cleanValues(); + this._setFulfilled(); + this._settledValue = value; + var len = this._length(); + + if (len > 0) { + async.invoke(this._settlePromises, this, len); + } +}; + +Promise.prototype._rejectUncheckedCheckError = +function Promise$_rejectUncheckedCheckError(reason) { + var trace = canAttach(reason) ? reason : new Error(reason + ""); + this._rejectUnchecked(reason, trace === reason ? void 0 : trace); +}; + +Promise.prototype._rejectUnchecked = +function Promise$_rejectUnchecked(reason, trace) { + if (!this.isPending()) return; + if (reason === this) { + var err = makeSelfResolutionError(); + this._attachExtraTrace(err); + return this._rejectUnchecked(err); + } + this._cleanValues(); + this._setRejected(); + this._settledValue = reason; + + if (this._isFinal()) { + async.invokeLater(thrower, void 0, trace === void 0 ? reason : trace); + return; + } + var len = this._length(); + + if (trace !== void 0) this._setCarriedStackTrace(trace); + + if (len > 0) { + async.invoke(this._rejectPromises, this, null); + } else { + this._ensurePossibleRejectionHandled(); + } +}; + +Promise.prototype._rejectPromises = function Promise$_rejectPromises() { + this._settlePromises(); + this._unsetCarriedStackTrace(); +}; + +Promise.prototype._settlePromises = function Promise$_settlePromises() { + var len = this._length(); + for (var i = 0; i < len; i++) { + this._settlePromiseAt(i); + } +}; + +Promise.prototype._ensurePossibleRejectionHandled = +function Promise$_ensurePossibleRejectionHandled() { + this._setRejectionIsUnhandled(); + if (CapturedTrace.possiblyUnhandledRejection !== void 0) { + async.invokeLater(this._notifyUnhandledRejection, this, void 0); + } +}; + +Promise.prototype._notifyUnhandledRejectionIsHandled = +function Promise$_notifyUnhandledRejectionIsHandled() { + if (typeof unhandledRejectionHandled === "function") { + async.invokeLater(unhandledRejectionHandled, void 0, this); + } +}; + +Promise.prototype._notifyUnhandledRejection = +function Promise$_notifyUnhandledRejection() { + if (this._isRejectionUnhandled()) { + var reason = this._settledValue; + var trace = this._getCarriedStackTrace(); + + this._setUnhandledRejectionIsNotified(); + + if (trace !== void 0) { + this._unsetCarriedStackTrace(); + reason = trace; + } + if (typeof CapturedTrace.possiblyUnhandledRejection === "function") { + CapturedTrace.possiblyUnhandledRejection(reason, this); + } + } +}; + +var contextStack = []; +Promise.prototype._peekContext = function Promise$_peekContext() { + var lastIndex = contextStack.length - 1; + if (lastIndex >= 0) { + return contextStack[lastIndex]; + } + return void 0; + +}; + +Promise.prototype._pushContext = function Promise$_pushContext() { + if (!debugging) return; + contextStack.push(this); +}; + +Promise.prototype._popContext = function Promise$_popContext() { + if (!debugging) return; + contextStack.pop(); +}; + +Promise.noConflict = function Promise$NoConflict() { + return noConflict(Promise); +}; + +Promise.setScheduler = function(fn) { + if (typeof fn !== "function") throw new TypeError("fn must be a function"); + async._schedule = fn; +}; + +if (!CapturedTrace.isSupported()) { + Promise.longStackTraces = function(){}; + debugging = false; +} + +Promise._makeSelfResolutionError = makeSelfResolutionError; +require("./finally.js")(Promise, NEXT_FILTER, cast); +require("./direct_resolve.js")(Promise); +require("./synchronous_inspection.js")(Promise); +require("./join.js")(Promise, PromiseArray, cast, INTERNAL); +Promise.RangeError = RangeError; +Promise.CancellationError = CancellationError; +Promise.TimeoutError = TimeoutError; +Promise.TypeError = TypeError; +Promise.OperationalError = OperationalError; +Promise.RejectionError = OperationalError; +Promise.AggregateError = errors.AggregateError; + +util.toFastProperties(Promise); +util.toFastProperties(Promise.prototype); +Promise.Promise = Promise; +require('./timers.js')(Promise,INTERNAL,cast); +require('./race.js')(Promise,INTERNAL,cast); +require('./call_get.js')(Promise); +require('./generators.js')(Promise,apiRejection,INTERNAL,cast); +require('./map.js')(Promise,PromiseArray,apiRejection,cast,INTERNAL); +require('./nodeify.js')(Promise); +require('./promisify.js')(Promise,INTERNAL); +require('./props.js')(Promise,PromiseArray,cast); +require('./reduce.js')(Promise,PromiseArray,apiRejection,cast,INTERNAL); +require('./settle.js')(Promise,PromiseArray); +require('./some.js')(Promise,PromiseArray,apiRejection); +require('./progress.js')(Promise,PromiseArray); +require('./cancel.js')(Promise,INTERNAL); +require('./filter.js')(Promise,INTERNAL); +require('./any.js')(Promise,PromiseArray); +require('./each.js')(Promise,INTERNAL); +require('./using.js')(Promise,apiRejection,cast); + +Promise.prototype = Promise.prototype; +return Promise; + +}; + +},{"./any.js":1,"./async.js":2,"./call_get.js":4,"./cancel.js":5,"./captured_trace.js":6,"./catch_filter.js":7,"./direct_resolve.js":8,"./each.js":9,"./errors.js":10,"./errors_api_rejection":11,"./filter.js":13,"./finally.js":14,"./generators.js":15,"./join.js":16,"./map.js":17,"./nodeify.js":18,"./progress.js":19,"./promise_array.js":21,"./promise_resolver.js":22,"./promisify.js":23,"./props.js":24,"./race.js":26,"./reduce.js":27,"./settle.js":29,"./some.js":30,"./synchronous_inspection.js":31,"./thenables.js":32,"./timers.js":33,"./using.js":34,"./util.js":35}],21:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise, INTERNAL, cast) { +var canAttach = require("./errors.js").canAttach; +var util = require("./util.js"); +var isArray = util.isArray; + +function toResolutionValue(val) { + switch(val) { + case -1: return void 0; + case -2: return []; + case -3: return {}; + } +} + +function PromiseArray(values) { + var promise = this._promise = new Promise(INTERNAL); + var parent = void 0; + if (values instanceof Promise) { + parent = values; + promise._propagateFrom(parent, 1 | 4); + } + promise._setTrace(parent); + this._values = values; + this._length = 0; + this._totalResolved = 0; + this._init(void 0, -2); +} +PromiseArray.prototype.length = function PromiseArray$length() { + return this._length; +}; + +PromiseArray.prototype.promise = function PromiseArray$promise() { + return this._promise; +}; + +PromiseArray.prototype._init = +function PromiseArray$_init(_, resolveValueIfEmpty) { + var values = cast(this._values, void 0); + if (values instanceof Promise) { + this._values = values; + values._setBoundTo(this._promise._boundTo); + if (values.isFulfilled()) { + values = values._settledValue; + if (!isArray(values)) { + var err = new Promise.TypeError("expecting an array, a promise or a thenable"); + this.__hardReject__(err); + return; + } + } else if (values.isPending()) { + values._then( + PromiseArray$_init, + this._reject, + void 0, + this, + resolveValueIfEmpty + ); + return; + } else { + values._unsetRejectionIsUnhandled(); + this._reject(values._settledValue); + return; + } + } else if (!isArray(values)) { + var err = new Promise.TypeError("expecting an array, a promise or a thenable"); + this.__hardReject__(err); + return; + } + + if (values.length === 0) { + if (resolveValueIfEmpty === -5) { + this._resolveEmptyArray(); + } + else { + this._resolve(toResolutionValue(resolveValueIfEmpty)); + } + return; + } + var len = this.getActualLength(values.length); + var newLen = len; + var newValues = this.shouldCopyValues() ? new Array(len) : this._values; + var isDirectScanNeeded = false; + for (var i = 0; i < len; ++i) { + var maybePromise = cast(values[i], void 0); + if (maybePromise instanceof Promise) { + if (maybePromise.isPending()) { + maybePromise._proxyPromiseArray(this, i); + } else { + maybePromise._unsetRejectionIsUnhandled(); + isDirectScanNeeded = true; + } + } else { + isDirectScanNeeded = true; + } + newValues[i] = maybePromise; + } + this._values = newValues; + this._length = newLen; + if (isDirectScanNeeded) { + this._scanDirectValues(len); + } +}; + +PromiseArray.prototype._settlePromiseAt = +function PromiseArray$_settlePromiseAt(index) { + var value = this._values[index]; + if (!(value instanceof Promise)) { + this._promiseFulfilled(value, index); + } else if (value.isFulfilled()) { + this._promiseFulfilled(value._settledValue, index); + } else if (value.isRejected()) { + this._promiseRejected(value._settledValue, index); + } +}; + +PromiseArray.prototype._scanDirectValues = +function PromiseArray$_scanDirectValues(len) { + for (var i = 0; i < len; ++i) { + if (this._isResolved()) { + break; + } + this._settlePromiseAt(i); + } +}; + +PromiseArray.prototype._isResolved = function PromiseArray$_isResolved() { + return this._values === null; +}; + +PromiseArray.prototype._resolve = function PromiseArray$_resolve(value) { + this._values = null; + this._promise._fulfill(value); +}; + +PromiseArray.prototype.__hardReject__ = +PromiseArray.prototype._reject = function PromiseArray$_reject(reason) { + this._values = null; + var trace = canAttach(reason) ? reason : new Error(reason + ""); + this._promise._attachExtraTrace(trace); + this._promise._reject(reason, trace); +}; + +PromiseArray.prototype._promiseProgressed = +function PromiseArray$_promiseProgressed(progressValue, index) { + if (this._isResolved()) return; + this._promise._progress({ + index: index, + value: progressValue + }); +}; + + +PromiseArray.prototype._promiseFulfilled = +function PromiseArray$_promiseFulfilled(value, index) { + if (this._isResolved()) return; + this._values[index] = value; + var totalResolved = ++this._totalResolved; + if (totalResolved >= this._length) { + this._resolve(this._values); + } +}; + +PromiseArray.prototype._promiseRejected = +function PromiseArray$_promiseRejected(reason, index) { + if (this._isResolved()) return; + this._totalResolved++; + this._reject(reason); +}; + +PromiseArray.prototype.shouldCopyValues = +function PromiseArray$_shouldCopyValues() { + return true; +}; + +PromiseArray.prototype.getActualLength = +function PromiseArray$getActualLength(len) { + return len; +}; + +return PromiseArray; +}; + +},{"./errors.js":10,"./util.js":35}],22:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +var util = require("./util.js"); +var maybeWrapAsError = util.maybeWrapAsError; +var errors = require("./errors.js"); +var TimeoutError = errors.TimeoutError; +var OperationalError = errors.OperationalError; +var async = require("./async.js"); +var haveGetters = util.haveGetters; +var es5 = require("./es5.js"); + +function isUntypedError(obj) { + return obj instanceof Error && + es5.getPrototypeOf(obj) === Error.prototype; +} + +function wrapAsOperationalError(obj) { + var ret; + if (isUntypedError(obj)) { + ret = new OperationalError(obj); + } else { + ret = obj; + } + errors.markAsOriginatingFromRejection(ret); + return ret; +} + +function nodebackForPromise(promise) { + function PromiseResolver$_callback(err, value) { + if (promise === null) return; + + if (err) { + var wrapped = wrapAsOperationalError(maybeWrapAsError(err)); + promise._attachExtraTrace(wrapped); + promise._reject(wrapped); + } else if (arguments.length > 2) { + var $_len = arguments.length;var args = new Array($_len - 1); for(var $_i = 1; $_i < $_len; ++$_i) {args[$_i - 1] = arguments[$_i];} + promise._fulfill(args); + } else { + promise._fulfill(value); + } + + promise = null; + } + return PromiseResolver$_callback; +} + + +var PromiseResolver; +if (!haveGetters) { + PromiseResolver = function PromiseResolver(promise) { + this.promise = promise; + this.asCallback = nodebackForPromise(promise); + this.callback = this.asCallback; + }; +} +else { + PromiseResolver = function PromiseResolver(promise) { + this.promise = promise; + }; +} +if (haveGetters) { + var prop = { + get: function() { + return nodebackForPromise(this.promise); + } + }; + es5.defineProperty(PromiseResolver.prototype, "asCallback", prop); + es5.defineProperty(PromiseResolver.prototype, "callback", prop); +} + +PromiseResolver._nodebackForPromise = nodebackForPromise; + +PromiseResolver.prototype.toString = function PromiseResolver$toString() { + return "[object PromiseResolver]"; +}; + +PromiseResolver.prototype.resolve = +PromiseResolver.prototype.fulfill = function PromiseResolver$resolve(value) { + if (!(this instanceof PromiseResolver)) { + throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead."); + } + + var promise = this.promise; + if (promise._tryFollow(value)) { + return; + } + async.invoke(promise._fulfill, promise, value); +}; + +PromiseResolver.prototype.reject = function PromiseResolver$reject(reason) { + if (!(this instanceof PromiseResolver)) { + throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead."); + } + + var promise = this.promise; + errors.markAsOriginatingFromRejection(reason); + var trace = errors.canAttach(reason) ? reason : new Error(reason + ""); + promise._attachExtraTrace(trace); + async.invoke(promise._reject, promise, reason); + if (trace !== reason) { + async.invoke(this._setCarriedStackTrace, this, trace); + } +}; + +PromiseResolver.prototype.progress = +function PromiseResolver$progress(value) { + if (!(this instanceof PromiseResolver)) { + throw new TypeError("Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead."); + } + async.invoke(this.promise._progress, this.promise, value); +}; + +PromiseResolver.prototype.cancel = function PromiseResolver$cancel() { + async.invoke(this.promise.cancel, this.promise, void 0); +}; + +PromiseResolver.prototype.timeout = function PromiseResolver$timeout() { + this.reject(new TimeoutError("timeout")); +}; + +PromiseResolver.prototype.isResolved = function PromiseResolver$isResolved() { + return this.promise.isResolved(); +}; + +PromiseResolver.prototype.toJSON = function PromiseResolver$toJSON() { + return this.promise.toJSON(); +}; + +PromiseResolver.prototype._setCarriedStackTrace = +function PromiseResolver$_setCarriedStackTrace(trace) { + if (this.promise.isRejected()) { + this.promise._setCarriedStackTrace(trace); + } +}; + +module.exports = PromiseResolver; + +},{"./async.js":2,"./errors.js":10,"./es5.js":12,"./util.js":35}],23:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise, INTERNAL) { +var THIS = {}; +var util = require("./util.js"); +var nodebackForPromise = require("./promise_resolver.js") + ._nodebackForPromise; +var withAppended = util.withAppended; +var maybeWrapAsError = util.maybeWrapAsError; +var canEvaluate = util.canEvaluate; +var TypeError = require("./errors").TypeError; +var defaultSuffix = "Async"; +var defaultFilter = function(name, func) { + return util.isIdentifier(name) && + name.charAt(0) !== "_" && + !util.isClass(func); +}; +var defaultPromisified = {__isPromisified__: true}; + + +function escapeIdentRegex(str) { + return str.replace(/([$])/, "\\$"); +} + +function isPromisified(fn) { + try { + return fn.__isPromisified__ === true; + } + catch (e) { + return false; + } +} + +function hasPromisified(obj, key, suffix) { + var val = util.getDataPropertyOrDefault(obj, key + suffix, + defaultPromisified); + return val ? isPromisified(val) : false; +} +function checkValid(ret, suffix, suffixRegexp) { + for (var i = 0; i < ret.length; i += 2) { + var key = ret[i]; + if (suffixRegexp.test(key)) { + var keyWithoutAsyncSuffix = key.replace(suffixRegexp, ""); + for (var j = 0; j < ret.length; j += 2) { + if (ret[j] === keyWithoutAsyncSuffix) { + throw new TypeError("Cannot promisify an API " + + "that has normal methods with '"+suffix+"'-suffix"); + } + } + } + } +} + +function promisifiableMethods(obj, suffix, suffixRegexp, filter) { + var keys = util.inheritedDataKeys(obj); + var ret = []; + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + var value = obj[key]; + if (typeof value === "function" && + !isPromisified(value) && + !hasPromisified(obj, key, suffix) && + filter(key, value, obj)) { + ret.push(key, value); + } + } + checkValid(ret, suffix, suffixRegexp); + return ret; +} + +function switchCaseArgumentOrder(likelyArgumentCount) { + var ret = [likelyArgumentCount]; + var min = Math.max(0, likelyArgumentCount - 1 - 5); + for(var i = likelyArgumentCount - 1; i >= min; --i) { + if (i === likelyArgumentCount) continue; + ret.push(i); + } + for(var i = likelyArgumentCount + 1; i <= 5; ++i) { + ret.push(i); + } + return ret; +} + +function argumentSequence(argumentCount) { + return util.filledRange(argumentCount, "arguments[", "]"); +} + +function parameterDeclaration(parameterCount) { + return util.filledRange(parameterCount, "_arg", ""); +} + +function parameterCount(fn) { + if (typeof fn.length === "number") { + return Math.max(Math.min(fn.length, 1023 + 1), 0); + } + return 0; +} + +function generatePropertyAccess(key) { + if (util.isIdentifier(key)) { + return "." + key; + } + else return "['" + key.replace(/(['\\])/g, "\\$1") + "']"; +} + +function makeNodePromisifiedEval(callback, receiver, originalName, fn, suffix) { + var newParameterCount = Math.max(0, parameterCount(fn) - 1); + var argumentOrder = switchCaseArgumentOrder(newParameterCount); + var callbackName = + (typeof originalName === "string" && util.isIdentifier(originalName) + ? originalName + suffix + : "promisified"); + + function generateCallForArgumentCount(count) { + var args = argumentSequence(count).join(", "); + var comma = count > 0 ? ", " : ""; + var ret; + if (typeof callback === "string") { + ret = " \n\ + this.method({{args}}, fn); \n\ + break; \n\ + ".replace(".method", generatePropertyAccess(callback)); + } else if (receiver === THIS) { + ret = " \n\ + callback.call(this, {{args}}, fn); \n\ + break; \n\ + "; + } else if (receiver !== void 0) { + ret = " \n\ + callback.call(receiver, {{args}}, fn); \n\ + break; \n\ + "; + } else { + ret = " \n\ + callback({{args}}, fn); \n\ + break; \n\ + "; + } + return ret.replace("{{args}}", args).replace(", ", comma); + } + + function generateArgumentSwitchCase() { + var ret = ""; + for(var i = 0; i < argumentOrder.length; ++i) { + ret += "case " + argumentOrder[i] +":" + + generateCallForArgumentCount(argumentOrder[i]); + } + var codeForCall; + if (typeof callback === "string") { + codeForCall = " \n\ + this.property.apply(this, args); \n\ + " + .replace(".property", generatePropertyAccess(callback)); + } else if (receiver === THIS) { + codeForCall = " \n\ + callback.apply(this, args); \n\ + "; + } else { + codeForCall = " \n\ + callback.apply(receiver, args); \n\ + "; + } + + ret += " \n\ + default: \n\ + var args = new Array(len + 1); \n\ + var i = 0; \n\ + for (var i = 0; i < len; ++i) { \n\ + args[i] = arguments[i]; \n\ + } \n\ + args[i] = fn; \n\ + [CodeForCall] \n\ + break; \n\ + ".replace("[CodeForCall]", codeForCall); + return ret; + } + + return new Function("Promise", + "callback", + "receiver", + "withAppended", + "maybeWrapAsError", + "nodebackForPromise", + "INTERNAL"," \n\ + var ret = function FunctionName(Parameters) { \n\ + 'use strict'; \n\ + var len = arguments.length; \n\ + var promise = new Promise(INTERNAL); \n\ + promise._setTrace(void 0); \n\ + var fn = nodebackForPromise(promise); \n\ + try { \n\ + switch(len) { \n\ + [CodeForSwitchCase] \n\ + } \n\ + } catch (e) { \n\ + var wrapped = maybeWrapAsError(e); \n\ + promise._attachExtraTrace(wrapped); \n\ + promise._reject(wrapped); \n\ + } \n\ + return promise; \n\ + }; \n\ + ret.__isPromisified__ = true; \n\ + return ret; \n\ + " + .replace("FunctionName", callbackName) + .replace("Parameters", parameterDeclaration(newParameterCount)) + .replace("[CodeForSwitchCase]", generateArgumentSwitchCase()))( + Promise, + callback, + receiver, + withAppended, + maybeWrapAsError, + nodebackForPromise, + INTERNAL + ); +} + +function makeNodePromisifiedClosure(callback, receiver) { + function promisified() { + var _receiver = receiver; + if (receiver === THIS) _receiver = this; + if (typeof callback === "string") { + callback = _receiver[callback]; + } + var promise = new Promise(INTERNAL); + promise._setTrace(void 0); + var fn = nodebackForPromise(promise); + try { + callback.apply(_receiver, withAppended(arguments, fn)); + } catch(e) { + var wrapped = maybeWrapAsError(e); + promise._attachExtraTrace(wrapped); + promise._reject(wrapped); + } + return promise; + } + promisified.__isPromisified__ = true; + return promisified; +} + +var makeNodePromisified = canEvaluate + ? makeNodePromisifiedEval + : makeNodePromisifiedClosure; + +function promisifyAll(obj, suffix, filter, promisifier) { + var suffixRegexp = new RegExp(escapeIdentRegex(suffix) + "$"); + var methods = + promisifiableMethods(obj, suffix, suffixRegexp, filter); + + for (var i = 0, len = methods.length; i < len; i+= 2) { + var key = methods[i]; + var fn = methods[i+1]; + var promisifiedKey = key + suffix; + obj[promisifiedKey] = promisifier === makeNodePromisified + ? makeNodePromisified(key, THIS, key, fn, suffix) + : promisifier(fn); + } + util.toFastProperties(obj); + return obj; +} + +function promisify(callback, receiver) { + return makeNodePromisified(callback, receiver, void 0, callback); +} + +Promise.promisify = function Promise$Promisify(fn, receiver) { + if (typeof fn !== "function") { + throw new TypeError("fn must be a function"); + } + if (isPromisified(fn)) { + return fn; + } + return promisify(fn, arguments.length < 2 ? THIS : receiver); +}; + +Promise.promisifyAll = function Promise$PromisifyAll(target, options) { + if (typeof target !== "function" && typeof target !== "object") { + throw new TypeError("the target of promisifyAll must be an object or a function"); + } + options = Object(options); + var suffix = options.suffix; + if (typeof suffix !== "string") suffix = defaultSuffix; + var filter = options.filter; + if (typeof filter !== "function") filter = defaultFilter; + var promisifier = options.promisifier; + if (typeof promisifier !== "function") promisifier = makeNodePromisified; + + if (!util.isIdentifier(suffix)) { + throw new RangeError("suffix must be a valid identifier"); + } + + var keys = util.inheritedDataKeys(target, {includeHidden: true}); + for (var i = 0; i < keys.length; ++i) { + var value = target[keys[i]]; + if (keys[i] !== "constructor" && + util.isClass(value)) { + promisifyAll(value.prototype, suffix, filter, promisifier); + promisifyAll(value, suffix, filter, promisifier); + } + } + + return promisifyAll(target, suffix, filter, promisifier); +}; +}; + + +},{"./errors":10,"./promise_resolver.js":22,"./util.js":35}],24:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise, PromiseArray, cast) { +var util = require("./util.js"); +var apiRejection = require("./errors_api_rejection")(Promise); +var isObject = util.isObject; +var es5 = require("./es5.js"); + +function PropertiesPromiseArray(obj) { + var keys = es5.keys(obj); + var len = keys.length; + var values = new Array(len * 2); + for (var i = 0; i < len; ++i) { + var key = keys[i]; + values[i] = obj[key]; + values[i + len] = key; + } + this.constructor$(values); +} +util.inherits(PropertiesPromiseArray, PromiseArray); + +PropertiesPromiseArray.prototype._init = +function PropertiesPromiseArray$_init() { + this._init$(void 0, -3) ; +}; + +PropertiesPromiseArray.prototype._promiseFulfilled = +function PropertiesPromiseArray$_promiseFulfilled(value, index) { + if (this._isResolved()) return; + this._values[index] = value; + var totalResolved = ++this._totalResolved; + if (totalResolved >= this._length) { + var val = {}; + var keyOffset = this.length(); + for (var i = 0, len = this.length(); i < len; ++i) { + val[this._values[i + keyOffset]] = this._values[i]; + } + this._resolve(val); + } +}; + +PropertiesPromiseArray.prototype._promiseProgressed = +function PropertiesPromiseArray$_promiseProgressed(value, index) { + if (this._isResolved()) return; + + this._promise._progress({ + key: this._values[index + this.length()], + value: value + }); +}; + +PropertiesPromiseArray.prototype.shouldCopyValues = +function PropertiesPromiseArray$_shouldCopyValues() { + return false; +}; + +PropertiesPromiseArray.prototype.getActualLength = +function PropertiesPromiseArray$getActualLength(len) { + return len >> 1; +}; + +function Promise$_Props(promises) { + var ret; + var castValue = cast(promises, void 0); + + if (!isObject(castValue)) { + return apiRejection("cannot await properties of a non-object"); + } else if (castValue instanceof Promise) { + ret = castValue._then(Promise.props, void 0, void 0, void 0, void 0); + } else { + ret = new PropertiesPromiseArray(castValue).promise(); + } + + if (castValue instanceof Promise) { + ret._propagateFrom(castValue, 4); + } + return ret; +} + +Promise.prototype.props = function Promise$props() { + return Promise$_Props(this); +}; + +Promise.props = function Promise$Props(promises) { + return Promise$_Props(promises); +}; +}; + +},{"./errors_api_rejection":11,"./es5.js":12,"./util.js":35}],25:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +function arrayCopy(src, srcIndex, dst, dstIndex, len) { + for (var j = 0; j < len; ++j) { + dst[j + dstIndex] = src[j + srcIndex]; + } +} + +function Queue(capacity) { + this._capacity = capacity; + this._length = 0; + this._front = 0; + this._makeCapacity(); +} + +Queue.prototype._willBeOverCapacity = +function Queue$_willBeOverCapacity(size) { + return this._capacity < size; +}; + +Queue.prototype._pushOne = function Queue$_pushOne(arg) { + var length = this.length(); + this._checkCapacity(length + 1); + var i = (this._front + length) & (this._capacity - 1); + this[i] = arg; + this._length = length + 1; +}; + +Queue.prototype.push = function Queue$push(fn, receiver, arg) { + var length = this.length() + 3; + if (this._willBeOverCapacity(length)) { + this._pushOne(fn); + this._pushOne(receiver); + this._pushOne(arg); + return; + } + var j = this._front + length - 3; + this._checkCapacity(length); + var wrapMask = this._capacity - 1; + this[(j + 0) & wrapMask] = fn; + this[(j + 1) & wrapMask] = receiver; + this[(j + 2) & wrapMask] = arg; + this._length = length; +}; + +Queue.prototype.shift = function Queue$shift() { + var front = this._front, + ret = this[front]; + + this[front] = void 0; + this._front = (front + 1) & (this._capacity - 1); + this._length--; + return ret; +}; + +Queue.prototype.length = function Queue$length() { + return this._length; +}; + +Queue.prototype._makeCapacity = function Queue$_makeCapacity() { + var len = this._capacity; + for (var i = 0; i < len; ++i) { + this[i] = void 0; + } +}; + +Queue.prototype._checkCapacity = function Queue$_checkCapacity(size) { + if (this._capacity < size) { + this._resizeTo(this._capacity << 3); + } +}; + +Queue.prototype._resizeTo = function Queue$_resizeTo(capacity) { + var oldFront = this._front; + var oldCapacity = this._capacity; + var oldQueue = new Array(oldCapacity); + var length = this.length(); + + arrayCopy(this, 0, oldQueue, 0, oldCapacity); + this._capacity = capacity; + this._makeCapacity(); + this._front = 0; + if (oldFront + length <= oldCapacity) { + arrayCopy(oldQueue, oldFront, this, 0, length); + } else { var lengthBeforeWrapping = + length - ((oldFront + length) & (oldCapacity - 1)); + + arrayCopy(oldQueue, oldFront, this, 0, lengthBeforeWrapping); + arrayCopy(oldQueue, 0, this, lengthBeforeWrapping, + length - lengthBeforeWrapping); + } +}; + +module.exports = Queue; + +},{}],26:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise, INTERNAL, cast) { +var apiRejection = require("./errors_api_rejection.js")(Promise); +var isArray = require("./util.js").isArray; + +var raceLater = function Promise$_raceLater(promise) { + return promise.then(function(array) { + return Promise$_Race(array, promise); + }); +}; + +var hasOwn = {}.hasOwnProperty; +function Promise$_Race(promises, parent) { + var maybePromise = cast(promises, void 0); + + if (maybePromise instanceof Promise) { + return raceLater(maybePromise); + } else if (!isArray(promises)) { + return apiRejection("expecting an array, a promise or a thenable"); + } + + var ret = new Promise(INTERNAL); + if (parent !== void 0) { + ret._propagateFrom(parent, 7); + } else { + ret._setTrace(void 0); + } + var fulfill = ret._fulfill; + var reject = ret._reject; + for (var i = 0, len = promises.length; i < len; ++i) { + var val = promises[i]; + + if (val === void 0 && !(hasOwn.call(promises, i))) { + continue; + } + + Promise.cast(val)._then(fulfill, reject, void 0, ret, null); + } + return ret; +} + +Promise.race = function Promise$Race(promises) { + return Promise$_Race(promises, void 0); +}; + +Promise.prototype.race = function Promise$race() { + return Promise$_Race(this, void 0); +}; + +}; + +},{"./errors_api_rejection.js":11,"./util.js":35}],27:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise, PromiseArray, apiRejection, cast, INTERNAL) { +var util = require("./util.js"); +var tryCatch4 = util.tryCatch4; +var tryCatch3 = util.tryCatch3; +var errorObj = util.errorObj; +function ReductionPromiseArray(promises, fn, accum, _each) { + this.constructor$(promises); + this._preservedValues = _each === INTERNAL ? [] : null; + this._zerothIsAccum = (accum === void 0); + this._gotAccum = false; + this._reducingIndex = (this._zerothIsAccum ? 1 : 0); + this._valuesPhase = undefined; + + var maybePromise = cast(accum, void 0); + var rejected = false; + var isPromise = maybePromise instanceof Promise; + if (isPromise) { + if (maybePromise.isPending()) { + maybePromise._proxyPromiseArray(this, -1); + } else if (maybePromise.isFulfilled()) { + accum = maybePromise.value(); + this._gotAccum = true; + } else { + maybePromise._unsetRejectionIsUnhandled(); + this._reject(maybePromise.reason()); + rejected = true; + } + } + if (!(isPromise || this._zerothIsAccum)) this._gotAccum = true; + this._callback = fn; + this._accum = accum; + if (!rejected) this._init$(void 0, -5); +} +util.inherits(ReductionPromiseArray, PromiseArray); + +ReductionPromiseArray.prototype._init = +function ReductionPromiseArray$_init() {}; + +ReductionPromiseArray.prototype._resolveEmptyArray = +function ReductionPromiseArray$_resolveEmptyArray() { + if (this._gotAccum || this._zerothIsAccum) { + this._resolve(this._preservedValues !== null + ? [] : this._accum); + } +}; + +ReductionPromiseArray.prototype._promiseFulfilled = +function ReductionPromiseArray$_promiseFulfilled(value, index) { + var values = this._values; + if (values === null) return; + var length = this.length(); + var preservedValues = this._preservedValues; + var isEach = preservedValues !== null; + var gotAccum = this._gotAccum; + var valuesPhase = this._valuesPhase; + var valuesPhaseIndex; + if (!valuesPhase) { + valuesPhase = this._valuesPhase = Array(length); + for (valuesPhaseIndex=0; valuesPhaseIndex + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +var schedule; +var _MutationObserver; +if (typeof process === "object" && typeof process.version === "string") { + schedule = function Promise$_Scheduler(fn) { + process.nextTick(fn); + }; +} +else if ((typeof MutationObserver !== "undefined" && + (_MutationObserver = MutationObserver)) || + (typeof WebKitMutationObserver !== "undefined" && + (_MutationObserver = WebKitMutationObserver))) { + schedule = (function() { + var div = document.createElement("div"); + var queuedFn = void 0; + var observer = new _MutationObserver( + function Promise$_Scheduler() { + var fn = queuedFn; + queuedFn = void 0; + fn(); + } + ); + observer.observe(div, { + attributes: true + }); + return function Promise$_Scheduler(fn) { + queuedFn = fn; + div.classList.toggle("foo"); + }; + + })(); +} +else if (typeof setTimeout !== "undefined") { + schedule = function Promise$_Scheduler(fn) { + setTimeout(fn, 0); + }; +} +else throw new Error("no async scheduler available"); +module.exports = schedule; + +},{}],29:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = + function(Promise, PromiseArray) { +var PromiseInspection = Promise.PromiseInspection; +var util = require("./util.js"); + +function SettledPromiseArray(values) { + this.constructor$(values); +} +util.inherits(SettledPromiseArray, PromiseArray); + +SettledPromiseArray.prototype._promiseResolved = +function SettledPromiseArray$_promiseResolved(index, inspection) { + this._values[index] = inspection; + var totalResolved = ++this._totalResolved; + if (totalResolved >= this._length) { + this._resolve(this._values); + } +}; + +SettledPromiseArray.prototype._promiseFulfilled = +function SettledPromiseArray$_promiseFulfilled(value, index) { + if (this._isResolved()) return; + var ret = new PromiseInspection(); + ret._bitField = 268435456; + ret._settledValue = value; + this._promiseResolved(index, ret); +}; +SettledPromiseArray.prototype._promiseRejected = +function SettledPromiseArray$_promiseRejected(reason, index) { + if (this._isResolved()) return; + var ret = new PromiseInspection(); + ret._bitField = 134217728; + ret._settledValue = reason; + this._promiseResolved(index, ret); +}; + +Promise.settle = function Promise$Settle(promises) { + return new SettledPromiseArray(promises).promise(); +}; + +Promise.prototype.settle = function Promise$settle() { + return new SettledPromiseArray(this).promise(); +}; +}; + +},{"./util.js":35}],30:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = +function(Promise, PromiseArray, apiRejection) { +var util = require("./util.js"); +var RangeError = require("./errors.js").RangeError; +var AggregateError = require("./errors.js").AggregateError; +var isArray = util.isArray; + + +function SomePromiseArray(values) { + this.constructor$(values); + this._howMany = 0; + this._unwrap = false; + this._initialized = false; +} +util.inherits(SomePromiseArray, PromiseArray); + +SomePromiseArray.prototype._init = function SomePromiseArray$_init() { + if (!this._initialized) { + return; + } + if (this._howMany === 0) { + this._resolve([]); + return; + } + this._init$(void 0, -5); + var isArrayResolved = isArray(this._values); + if (!this._isResolved() && + isArrayResolved && + this._howMany > this._canPossiblyFulfill()) { + this._reject(this._getRangeError(this.length())); + } +}; + +SomePromiseArray.prototype.init = function SomePromiseArray$init() { + this._initialized = true; + this._init(); +}; + +SomePromiseArray.prototype.setUnwrap = function SomePromiseArray$setUnwrap() { + this._unwrap = true; +}; + +SomePromiseArray.prototype.howMany = function SomePromiseArray$howMany() { + return this._howMany; +}; + +SomePromiseArray.prototype.setHowMany = +function SomePromiseArray$setHowMany(count) { + if (this._isResolved()) return; + this._howMany = count; +}; + +SomePromiseArray.prototype._promiseFulfilled = +function SomePromiseArray$_promiseFulfilled(value) { + if (this._isResolved()) return; + this._addFulfilled(value); + if (this._fulfilled() === this.howMany()) { + this._values.length = this.howMany(); + if (this.howMany() === 1 && this._unwrap) { + this._resolve(this._values[0]); + } else { + this._resolve(this._values); + } + } + +}; +SomePromiseArray.prototype._promiseRejected = +function SomePromiseArray$_promiseRejected(reason) { + if (this._isResolved()) return; + this._addRejected(reason); + if (this.howMany() > this._canPossiblyFulfill()) { + var e = new AggregateError(); + for (var i = this.length(); i < this._values.length; ++i) { + e.push(this._values[i]); + } + this._reject(e); + } +}; + +SomePromiseArray.prototype._fulfilled = function SomePromiseArray$_fulfilled() { + return this._totalResolved; +}; + +SomePromiseArray.prototype._rejected = function SomePromiseArray$_rejected() { + return this._values.length - this.length(); +}; + +SomePromiseArray.prototype._addRejected = +function SomePromiseArray$_addRejected(reason) { + this._values.push(reason); +}; + +SomePromiseArray.prototype._addFulfilled = +function SomePromiseArray$_addFulfilled(value) { + this._values[this._totalResolved++] = value; +}; + +SomePromiseArray.prototype._canPossiblyFulfill = +function SomePromiseArray$_canPossiblyFulfill() { + return this.length() - this._rejected(); +}; + +SomePromiseArray.prototype._getRangeError = +function SomePromiseArray$_getRangeError(count) { + var message = "Input array must contain at least " + + this._howMany + " items but contains only " + count + " items"; + return new RangeError(message); +}; + +SomePromiseArray.prototype._resolveEmptyArray = +function SomePromiseArray$_resolveEmptyArray() { + this._reject(this._getRangeError(0)); +}; + +function Promise$_Some(promises, howMany) { + if ((howMany | 0) !== howMany || howMany < 0) { + return apiRejection("expecting a positive integer"); + } + var ret = new SomePromiseArray(promises); + var promise = ret.promise(); + if (promise.isRejected()) { + return promise; + } + ret.setHowMany(howMany); + ret.init(); + return promise; +} + +Promise.some = function Promise$Some(promises, howMany) { + return Promise$_Some(promises, howMany); +}; + +Promise.prototype.some = function Promise$some(howMany) { + return Promise$_Some(this, howMany); +}; + +Promise._SomePromiseArray = SomePromiseArray; +}; + +},{"./errors.js":10,"./util.js":35}],31:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise) { +function PromiseInspection(promise) { + if (promise !== void 0) { + this._bitField = promise._bitField; + this._settledValue = promise.isResolved() + ? promise._settledValue + : void 0; + } + else { + this._bitField = 0; + this._settledValue = void 0; + } +} + +PromiseInspection.prototype.isFulfilled = +Promise.prototype.isFulfilled = function Promise$isFulfilled() { + return (this._bitField & 268435456) > 0; +}; + +PromiseInspection.prototype.isRejected = +Promise.prototype.isRejected = function Promise$isRejected() { + return (this._bitField & 134217728) > 0; +}; + +PromiseInspection.prototype.isPending = +Promise.prototype.isPending = function Promise$isPending() { + return (this._bitField & 402653184) === 0; +}; + +PromiseInspection.prototype.value = +Promise.prototype.value = function Promise$value() { + if (!this.isFulfilled()) { + throw new TypeError("cannot get fulfillment value of a non-fulfilled promise"); + } + return this._settledValue; +}; + +PromiseInspection.prototype.error = +PromiseInspection.prototype.reason = +Promise.prototype.reason = function Promise$reason() { + if (!this.isRejected()) { + throw new TypeError("cannot get rejection reason of a non-rejected promise"); + } + return this._settledValue; +}; + +PromiseInspection.prototype.isResolved = +Promise.prototype.isResolved = function Promise$isResolved() { + return (this._bitField & 402653184) > 0; +}; + +Promise.PromiseInspection = PromiseInspection; +}; + +},{}],32:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function(Promise, INTERNAL) { +var util = require("./util.js"); +var canAttach = require("./errors.js").canAttach; +var errorObj = util.errorObj; +var isObject = util.isObject; + +function getThen(obj) { + try { + return obj.then; + } + catch(e) { + errorObj.e = e; + return errorObj; + } +} + +function Promise$_Cast(obj, originalPromise) { + if (isObject(obj)) { + if (obj instanceof Promise) { + return obj; + } + else if (isAnyBluebirdPromise(obj)) { + var ret = new Promise(INTERNAL); + ret._setTrace(void 0); + obj._then( + ret._fulfillUnchecked, + ret._rejectUncheckedCheckError, + ret._progressUnchecked, + ret, + null + ); + ret._setFollowing(); + return ret; + } + var then = getThen(obj); + if (then === errorObj) { + if (originalPromise !== void 0 && canAttach(then.e)) { + originalPromise._attachExtraTrace(then.e); + } + return Promise.reject(then.e); + } else if (typeof then === "function") { + return Promise$_doThenable(obj, then, originalPromise); + } + } + return obj; +} + +var hasProp = {}.hasOwnProperty; +function isAnyBluebirdPromise(obj) { + return hasProp.call(obj, "_promise0"); +} + +function Promise$_doThenable(x, then, originalPromise) { + var resolver = Promise.defer(); + var called = false; + try { + then.call( + x, + Promise$_resolveFromThenable, + Promise$_rejectFromThenable, + Promise$_progressFromThenable + ); + } catch(e) { + if (!called) { + called = true; + var trace = canAttach(e) ? e : new Error(e + ""); + if (originalPromise !== void 0) { + originalPromise._attachExtraTrace(trace); + } + resolver.promise._reject(e, trace); + } + } + return resolver.promise; + + function Promise$_resolveFromThenable(y) { + if (called) return; + called = true; + + if (x === y) { + var e = Promise._makeSelfResolutionError(); + if (originalPromise !== void 0) { + originalPromise._attachExtraTrace(e); + } + resolver.promise._reject(e, void 0); + return; + } + resolver.resolve(y); + } + + function Promise$_rejectFromThenable(r) { + if (called) return; + called = true; + var trace = canAttach(r) ? r : new Error(r + ""); + if (originalPromise !== void 0) { + originalPromise._attachExtraTrace(trace); + } + resolver.promise._reject(r, trace); + } + + function Promise$_progressFromThenable(v) { + if (called) return; + var promise = resolver.promise; + if (typeof promise._progress === "function") { + promise._progress(v); + } + } +} + +return Promise$_Cast; +}; + +},{"./errors.js":10,"./util.js":35}],33:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +var _setTimeout = function(fn, ms) { + var len = arguments.length; + var arg0 = arguments[2]; + var arg1 = arguments[3]; + var arg2 = len >= 5 ? arguments[4] : void 0; + return setTimeout(function() { + fn(arg0, arg1, arg2); + }, ms|0); +}; + +module.exports = function(Promise, INTERNAL, cast) { +var util = require("./util.js"); +var errors = require("./errors.js"); +var apiRejection = require("./errors_api_rejection")(Promise); +var TimeoutError = Promise.TimeoutError; + +var afterTimeout = function Promise$_afterTimeout(promise, message, ms) { + if (!promise.isPending()) return; + if (typeof message !== "string") { + message = "operation timed out after" + " " + ms + " ms" + } + var err = new TimeoutError(message); + errors.markAsOriginatingFromRejection(err); + promise._attachExtraTrace(err); + promise._cancel(err); +}; + +var afterDelay = function Promise$_afterDelay(value, promise) { + promise._fulfill(value); +}; + +var delay = Promise.delay = function Promise$Delay(value, ms) { + if (ms === void 0) { + ms = value; + value = void 0; + } + ms = +ms; + var maybePromise = cast(value, void 0); + var promise = new Promise(INTERNAL); + + if (maybePromise instanceof Promise) { + promise._propagateFrom(maybePromise, 7); + promise._follow(maybePromise); + return promise.then(function(value) { + return Promise.delay(value, ms); + }); + } else { + promise._setTrace(void 0); + _setTimeout(afterDelay, ms, value, promise); + } + return promise; +}; + +Promise.prototype.delay = function Promise$delay(ms) { + return delay(this, ms); +}; + +function successClear(value) { + var handle = this; + if (handle instanceof Number) handle = +handle; + clearTimeout(handle); + return value; +} + +function failureClear(reason) { + var handle = this; + if (handle instanceof Number) handle = +handle; + clearTimeout(handle); + throw reason; +} + +Promise.prototype.timeout = function Promise$timeout(ms, message) { + ms = +ms; + + var ret = new Promise(INTERNAL); + ret._propagateFrom(this, 7); + ret._follow(this); + var handle = _setTimeout(afterTimeout, ms, ret, message, ms); + return ret.cancellable() + ._then(successClear, failureClear, void 0, handle, void 0); +}; + +}; + +},{"./errors.js":10,"./errors_api_rejection":11,"./util.js":35}],34:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +module.exports = function (Promise, apiRejection, cast) { + var TypeError = require("./errors.js").TypeError; + var inherits = require("./util.js").inherits; + var PromiseInspection = Promise.PromiseInspection; + + function inspectionMapper(inspections) { + var len = inspections.length; + for (var i = 0; i < len; ++i) { + var inspection = inspections[i]; + if (inspection.isRejected()) { + return Promise.reject(inspection.error()); + } + inspections[i] = inspection.value(); + } + return inspections; + } + + function thrower(e) { + setTimeout(function(){throw e;}, 0); + } + + function castPreservingDisposable(thenable) { + var maybePromise = cast(thenable, void 0); + if (maybePromise !== thenable && + typeof thenable._isDisposable === "function" && + typeof thenable._getDisposer === "function" && + thenable._isDisposable()) { + maybePromise._setDisposable(thenable._getDisposer()); + } + return maybePromise; + } + function dispose(resources, inspection) { + var i = 0; + var len = resources.length; + var ret = Promise.defer(); + function iterator() { + if (i >= len) return ret.resolve(); + var maybePromise = castPreservingDisposable(resources[i++]); + if (maybePromise instanceof Promise && + maybePromise._isDisposable()) { + try { + maybePromise = cast(maybePromise._getDisposer() + .tryDispose(inspection), void 0); + } catch (e) { + return thrower(e); + } + if (maybePromise instanceof Promise) { + return maybePromise._then(iterator, thrower, + null, null, null); + } + } + iterator(); + } + iterator(); + return ret.promise; + } + + function disposerSuccess(value) { + var inspection = new PromiseInspection(); + inspection._settledValue = value; + inspection._bitField = 268435456; + return dispose(this, inspection).thenReturn(value); + } + + function disposerFail(reason) { + var inspection = new PromiseInspection(); + inspection._settledValue = reason; + inspection._bitField = 134217728; + return dispose(this, inspection).thenThrow(reason); + } + + function Disposer(data, promise) { + this._data = data; + this._promise = promise; + } + + Disposer.prototype.data = function Disposer$data() { + return this._data; + }; + + Disposer.prototype.promise = function Disposer$promise() { + return this._promise; + }; + + Disposer.prototype.resource = function Disposer$resource() { + if (this.promise().isFulfilled()) { + return this.promise().value(); + } + return null; + }; + + Disposer.prototype.tryDispose = function(inspection) { + var resource = this.resource(); + var ret = resource !== null + ? this.doDispose(resource, inspection) : null; + this._promise._unsetDisposable(); + this._data = this._promise = null; + return ret; + }; + + Disposer.isDisposer = function Disposer$isDisposer(d) { + return (d != null && + typeof d.resource === "function" && + typeof d.tryDispose === "function"); + }; + + function FunctionDisposer(fn, promise) { + this.constructor$(fn, promise); + } + inherits(FunctionDisposer, Disposer); + + FunctionDisposer.prototype.doDispose = function (resource, inspection) { + var fn = this.data(); + return fn.call(resource, resource, inspection); + }; + + Promise.using = function Promise$using() { + var len = arguments.length; + if (len < 2) return apiRejection( + "you must pass at least 2 arguments to Promise.using"); + var fn = arguments[len - 1]; + if (typeof fn !== "function") return apiRejection("fn must be a function"); + len--; + var resources = new Array(len); + for (var i = 0; i < len; ++i) { + var resource = arguments[i]; + if (Disposer.isDisposer(resource)) { + var disposer = resource; + resource = resource.promise(); + resource._setDisposable(disposer); + } + resources[i] = resource; + } + + return Promise.settle(resources) + .then(inspectionMapper) + .spread(fn) + ._then(disposerSuccess, disposerFail, void 0, resources, void 0); + }; + + Promise.prototype._setDisposable = + function Promise$_setDisposable(disposer) { + this._bitField = this._bitField | 262144; + this._disposer = disposer; + }; + + Promise.prototype._isDisposable = function Promise$_isDisposable() { + return (this._bitField & 262144) > 0; + }; + + Promise.prototype._getDisposer = function Promise$_getDisposer() { + return this._disposer; + }; + + Promise.prototype._unsetDisposable = function Promise$_unsetDisposable() { + this._bitField = this._bitField & (~262144); + this._disposer = void 0; + }; + + Promise.prototype.disposer = function Promise$disposer(fn) { + if (typeof fn === "function") { + return new FunctionDisposer(fn, this); + } + throw new TypeError(); + }; + +}; + +},{"./errors.js":10,"./util.js":35}],35:[function(require,module,exports){ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Petka Antonov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:

+ * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +"use strict"; +var es5 = require("./es5.js"); +var haveGetters = (function(){ + try { + var o = {}; + es5.defineProperty(o, "f", { + get: function () { + return 3; + } + }); + return o.f === 3; + } + catch (e) { + return false; + } + +})(); +var canEvaluate = typeof navigator == "undefined"; +var errorObj = {e: {}}; +function tryCatch1(fn, receiver, arg) { + try { return fn.call(receiver, arg); } + catch (e) { + errorObj.e = e; + return errorObj; + } +} + +function tryCatch2(fn, receiver, arg, arg2) { + try { return fn.call(receiver, arg, arg2); } + catch (e) { + errorObj.e = e; + return errorObj; + } +} + +function tryCatch3(fn, receiver, arg, arg2, arg3) { + try { return fn.call(receiver, arg, arg2, arg3); } + catch (e) { + errorObj.e = e; + return errorObj; + } +} + +function tryCatch4(fn, receiver, arg, arg2, arg3, arg4) { + try { return fn.call(receiver, arg, arg2, arg3, arg4); } + catch (e) { + errorObj.e = e; + return errorObj; + } +} + +function tryCatchApply(fn, args, receiver) { + try { return fn.apply(receiver, args); } + catch (e) { + errorObj.e = e; + return errorObj; + } +} + +var inherits = function(Child, Parent) { + var hasProp = {}.hasOwnProperty; + + function T() { + this.constructor = Child; + this.constructor$ = Parent; + for (var propertyName in Parent.prototype) { + if (hasProp.call(Parent.prototype, propertyName) && + propertyName.charAt(propertyName.length-1) !== "$" + ) { + this[propertyName + "$"] = Parent.prototype[propertyName]; + } + } + } + T.prototype = Parent.prototype; + Child.prototype = new T(); + return Child.prototype; +}; + +function asString(val) { + return typeof val === "string" ? val : ("" + val); +} + +function isPrimitive(val) { + return val == null || val === true || val === false || + typeof val === "string" || typeof val === "number"; + +} + +function isObject(value) { + return !isPrimitive(value); +} + +function maybeWrapAsError(maybeError) { + if (!isPrimitive(maybeError)) return maybeError; + + return new Error(asString(maybeError)); +} + +function withAppended(target, appendee) { + var len = target.length; + var ret = new Array(len + 1); + var i; + for (i = 0; i < len; ++i) { + ret[i] = target[i]; + } + ret[i] = appendee; + return ret; +} + +function getDataPropertyOrDefault(obj, key, defaultValue) { + if (es5.isES5) { + var desc = Object.getOwnPropertyDescriptor(obj, key); + if (desc != null) { + return desc.get == null && desc.set == null + ? desc.value + : defaultValue; + } + } else { + return {}.hasOwnProperty.call(obj, key) ? obj[key] : void 0; + } +} + +function notEnumerableProp(obj, name, value) { + if (isPrimitive(obj)) return obj; + var descriptor = { + value: value, + configurable: true, + enumerable: false, + writable: true + }; + es5.defineProperty(obj, name, descriptor); + return obj; +} + + +var wrapsPrimitiveReceiver = (function() { + return this !== "string"; +}).call("string"); + +function thrower(r) { + throw r; +} + +var inheritedDataKeys = (function() { + if (es5.isES5) { + return function(obj, opts) { + var ret = []; + var visitedKeys = Object.create(null); + var getKeys = Object(opts).includeHidden + ? Object.getOwnPropertyNames + : Object.keys; + while (obj != null) { + var keys; + try { + keys = getKeys(obj); + } catch (e) { + return ret; + } + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + if (visitedKeys[key]) continue; + visitedKeys[key] = true; + var desc = Object.getOwnPropertyDescriptor(obj, key); + if (desc != null && desc.get == null && desc.set == null) { + ret.push(key); + } + } + obj = es5.getPrototypeOf(obj); + } + return ret; + }; + } else { + return function(obj) { + var ret = []; + /*jshint forin:false */ + for (var key in obj) { + ret.push(key); + } + return ret; + }; + } + +})(); + +function isClass(fn) { + try { + if (typeof fn === "function") { + var keys = es5.keys(fn.prototype); + return keys.length > 0 && + !(keys.length === 1 && keys[0] === "constructor"); + } + return false; + } catch (e) { + return false; + } +} + +function toFastProperties(obj) { + /*jshint -W027*/ + function f() {} + f.prototype = obj; + return f; +} + +var rident = /^[a-z$_][a-z$_0-9]*$/i; +function isIdentifier(str) { + return rident.test(str); +} + +function filledRange(count, prefix, suffix) { + var ret = new Array(count); + for(var i = 0; i < count; ++i) { + ret[i] = prefix + i + suffix; + } + return ret; +} + +var ret = { + isClass: isClass, + isIdentifier: isIdentifier, + inheritedDataKeys: inheritedDataKeys, + getDataPropertyOrDefault: getDataPropertyOrDefault, + thrower: thrower, + isArray: es5.isArray, + haveGetters: haveGetters, + notEnumerableProp: notEnumerableProp, + isPrimitive: isPrimitive, + isObject: isObject, + canEvaluate: canEvaluate, + errorObj: errorObj, + tryCatch1: tryCatch1, + tryCatch2: tryCatch2, + tryCatch3: tryCatch3, + tryCatch4: tryCatch4, + tryCatchApply: tryCatchApply, + inherits: inherits, + withAppended: withAppended, + asString: asString, + maybeWrapAsError: maybeWrapAsError, + wrapsPrimitiveReceiver: wrapsPrimitiveReceiver, + toFastProperties: toFastProperties, + filledRange: filledRange +}; + +module.exports = ret; + +},{"./es5.js":12}]},{},[3]) +(3) +}); +; ;if (typeof window !== 'undefined' && window !== null) { window.P = window.Promise; } else if (typeof self !== 'undefined' && self !== null) { self.P = self.Promise; } \ No newline at end of file