<commit_before>/*
 * Licensed to Apereo under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Apereo licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License.  You may obtain a
 * copy of the License at the following location:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
'use strict';

define(['angular', 'jquery', 'require'], function(angular, $, require) {
  var currentPage = 'market';
  var currentCategory = '';

  return angular.module('my-app.marketplace.controllers', [])

  .controller('MarketplaceCommonFunctionsController',
    ['googleCustomSearchService', 'miscSearchService', 'layoutService',
      '$log', 'marketplaceService', 'miscService', 'MISC_URLS',
      '$sessionStorage', '$localStorage', '$rootScope', '$scope',
      '$routeParams', '$timeout', '$location', '$mdColors',
    function(googleCustomSearchService, miscSearchService, layoutService,
      $log, marketplaceService, miscService, MISC_URLS,
        $sessionStorage, $localStorage, $rootScope, $scope,
        $routeParams, $timeout, $location, $mdColors) {
      var vm = this;

      if ($sessionStorage.portal.theme) {
        // theme already in session, use primary color from it
        $scope.primaryColorRgb =
          $mdColors.getThemeColor($sessionStorage.portal.theme.name
          + '-primary');
      } else {
        // theme not yet in session, use primary color from zeroth theme
        $scope.primaryColorRgb =
          $mdColors.getThemeColor($rootScope.THEMES[0].name
            + '-primary');
        }

       $scope.navToDetails = function(marketplaceEntry, location) {
        marketplaceService.setFromInfo(location, $scope.searchTerm);
        $location.path('apps/details/'+ marketplaceEntry.fname);
       };

      $scope.isStatic = function(portlet) {
        return portlet.maxUrl.indexOf('portal') !== -1 // a portal hit
          && portlet.portletName // there is a portletName
          && portlet.portletName.indexOf('cms') != -1; // static content portlet
      };

      $scope.getLaunchURL = function(marketplaceEntry) {
        var layoutObj = marketplaceEntry.layoutObject;
        if ($rootScope.GuestMode && !marketplaceEntry.hasInLayout) {
          return $scope.loginToAuthPage +
              '/web/apps/details/'+ marketplaceEntry.fname;
        } else if (layoutObj.altMaxUrl == false &&
            (layoutObj.renderOnWeb || $localStorage.webPortletRender)) {
          return 'exclusive/' + layoutObj.fname;
        } else if (layoutObj.altMaxUrl == false &&
            $scope.isStatic(marketplaceEntry)) {
          return 'static/' + layoutObj.fname;
        } else {
          return marketplaceEntry.maxUrl;
        }
      };

      $scope.addToHome = function addToHome(portlet) {
        var fname = portlet.fname;
        var ret = layoutService.addToHome(portlet);
        ret.success(function(request, text) {
          angular.element('.fname-'+fname)
            .html(' Added Successfully')
            .prop('disabled', true)
            .removeClass('btn-add')
            .addClass('btn-added');
          $scope.$apply(function() {
            var marketplaceEntries = $.grep(
              $sessionStorage.marketplace,
              function(e) {
                return e.fname === portlet.fname;
              }
            );
            if (marketplaceEntries.length > 0) {
              marketplaceEntries[0].hasInLayout = true;
            }
            $rootScope.layout = null; // reset layout due to modifications
            $sessionStorage.layout = null;
          });
        })
          .error(function(request, text, error) {
            angular.element('.fname-'+fname)
              .parent()
              .append(
                'Issue adding to home, please try again later'
              );
          });
      };

      $scope.searchTermFilter = function(portlet) {
        return marketplaceService.portletMatchesSearchTerm(
          portlet,
          $scope.searchTerm,
          {
            searchDescription: true,
            searchKeywords: true,
            defaultReturn: true,
          }
        );
      };

      $scope.selectFilter = function(filter, category) {
        $scope.sortParameter = filter;
        $scope.categoryToShow = category;
        $scope.showCategories = false;
        if (filter === 'popular') {
          $scope.selectedFilter = 'popular';
          $scope.sortParameter = ['-rating', '-userRated'];
        }
        if (filter === 'az') {
          $scope.selectedFilter = 'az';
          $scope.sortParameter = 'title';
        }
        if (filter === 'category') {
          $scope.selectedFilter = 'category';
          $scope.sortParameter = 'title';
          $scope.showCategories = true;
        }

        miscService.pushGAEvent('Marketplace', 'Tab Select', filter);
      };

      $scope.slideTabs = function(direction) {
        $scope.tabsPosition = 'start';
        if (direction === 'right') {
          $scope.tabsPosition = 'end';
        }
      };

      $scope.toggleShowAll = function() {
        $scope.showAll = !$scope.showAll;
      };

      vm.setupSearchTerm = function() {
        var tempFilterText = '';
        var filterTextTimeout;
        $scope.searchTerm = marketplaceService.getInitialFilter();
        if ($routeParams.initFilter !== null &&
            ($scope.searchTerm === null || $scope.searchTerm === '')) {
          $scope.searchTerm = $routeParams.initFilter;
        } else {
          marketplaceService.initialFilter('');
        }
        $scope.searchText = $scope.searchTerm;
        var initFilter = false;
        // delay on the filter
        $scope.$watch('searchText', function(val) {
          if (filterTextTimeout) $timeout.cancel(filterTextTimeout);

          tempFilterText = val;
          filterTextTimeout = $timeout(function() {
            $scope.searchTerm = tempFilterText;
            if (initFilter && $scope.searchTerm) {
              miscService.pushGAEvent('Search', 'Filter', $scope.searchTerm);
            } else {
              initFilter = true;
            }
          }, 250); // delay 250 ms
        });
      };

      vm.initializeConstants = function() {
        var errorFn = function(name) {
          return function() {
            $log.warn('Could not ' + name);
          };
        };
        // initialize constants
        googleCustomSearchService.getPublicWebSearchURL().then(
          function(webSearchURL) {
            $scope.webSearchUrl = webSearchURL;
            return webSearchURL;
          }
        ).catch(errorFn('getPublicWebSearchURL'));
        googleCustomSearchService.getDomainResultsLabel().then(
          function(domainResultsLabel) {
            $scope.domainResultsLabel = domainResultsLabel;
            return domainResultsLabel;
          }
        ).catch(errorFn('getDomainResultsLabel'));
        miscSearchService.getKBSearchURL().then(
          function(kbSearchURL) {
            $scope.kbSearchUrl = kbSearchURL;
            return kbSearchURL;
          }
        ).catch(errorFn('getKBSearchURL'));
        miscSearchService.getEventSearchURL().then(
          function(eventsSearchURL) {
            $scope.eventsSearchUrl = eventsSearchURL;
            return eventsSearchURL;
          }
        ).catch(errorFn('getEventSearchURL'));
        miscSearchService.getHelpDeskHelpURL().then(
          function(helpdeskURL) {
            $scope.helpdeskUrl = helpdeskURL;
            return helpdeskURL;
          }
        ).catch(errorFn('getHelpDeskHelpURL'));
        $scope.directorySearchUrl = MISC_URLS.directorySearchURL;
        $scope.feedbackUrl = MISC_URLS.feedbackURL;
        $scope.loginToAuthPage = MISC_URLS.myuwHome;
      };
    },
  ])

  .controller('MarketplaceController', [
    '$log', '$rootScope', '$scope', '$controller',
    'mainService', 'marketplaceService',
    function($log, $rootScope, $scope, $controller,
      mainService, marketplaceService) {
      var base = $controller('MarketplaceCommonFunctionsController',
        {$scope: $scope});

      var init = function() {
        // init variables
        $scope.portlets = [];
        marketplaceService.getPortlets().then(function(data) {
          $scope.portlets = data.portlets;
          $scope.categories = data.categories;
          return data;
        }).catch(function() {
          $log.warn('Could not getPortlets');
        });

        base.setupSearchTerm();

        // initialize variables

        $scope.searchResultLimit = 20;
        $scope.showAll = false;

        mainService.isGuest()
          .then(function(isGuest) {
            if (isGuest) {
              $scope.showAll = true;
            }
        }).catch(function() {
          $log.warn('Cannot get isGuest');
          return true;
        });

        if (currentPage === 'details') {
          // Empty string indicates no categories, show all portlets
          $scope.categoryToShow = '';
          // Default to filter by category on return back to app dir browse
          $scope.selectedFilter = 'category';
          // When filtering by category, sort by title
          $scope.sortParameter = 'title';
          // Show category selection div by default
          $scope.showCategories = true;

          currentPage = 'market';
          if (currentCategory !== '') {
            $scope.categoryToShow = currentCategory;
          } else {
            $scope.categoryToShow = '';
          }
        } else {
          // Empty string indicates no categories, show all portlets
          $scope.categoryToShow = '';
          // Default filter is to sort by popularity
          $scope.selectedFilter = 'popular';
          // To sort by popularity, angular will use portlet.rating to filter
          $scope.sortParameter = ['-rating', '-userRated'];
          // Hide category selection div by default
          $scope.showCategories = false;
        }

        base.initializeConstants();
      };

      // run functions
      init();
    }])

  .controller('MarketplaceDetailsController', [
      '$controller', '$document', '$scope', '$routeParams',
      '$mdDialog', 'marketplaceService', 'SERVICE_LOC',
      function($controller, $document, $scope, $routeParams,
          $mdDialog, marketplaceService, SERVICE_LOC) {
        $controller('MarketplaceCommonFunctionsController',
          {$scope: $scope});

        $scope.specifyCategory = function(category) {
          currentCategory=category;
          currentPage='details';
        };

        var figureOutBackStuff = function() {
          var fromInfo = marketplaceService.getFromInfo();
          if (fromInfo.term) {
            // from somewhere
            if ('Search' === fromInfo.searchOrBrowse && fromInfo.term) {
              // if from search and term is populated, return to search
              $scope.backText = 'Search Results for ' + fromInfo.term;
              $scope.backURL = 'apps/search/' + fromInfo.term;
            } else {
              // assuming from browse
              $scope.backText = 'Browse';
              $scope.backURL = 'apps/browse/' + fromInfo.term;
            }

            // reset services
            marketplaceService.setFromInfo(undefined, undefined);
          } else {
            // direct hit, will go back to browse
            $scope.backURL='apps';
            $scope.backText='Browse';
          }
        };

        $scope.clickRatingReviewAdmin = function() {
          $mdDialog.show({
            controller: 'MarketplaceRatingReviewAdminController',
            templateUrl: require.toUrl('./partials/rating-review-admin.html'),
            parent: angular.element($document.body),
            scope: $scope,
            preserveScope: true,
            clickOutsideToClose: true,
            fullscreen: false,
          });
        };

        // init
        var init = function() {
          $scope.loading = true;
          figureOutBackStuff();
          $scope.obj = [];
          $scope.ratingPrefix = SERVICE_LOC.base +
            SERVICE_LOC.marketplace.base;
          $scope.errorMessage =
              'There was an issue loading details, please click back to apps.';
          marketplaceService.getPortlet($routeParams.fname).then(
            function(result) {
              $scope.loading = false;
              if (!result) {
                $scope.error = true;
                $scope.portlet = null;
              } else {
                $scope.portlet = result;
                $scope.error = false;
              }
              return result;
            }
          ).catch(function(reason) {
            $scope.loading = false;
            $scope.error = true;
          });
        };
        init();
      }]
  )

  .controller('MarketplaceRatingReviewAdminController', [
    '$log', '$scope', 'marketplaceService',
    function($log, $scope, marketplaceService) {
      var init = function() {
        $scope.ratings = [];
        marketplaceService.getAllRatings($scope.portlet.fname).then(
          function(ratings) {
            if (ratings) {
              $scope.ratings = ratings;
              $scope.average =0;
              $scope.totalReviews = 0;
              angular.forEach(ratings, function(value, key) {
                $scope.average+= value.rating;
                if (value.review) {
                  $scope.totalReviews += 1;
                }
              });
              $scope.average = Math.round($scope.average / ratings.length);
            }
            return ratings;
          }
        ).catch(function() {
          $log.warn('Could not getAllRatings');
        });
      };

      init();
    }]);
});
<commit_msg>feat: adds guestmode method<commit_after>/*
 * Licensed to Apereo under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Apereo licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License.  You may obtain a
 * copy of the License at the following location:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
'use strict';

define(['angular', 'jquery', 'require'], function(angular, $, require) {
  var currentPage = 'market';
  var currentCategory = '';

  return angular.module('my-app.marketplace.controllers', [])

  .controller('MarketplaceCommonFunctionsController',
    ['googleCustomSearchService', 'miscSearchService', 'layoutService',
      '$log', 'marketplaceService', 'miscService', 'mainService',
      'MISC_URLS', '$sessionStorage', '$localStorage', '$rootScope', '$scope',
      '$routeParams', '$timeout', '$location', '$mdColors',
    function(googleCustomSearchService, miscSearchService, layoutService,
      $log, marketplaceService, miscService, mainService,
        MISC_URLS, $sessionStorage, $localStorage, $rootScope, $scope,
        $routeParams, $timeout, $location, $mdColors) {
      var vm = this;

      if ($sessionStorage.portal.theme) {
        // theme already in session, use primary color from it
        $scope.primaryColorRgb =
          $mdColors.getThemeColor($sessionStorage.portal.theme.name
          + '-primary');
      } else {
        // theme not yet in session, use primary color from zeroth theme
        $scope.primaryColorRgb =
          $mdColors.getThemeColor($rootScope.THEMES[0].name
            + '-primary');
        }

       $scope.navToDetails = function(marketplaceEntry, location) {
        marketplaceService.setFromInfo(location, $scope.searchTerm);
        $location.path('apps/details/'+ marketplaceEntry.fname);
       };

      $scope.isStatic = function(portlet) {
        return portlet.maxUrl.indexOf('portal') !== -1 // a portal hit
          && portlet.portletName // there is a portletName
          && portlet.portletName.indexOf('cms') != -1; // static content portlet
      };

      $scope.isGuest = function(mainService.isGuest())
          .then(function(isGuest) {
            return isGuest;
        }).catch(function() {
          $log.warn('Cannot get isGuest');
          return true;
        });

      $scope.getLaunchURL = function(marketplaceEntry) {
        var layoutObj = marketplaceEntry.layoutObject;
        if ($scope.isGuest && !marketplaceEntry.hasInLayout) {
          return $scope.loginToAuthPage +
              '/web/apps/details/'+ marketplaceEntry.fname;
        } else if (layoutObj.altMaxUrl == false &&
            (layoutObj.renderOnWeb || $localStorage.webPortletRender)) {
          return 'exclusive/' + layoutObj.fname;
        } else if (layoutObj.altMaxUrl == false &&
            $scope.isStatic(marketplaceEntry)) {
          return 'static/' + layoutObj.fname;
        } else {
          return marketplaceEntry.maxUrl;
        }
      };

      $scope.addToHome = function addToHome(portlet) {
        var fname = portlet.fname;
        var ret = layoutService.addToHome(portlet);
        ret.success(function(request, text) {
          angular.element('.fname-'+fname)
            .html(' Added Successfully')
            .prop('disabled', true)
            .removeClass('btn-add')
            .addClass('btn-added');
          $scope.$apply(function() {
            var marketplaceEntries = $.grep(
              $sessionStorage.marketplace,
              function(e) {
                return e.fname === portlet.fname;
              }
            );
            if (marketplaceEntries.length > 0) {
              marketplaceEntries[0].hasInLayout = true;
            }
            $rootScope.layout = null; // reset layout due to modifications
            $sessionStorage.layout = null;
          });
        })
          .error(function(request, text, error) {
            angular.element('.fname-'+fname)
              .parent()
              .append(
                'Issue adding to home, please try again later'
              );
          });
      };

      $scope.searchTermFilter = function(portlet) {
        return marketplaceService.portletMatchesSearchTerm(
          portlet,
          $scope.searchTerm,
          {
            searchDescription: true,
            searchKeywords: true,
            defaultReturn: true,
          }
        );
      };

      $scope.selectFilter = function(filter, category) {
        $scope.sortParameter = filter;
        $scope.categoryToShow = category;
        $scope.showCategories = false;
        if (filter === 'popular') {
          $scope.selectedFilter = 'popular';
          $scope.sortParameter = ['-rating', '-userRated'];
        }
        if (filter === 'az') {
          $scope.selectedFilter = 'az';
          $scope.sortParameter = 'title';
        }
        if (filter === 'category') {
          $scope.selectedFilter = 'category';
          $scope.sortParameter = 'title';
          $scope.showCategories = true;
        }

        miscService.pushGAEvent('Marketplace', 'Tab Select', filter);
      };

      $scope.slideTabs = function(direction) {
        $scope.tabsPosition = 'start';
        if (direction === 'right') {
          $scope.tabsPosition = 'end';
        }
      };

      $scope.toggleShowAll = function() {
        $scope.showAll = !$scope.showAll;
      };

      vm.setupSearchTerm = function() {
        var tempFilterText = '';
        var filterTextTimeout;
        $scope.searchTerm = marketplaceService.getInitialFilter();
        if ($routeParams.initFilter !== null &&
            ($scope.searchTerm === null || $scope.searchTerm === '')) {
          $scope.searchTerm = $routeParams.initFilter;
        } else {
          marketplaceService.initialFilter('');
        }
        $scope.searchText = $scope.searchTerm;
        var initFilter = false;
        // delay on the filter
        $scope.$watch('searchText', function(val) {
          if (filterTextTimeout) $timeout.cancel(filterTextTimeout);

          tempFilterText = val;
          filterTextTimeout = $timeout(function() {
            $scope.searchTerm = tempFilterText;
            if (initFilter && $scope.searchTerm) {
              miscService.pushGAEvent('Search', 'Filter', $scope.searchTerm);
            } else {
              initFilter = true;
            }
          }, 250); // delay 250 ms
        });
      };

      vm.initializeConstants = function() {
        var errorFn = function(name) {
          return function() {
            $log.warn('Could not ' + name);
          };
        };
        // initialize constants
        googleCustomSearchService.getPublicWebSearchURL().then(
          function(webSearchURL) {
            $scope.webSearchUrl = webSearchURL;
            return webSearchURL;
          }
        ).catch(errorFn('getPublicWebSearchURL'));
        googleCustomSearchService.getDomainResultsLabel().then(
          function(domainResultsLabel) {
            $scope.domainResultsLabel = domainResultsLabel;
            return domainResultsLabel;
          }
        ).catch(errorFn('getDomainResultsLabel'));
        miscSearchService.getKBSearchURL().then(
          function(kbSearchURL) {
            $scope.kbSearchUrl = kbSearchURL;
            return kbSearchURL;
          }
        ).catch(errorFn('getKBSearchURL'));
        miscSearchService.getEventSearchURL().then(
          function(eventsSearchURL) {
            $scope.eventsSearchUrl = eventsSearchURL;
            return eventsSearchURL;
          }
        ).catch(errorFn('getEventSearchURL'));
        miscSearchService.getHelpDeskHelpURL().then(
          function(helpdeskURL) {
            $scope.helpdeskUrl = helpdeskURL;
            return helpdeskURL;
          }
        ).catch(errorFn('getHelpDeskHelpURL'));
        $scope.directorySearchUrl = MISC_URLS.directorySearchURL;
        $scope.feedbackUrl = MISC_URLS.feedbackURL;
        $scope.loginToAuthPage = MISC_URLS.myuwHome;
      };
    },
  ])

  .controller('MarketplaceController', [
    '$log', '$rootScope', '$scope', '$controller',
    'mainService', 'marketplaceService',
    function($log, $rootScope, $scope, $controller,
      mainService, marketplaceService) {
      var base = $controller('MarketplaceCommonFunctionsController',
        {$scope: $scope});

      var init = function() {
        // init variables
        $scope.portlets = [];
        marketplaceService.getPortlets().then(function(data) {
          $scope.portlets = data.portlets;
          $scope.categories = data.categories;
          return data;
        }).catch(function() {
          $log.warn('Could not getPortlets');
        });

        base.setupSearchTerm();

        // initialize variables

        $scope.searchResultLimit = 20;
        $scope.showAll = false;

        mainService.isGuest()
          .then(function(isGuest) {
            if (isGuest) {
              $scope.showAll = true;
            }
            return isGuest;
        }).catch(function() {
          $log.warn('Cannot get isGuest');
          return true;
        });

        if (currentPage === 'details') {
          // Empty string indicates no categories, show all portlets
          $scope.categoryToShow = '';
          // Default to filter by category on return back to app dir browse
          $scope.selectedFilter = 'category';
          // When filtering by category, sort by title
          $scope.sortParameter = 'title';
          // Show category selection div by default
          $scope.showCategories = true;

          currentPage = 'market';
          if (currentCategory !== '') {
            $scope.categoryToShow = currentCategory;
          } else {
            $scope.categoryToShow = '';
          }
        } else {
          // Empty string indicates no categories, show all portlets
          $scope.categoryToShow = '';
          // Default filter is to sort by popularity
          $scope.selectedFilter = 'popular';
          // To sort by popularity, angular will use portlet.rating to filter
          $scope.sortParameter = ['-rating', '-userRated'];
          // Hide category selection div by default
          $scope.showCategories = false;
        }

        base.initializeConstants();
      };

      // run functions
      init();
    }])

  .controller('MarketplaceDetailsController', [
      '$controller', '$document', '$scope', '$routeParams',
      '$mdDialog', 'marketplaceService', 'SERVICE_LOC',
      function($controller, $document, $scope, $routeParams,
          $mdDialog, marketplaceService, SERVICE_LOC) {
        $controller('MarketplaceCommonFunctionsController',
          {$scope: $scope});

        $scope.specifyCategory = function(category) {
          currentCategory=category;
          currentPage='details';
        };

        var figureOutBackStuff = function() {
          var fromInfo = marketplaceService.getFromInfo();
          if (fromInfo.term) {
            // from somewhere
            if ('Search' === fromInfo.searchOrBrowse && fromInfo.term) {
              // if from search and term is populated, return to search
              $scope.backText = 'Search Results for ' + fromInfo.term;
              $scope.backURL = 'apps/search/' + fromInfo.term;
            } else {
              // assuming from browse
              $scope.backText = 'Browse';
              $scope.backURL = 'apps/browse/' + fromInfo.term;
            }

            // reset services
            marketplaceService.setFromInfo(undefined, undefined);
          } else {
            // direct hit, will go back to browse
            $scope.backURL='apps';
            $scope.backText='Browse';
          }
        };

        $scope.clickRatingReviewAdmin = function() {
          $mdDialog.show({
            controller: 'MarketplaceRatingReviewAdminController',
            templateUrl: require.toUrl('./partials/rating-review-admin.html'),
            parent: angular.element($document.body),
            scope: $scope,
            preserveScope: true,
            clickOutsideToClose: true,
            fullscreen: false,
          });
        };

        // init
        var init = function() {
          $scope.loading = true;
          figureOutBackStuff();
          $scope.obj = [];
          $scope.ratingPrefix = SERVICE_LOC.base +
            SERVICE_LOC.marketplace.base;
          $scope.errorMessage =
              'There was an issue loading details, please click back to apps.';
          marketplaceService.getPortlet($routeParams.fname).then(
            function(result) {
              $scope.loading = false;
              if (!result) {
                $scope.error = true;
                $scope.portlet = null;
              } else {
                $scope.portlet = result;
                $scope.error = false;
              }
              return result;
            }
          ).catch(function(reason) {
            $scope.loading = false;
            $scope.error = true;
          });
        };
        init();
      }]
  )

  .controller('MarketplaceRatingReviewAdminController', [
    '$log', '$scope', 'marketplaceService',
    function($log, $scope, marketplaceService) {
      var init = function() {
        $scope.ratings = [];
        marketplaceService.getAllRatings($scope.portlet.fname).then(
          function(ratings) {
            if (ratings) {
              $scope.ratings = ratings;
              $scope.average =0;
              $scope.totalReviews = 0;
              angular.forEach(ratings, function(value, key) {
                $scope.average+= value.rating;
                if (value.review) {
                  $scope.totalReviews += 1;
                }
              });
              $scope.average = Math.round($scope.average / ratings.length);
            }
            return ratings;
          }
        ).catch(function() {
          $log.warn('Could not getAllRatings');
        });
      };

      init();
    }]);
});
<|endoftext|>


<commit_before>var URL = '../api/';

function loadData(entityName, contentData) {
    $.extend($.jgrid.defaults, {
        autowidth: true,
        shrinkToFit: true,
        datatype: 'json',
        jsonReader: {
            repeatitems: false,
            root: "content",
            page: function(result) {
                //Total number of records
                return result.number + 1;
            },
            total: "totalPages",
            records: "totalElements"
        },
        prmNames: {
            page: "page.page",
            rows: "page.size",
            sort: "page.sort",
            order: "page.sort.dir"
        },
        height: 'auto',
        viewrecords: true,
        rowList: [10, 20, 50, 100],
        altRows: true,
        loadError: function(xhr, status, error) {
            $("#grid").clearGridData();
        }
    });

    $.extend($.jgrid.edit, {
        closeAfterEdit: true,
        closeAfterAdd: true,
        ajaxEditOptions: {contentType: "application/json"},
        mtype: 'PUT',
        serializeEditData: function(data) {
            delete data.oper;
            return JSON.stringify(data);
        }
    });
    $.extend($.jgrid.del, {
        mtype: 'DELETE',
        serializeDelData: function() {
            return "";
        }
    });
    var delOptions = {
        onclickSubmit: function(params, postdata) {
            console.log(postdata);
            params.url = URL + 'data/' + entityName + '/' + postdata;
        }
    };

    var colModelDynamic = [];
    colModelDynamic.push({
        name: 'name',
        label: 'Name',
        key: true,
        index: 'name',
        editable: true,
        editoptions: {required: true}
    });

    $.each(contentData.attributes, function(index, attribute) {
        colModelDynamic.push({
            name: attribute.name,
            label: attribute.label,
            key: true,
            index: 'name',
            editable: true,
            editoptions: {required: true}
        });
    });
    var options = {
        url: URL + 'data/' + entityName,
        editurl: URL + 'data/' + entityName,
        colModel: colModelDynamic,
        caption: contentData.label,
        pager: '#pager',
        height: 'auto',
        ondblClickRow: function(id) {
            //edit url
            window.location = entityName + '/' + id;
        },
        formatter: {idName: "name"}
    };
    $("#grid")
            .jqGrid(options)
            .navGrid('#pager',
                    {search: false, addfunc: function() {
                            window.location = entityName + '/add';
                        }, editfunc: function(data) {
                            window.location = entityName + '/' + data;
                        }}, //options
            {}, // edit options
                    {}, // add options
                    delOptions,
                    {} // search options
            );
}

$(document).ready(function() {
    var pathname = window.location.pathname;
    var entityName = pathname.substr(pathname.lastIndexOf('/') + 1);
    $.ajax(
            {
                url: URL + "entities/" + entityName,
                type: 'GET',
                dataType: "json",
                contentType: 'application/json',
                success: function(data, textStatus, jqXHR)
                {
                    loadData(entityName, data.entity);

                },
                error: function(jqXHR, textStatus, errorThrown)
                {
                    console.log(jqXHR + "===" + textStatus);
                }
            });
});
<commit_msg>BOG PATCH :(<commit_after>var URL = '../api/';

function loadData(entityName, contentData) {
    $.extend($.jgrid.defaults, {
        rowNum:100,
        autowidth: true,
        shrinkToFit: true,
        datatype: 'json',
        jsonReader: {
            repeatitems: false,
            root: "content",
            page: function(result) {
                //Total number of records
                return result.number + 1;
            },
            total: "totalPages",
            records: "totalElements"
        },
        prmNames: {
            page: "page.page",
            rows: "page.size",
            sort: "page.sort",
            order: "page.sort.dir"
        },
        height: 'auto',
        viewrecords: true,
        rowList: [10, 20, 50, 100],
        altRows: true,
        loadError: function(xhr, status, error) {
            $("#grid").clearGridData();
        }
    });

    $.extend($.jgrid.edit, {
        closeAfterEdit: true,
        closeAfterAdd: true,
        ajaxEditOptions: {contentType: "application/json"},
        mtype: 'PUT',
        serializeEditData: function(data) {
            delete data.oper;
            return JSON.stringify(data);
        }
    });
    $.extend($.jgrid.del, {
        mtype: 'DELETE',
        serializeDelData: function() {
            return "";
        }
    });
    var delOptions = {
        onclickSubmit: function(params, postdata) {
            console.log(postdata);
            params.url = URL + 'data/' + entityName + '/' + postdata;
        }
    };

    var colModelDynamic = [];
    colModelDynamic.push({
        name: 'name',
        label: 'Name',
        key: true,
        index: 'name',
        editable: true,
        editoptions: {required: true}
    });

    $.each(contentData.attributes, function(index, attribute) {
        colModelDynamic.push({
            name: attribute.name,
            label: attribute.label,
            key: true,
            index: 'name',
            editable: true,
            editoptions: {required: true}
        });
    });
    var options = {
        url: URL + 'data/' + entityName,
        editurl: URL + 'data/' + entityName,
        colModel: colModelDynamic,
        caption: contentData.label,
        pager: '#pager',
        height: 'auto',
        ondblClickRow: function(id) {
            //edit url
            window.location = entityName + '/' + id;
        },
        formatter: {idName: "name"}
    };
    $("#grid")
            .jqGrid(options)
            .navGrid('#pager',
                    {search: false, addfunc: function() {
                            window.location = entityName + '/add';
                        }, editfunc: function(data) {
                            window.location = entityName + '/' + data;
                        }}, //options
            {}, // edit options
                    {}, // add options
                    delOptions,
                    {} // search options
            );
}

$(document).ready(function() {
    var pathname = window.location.pathname;
    var entityName = pathname.substr(pathname.lastIndexOf('/') + 1);
    $.ajax(
            {
                url: URL + "entities/" + entityName,
                type: 'GET',
                dataType: "json",
                contentType: 'application/json',
                success: function(data, textStatus, jqXHR)
                {
                    loadData(entityName, data.entity);

                },
                error: function(jqXHR, textStatus, errorThrown)
                {
                    console.log(jqXHR + "===" + textStatus);
                }
            });
});
<|endoftext|>


<commit_before><commit_msg>[ADD] tests for mirrorMatrix<commit_after>var should = require('should');

var orb = require('./../../');

describe('orb.vector.mirrorMatrix', function() {

  it('should return a correct Q1 matrix', function() {
    var q1 = orb.vector.mirrorMatrix(1);

    q1[0].should.equal(-1);
    q1[1].should.equal(0);
    q1[2].should.equal(0);

    q1[3].should.equal(0);
    q1[4].should.equal(1);
    q1[5].should.equal(0);

    q1[6].should.equal(0);
    q1[7].should.equal(0);
    q1[8].should.equal(1);
  });

  it('should return a correct Q2 matrix', function() {
    var q2 = orb.vector.mirrorMatrix(2);

    q2[0].should.equal(1);
    q2[1].should.equal(0);
    q2[2].should.equal(0);

    q2[3].should.equal(0);
    q2[4].should.equal(-1);
    q2[5].should.equal(0);

    q2[6].should.equal(0);
    q2[7].should.equal(0);
    q2[8].should.equal(1);
  });

  it('should return a correct Q3 matrix', function() {
    var q3 = orb.vector.mirrorMatrix(3);

    q3[0].should.equal(1);
    q3[1].should.equal(0);
    q3[2].should.equal(0);

    q3[3].should.equal(0);
    q3[4].should.equal(1);
    q3[5].should.equal(0);

    q3[6].should.equal(0);
    q3[7].should.equal(0);
    q3[8].should.equal(-1);
  });

});
<|endoftext|>


<commit_before>Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
Components.utils.import("resource://cck2/CCK2.jsm");

(function () {
  var temp = {};
  Cu.import("resource://cck2/Preferences.jsm", temp);
  var Preferences = temp.Preferences;
  let scope = {};
  Services.scriptloader.loadSubScript("chrome://cck2/content/util.js", scope);
  let {E, hide, remove, disable, errorCritical} = scope;

  var config;

  function onPageLoad(event) {
    try {
      var doc = event.target;
      var win = doc.defaultView;
      if (!doc.location) {
        return;
      }
      /* Remove the sync button from about:home */
      if ((config && config.disableSync) &&
         /^about:home/.test(doc.location.href)) {
        remove(E("sync", doc));
      }
      /* Remove the addons button from about:home */
      if ((config && config.disableAddonsManager) &&
         /^about:home/.test(doc.location.href)) {
        remove(E("addons", doc));
      }
      /* Remove the addons button from about:home */
      if ((config && config.removeSnippets) &&
         /^about:home/.test(doc.location.href)) {
        remove(E("snippets", doc));
      }
      /* Remove the reset button from about:support */
      if ((config && config.disableResetFirefox) &&
         /^about:support/.test(doc.location.href)) {
        remove(E("reset-box", doc));
      }

      /* If health reporter upload is locked, remove the activation widget */
      if (Preferences.locked("datareporting.healthreport.uploadEnabled", false)) {
        if (/^https:\/\/fhr.cdn.mozilla.net\//.test(doc.location.href)) {
          var activationWidget = event.target.querySelector(".activationWidget");
          if (activationWidget) {
            remove(activationWidget);
          }
        }
      }
    } catch (e) {
      errorCritical(e);
    }
  }

  function disableSync() {
    window.XULBrowserWindow.inContentWhitelist =
      window.XULBrowserWindow.inContentWhitelist.filter(function(element) {
        return element != "about:sync-progress";
      })
    var mySyncUI = {
      init: function() {
        return;
      },
      initUI: function() {
        return;
      },
      updateUI: function() {
        hide(E("sync-setup-state"));
        hide(E("sync-syncnow-state"));
      }
    }
    gSyncUI = mySyncUI;
    remove(E("sync-button"));
  }

  function disablePrivateBrowsing() {
    disable(E("Tools:PrivateBrowsing"));
    hide(E("menu_newPrivateWindow"));
    // Because this is on a context menu, we can't use "hidden"
    if (E("context-openlinkprivate"))
      E("context-openlinkprivate").setAttribute("style", "display: none;");
    hide(E("appmenu_privateBrowsing"));
    hide(E("appmenu_newPrivateWindow"));
    hide(E("privateBrowsingItem"));
  }

  function disableAddonsManager() {
    window.XULBrowserWindow.inContentWhitelist =
      window.XULBrowserWindow.inContentWhitelist.filter(function(element) {
        return element != "about:addons";
      })
    hide(E("appmenu_addons"));
    hide(E("menu_openAddons"));
    disable(E("Tools:Addons"));
  }

  function removeDeveloperTools() {
    hide(E("webDeveloperMenu"));
    var devtoolsKeyset = document.getElementById("devtoolsKeyset");
    for (var i = 0; i < devtoolsKeyset.childNodes.length; i++) {
      devtoolsKeyset.childNodes[i].removeAttribute("command");
    }
    try {
      document.getElementById("Tools:ResponsiveUI").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:Scratchpad").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:BrowserConsole").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:BrowserToolbox").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:DevAppsMgr").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:DevToolbar").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:DevToolbox").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:DevToolbarFocus").removeAttribute("oncommand");
    } catch (e) {}
  }

  function disableErrorConsole() {
    document.getElementById("Tools:ErrorConsole").removeAttribute("oncommand");
  }

  function startup()
  {
    try {
      window.removeEventListener("load", startup, false);
      window.XULBrowserWindow.inContentWhitelist =
        window.XULBrowserWindow.inContentWhitelist.filter(function(element) {
          return element != "about:preferences";
        })

      config = CCK2.getConfig();
      if (!config)
        return;

      if (config.disablePrivateBrowsing &&
          PrivateBrowsingUtils.isWindowPrivate(window)) {
        window.setTimeout(function() {
          Services.prompt.alert(window, "Private Browsing", "Private Browsing has been disabled by your administrator");
          window.close();
        }, 0, false);
      }
      if (config.disablePrivateBrowsing) {
        disablePrivateBrowsing();
      }
      if (config.disableSync) {
        disableSync();
      }
      E("appcontent").addEventListener("DOMContentLoaded", onPageLoad, false);

      if (config.disableAddonsManager) {
        disableAddonsManager();
      }
      if (config.removeDeveloperTools) {
        Services.tm.mainThread.dispatch(function() {
          removeDeveloperTools();
        }, Ci.nsIThread.DISPATCH_NORMAL);
      }
      if (config.disableErrorConsole) {
        disableErrorConsole();
      }
      if (config.removeSafeModeMenu) {
        hide(E("helpSafeMode"));
        try {
          hide(E("appmenu_safeMode"));
        } catch (e) {}
      }
      if (config.titlemodifier) {
        document.getElementById("main-window").setAttribute("titlemodifier", config.titlemodifier);
      }
      if (config.removeSetDesktopBackground) {
        // Because this is on a context menu, we can't use "hidden"
        if (E("context-setDesktopBackground"))
          E("context-setDesktopBackground").setAttribute("style", "display: none;");
        }
      if (config.hiddenUI) {
        for (var i=0; i < config.hiddenUI.length; i++) {
          var uiElement = document.querySelector(config.hiddenUI[i]);
          if (!uiElement)
            continue;
          hide(uiElement);
          if (uiElement.nodeName == "menuitem") {
            uiElement.removeAttribute("key");
            uiElement.removeAttribute("oncommand");
            if (uiElement.hasAttribute("command")) {
              var commandId = uiElement.getAttribute("command");
              uiElement.removeAttribute("command");
              var command = document.getElementById(commandId);
              command.removeAttribute("oncommand");
              var keys = document.querySelectorAll("key[command='" + commandId + "']")
              for (var i=0; i < keys.length; i++) {
                keys[i].removeAttribute("command");
              }
            }
          }
        }
      }
      if (config.helpMenu) {
        // We need to run this function on a delay, because we won't know
        // if the about menu is hidden for mac until after it is run.
        Services.tm.mainThread.dispatch(function() {
          var helpMenuPopup = document.getElementById("menu_HelpPopup");
          var menuitem = document.createElement("menuitem");
          menuitem.setAttribute("label", config.helpMenu.label);
          menuitem.setAttribute("url", config.helpMenu.url);
          menuitem.setAttribute("accesskey", config.helpMenu.accesskey);
          menuitem.addEventListener("command", function(event) {
            openUILink(this.getAttribute("url"), event, false, true);
          })
          menuitem.addEventListener("click", function(event) {
            checkForMiddleClick(this, event);
          }, false);
          if (E("aboutName").hidden) {
            // Mac
            helpMenuPopup.appendChild(menuitem);
          } else {
            helpMenuPopup.insertBefore(menuitem, E("aboutName"));
            helpMenuPopup.insertBefore(document.createElement("menuseparator"),
                                              E("aboutName"));
          }
        }, Ci.nsIThread.DISPATCH_NORMAL);
        var appMenuHelpMenuPopup = document.getElementById("appmenu_helpMenupopup");
        if (appMenuHelpMenuPopup) {
          var menuitem = document.createElement("menuitem");
          menuitem.setAttribute("label", config.helpMenu.label);
          menuitem.setAttribute("url", config.helpMenu.url);
          menuitem.addEventListener("command", function(event) {
            openUILink(this.getAttribute("url"), event, false, true);
          })
          menuitem.addEventListener("click", function(event) {
            checkForMiddleClick(this, event);
          }, false);
          appMenuHelpMenuPopup.insertBefore(menuitem, E("appmenu_about"));
          appMenuHelpMenuPopup.insertBefore(document.createElement("menuseparator"),
                                            E("appmenu_about"));
        }
      }
      if (CCK2.firstrun) {
        if (config.displayBookmarksToolbar || (config.bookmarks && config.bookmarks.toolbar)) {
          E("PersonalToolbar").collapsed = false;
          E("PersonalToolbar").setAttribute("collapsed", "false");
          document.persist("PersonalToolbar", "collapsed");
        }
        if (config.displayMenuBar) {
          if (typeof updateAppButtonDisplay != "undefined") {
            E("toolbar-menubar").setAttribute("autohide", "false");
            document.persist("toolbar-menubar", "autohide")
            updateAppButtonDisplay();
          }
        }
        CCK2.firstrun = false;
      }
    } catch (e) {
      errorCritical(e);
    }
  }

  function shutdown()
  {
    window.removeEventListener("unload", shutdown, false);
    var appcontent = E("appcontent");
    if (appcontent) {
       appcontent.removeEventListener("DOMContentLoaded", onPageLoad, false);
    }
  }

  window.addEventListener("load", startup, false);
  window.addEventListener("unload", shutdown, false);
})();
<commit_msg>Use querySelectorAll in case thre is more than one element<commit_after>Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
Components.utils.import("resource://cck2/CCK2.jsm");

(function () {
  var temp = {};
  Cu.import("resource://cck2/Preferences.jsm", temp);
  var Preferences = temp.Preferences;
  let scope = {};
  Services.scriptloader.loadSubScript("chrome://cck2/content/util.js", scope);
  let {E, hide, remove, disable, errorCritical} = scope;

  var config;

  function onPageLoad(event) {
    try {
      var doc = event.target;
      var win = doc.defaultView;
      if (!doc.location) {
        return;
      }
      /* Remove the sync button from about:home */
      if ((config && config.disableSync) &&
         /^about:home/.test(doc.location.href)) {
        remove(E("sync", doc));
      }
      /* Remove the addons button from about:home */
      if ((config && config.disableAddonsManager) &&
         /^about:home/.test(doc.location.href)) {
        remove(E("addons", doc));
      }
      /* Remove the addons button from about:home */
      if ((config && config.removeSnippets) &&
         /^about:home/.test(doc.location.href)) {
        remove(E("snippets", doc));
      }
      /* Remove the reset button from about:support */
      if ((config && config.disableResetFirefox) &&
         /^about:support/.test(doc.location.href)) {
        remove(E("reset-box", doc));
      }

      /* If health reporter upload is locked, remove the activation widget */
      if (Preferences.locked("datareporting.healthreport.uploadEnabled", false)) {
        if (/^https:\/\/fhr.cdn.mozilla.net\//.test(doc.location.href)) {
          var activationWidget = event.target.querySelector(".activationWidget");
          if (activationWidget) {
            remove(activationWidget);
          }
        }
      }
    } catch (e) {
      errorCritical(e);
    }
  }

  function disableSync() {
    window.XULBrowserWindow.inContentWhitelist =
      window.XULBrowserWindow.inContentWhitelist.filter(function(element) {
        return element != "about:sync-progress";
      })
    var mySyncUI = {
      init: function() {
        return;
      },
      initUI: function() {
        return;
      },
      updateUI: function() {
        hide(E("sync-setup-state"));
        hide(E("sync-syncnow-state"));
      }
    }
    gSyncUI = mySyncUI;
    remove(E("sync-button"));
  }

  function disablePrivateBrowsing() {
    disable(E("Tools:PrivateBrowsing"));
    hide(E("menu_newPrivateWindow"));
    // Because this is on a context menu, we can't use "hidden"
    if (E("context-openlinkprivate"))
      E("context-openlinkprivate").setAttribute("style", "display: none;");
    hide(E("appmenu_privateBrowsing"));
    hide(E("appmenu_newPrivateWindow"));
    hide(E("privateBrowsingItem"));
  }

  function disableAddonsManager() {
    window.XULBrowserWindow.inContentWhitelist =
      window.XULBrowserWindow.inContentWhitelist.filter(function(element) {
        return element != "about:addons";
      })
    hide(E("appmenu_addons"));
    hide(E("menu_openAddons"));
    disable(E("Tools:Addons"));
  }

  function removeDeveloperTools() {
    hide(E("webDeveloperMenu"));
    var devtoolsKeyset = document.getElementById("devtoolsKeyset");
    for (var i = 0; i < devtoolsKeyset.childNodes.length; i++) {
      devtoolsKeyset.childNodes[i].removeAttribute("command");
    }
    try {
      document.getElementById("Tools:ResponsiveUI").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:Scratchpad").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:BrowserConsole").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:BrowserToolbox").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:DevAppsMgr").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:DevToolbar").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:DevToolbox").removeAttribute("oncommand");
    } catch (e) {}
    try {
      document.getElementById("Tools:DevToolbarFocus").removeAttribute("oncommand");
    } catch (e) {}
  }

  function disableErrorConsole() {
    document.getElementById("Tools:ErrorConsole").removeAttribute("oncommand");
  }

  function startup()
  {
    try {
      window.removeEventListener("load", startup, false);
      window.XULBrowserWindow.inContentWhitelist =
        window.XULBrowserWindow.inContentWhitelist.filter(function(element) {
          return element != "about:preferences";
        })

      config = CCK2.getConfig();
      if (!config)
        return;

      if (config.disablePrivateBrowsing &&
          PrivateBrowsingUtils.isWindowPrivate(window)) {
        window.setTimeout(function() {
          Services.prompt.alert(window, "Private Browsing", "Private Browsing has been disabled by your administrator");
          window.close();
        }, 0, false);
      }
      if (config.disablePrivateBrowsing) {
        disablePrivateBrowsing();
      }
      if (config.disableSync) {
        disableSync();
      }
      E("appcontent").addEventListener("DOMContentLoaded", onPageLoad, false);

      if (config.disableAddonsManager) {
        disableAddonsManager();
      }
      if (config.removeDeveloperTools) {
        Services.tm.mainThread.dispatch(function() {
          removeDeveloperTools();
        }, Ci.nsIThread.DISPATCH_NORMAL);
      }
      if (config.disableErrorConsole) {
        disableErrorConsole();
      }
      if (config.removeSafeModeMenu) {
        hide(E("helpSafeMode"));
        try {
          hide(E("appmenu_safeMode"));
        } catch (e) {}
      }
      if (config.titlemodifier) {
        document.getElementById("main-window").setAttribute("titlemodifier", config.titlemodifier);
      }
      if (config.removeSetDesktopBackground) {
        // Because this is on a context menu, we can't use "hidden"
        if (E("context-setDesktopBackground"))
          E("context-setDesktopBackground").setAttribute("style", "display: none;");
        }
      if (config.hiddenUI) {
        for (var i=0; i < config.hiddenUI.length; i++) {
          var uiElements = document.querySelectorAll(config.hiddenUI[i]);
          if (!uiElements || uiElements.length == 0) {
            continue;
          }
          for (var i=0; i < uiElements.length; i++) {
            var uiElement = uiElements[i];
            hide(uiElement);
            if (uiElement.nodeName == "menuitem") {
              uiElement.removeAttribute("key");
              uiElement.removeAttribute("oncommand");
              if (uiElement.hasAttribute("command")) {
                var commandId = uiElement.getAttribute("command");
                uiElement.removeAttribute("command");
                var command = document.getElementById(commandId);
                command.removeAttribute("oncommand");
                var keys = document.querySelectorAll("key[command='" + commandId + "']")
                for (var i=0; i < keys.length; i++) {
                  keys[i].removeAttribute("command");
                }
              }
            }
          }
        }
      }
      if (config.helpMenu) {
        // We need to run this function on a delay, because we won't know
        // if the about menu is hidden for mac until after it is run.
        Services.tm.mainThread.dispatch(function() {
          var helpMenuPopup = document.getElementById("menu_HelpPopup");
          var menuitem = document.createElement("menuitem");
          menuitem.setAttribute("label", config.helpMenu.label);
          menuitem.setAttribute("url", config.helpMenu.url);
          menuitem.setAttribute("accesskey", config.helpMenu.accesskey);
          menuitem.addEventListener("command", function(event) {
            openUILink(this.getAttribute("url"), event, false, true);
          })
          menuitem.addEventListener("click", function(event) {
            checkForMiddleClick(this, event);
          }, false);
          if (E("aboutName").hidden) {
            // Mac
            helpMenuPopup.appendChild(menuitem);
          } else {
            helpMenuPopup.insertBefore(menuitem, E("aboutName"));
            helpMenuPopup.insertBefore(document.createElement("menuseparator"),
                                              E("aboutName"));
          }
        }, Ci.nsIThread.DISPATCH_NORMAL);
        var appMenuHelpMenuPopup = document.getElementById("appmenu_helpMenupopup");
        if (appMenuHelpMenuPopup) {
          var menuitem = document.createElement("menuitem");
          menuitem.setAttribute("label", config.helpMenu.label);
          menuitem.setAttribute("url", config.helpMenu.url);
          menuitem.addEventListener("command", function(event) {
            openUILink(this.getAttribute("url"), event, false, true);
          })
          menuitem.addEventListener("click", function(event) {
            checkForMiddleClick(this, event);
          }, false);
          appMenuHelpMenuPopup.insertBefore(menuitem, E("appmenu_about"));
          appMenuHelpMenuPopup.insertBefore(document.createElement("menuseparator"),
                                            E("appmenu_about"));
        }
      }
      if (CCK2.firstrun) {
        if (config.displayBookmarksToolbar || (config.bookmarks && config.bookmarks.toolbar)) {
          E("PersonalToolbar").collapsed = false;
          E("PersonalToolbar").setAttribute("collapsed", "false");
          document.persist("PersonalToolbar", "collapsed");
        }
        if (config.displayMenuBar) {
          if (typeof updateAppButtonDisplay != "undefined") {
            E("toolbar-menubar").setAttribute("autohide", "false");
            document.persist("toolbar-menubar", "autohide")
            updateAppButtonDisplay();
          }
        }
        CCK2.firstrun = false;
      }
    } catch (e) {
      errorCritical(e);
    }
  }

  function shutdown()
  {
    window.removeEventListener("unload", shutdown, false);
    var appcontent = E("appcontent");
    if (appcontent) {
       appcontent.removeEventListener("DOMContentLoaded", onPageLoad, false);
    }
  }

  window.addEventListener("load", startup, false);
  window.addEventListener("unload", shutdown, false);
})();
<|endoftext|>


<commit_before>import path from "path";
import webpack from "webpack";
import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin";
import { WebpackManifestPlugin } from "webpack-manifest-plugin";
import TerserPlugin from "terser-webpack-plugin";
import MiniCssExtractPlugin from "mini-css-extract-plugin";
import CssMinimizerPlugin from "css-minimizer-webpack-plugin";
import CompressionPlugin from "compression-webpack-plugin";
import ImageMinimizerPlugin from "image-minimizer-webpack-plugin";
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";
import { BundleAnalyzerPlugin } from "webpack-bundle-analyzer";
import LoadablePlugin from "@loadable/webpack-plugin";

const isDev = process.env.NODE_ENV !== "production";

// Loaders for CSS and SASS
const getStyleLoaders = (sass) =>
  [
    MiniCssExtractPlugin.loader,
    {
      loader: "css-loader",
      options: {
        importLoaders: sass ? 2 : 1,
        modules: {
          auto: true,
          localIdentName: isDev ? "[path][name]__[local]" : "[hash:base64]",
        },
      },
    },
    { loader: "postcss-loader", options: { sourceMap: isDev } },
    sass && { loader: "sass-loader", options: { sourceMap: isDev } },
  ].filter(Boolean);

// Webpack configuration
module.exports = {
  mode: isDev ? "development" : "production",
  devtool: isDev && "eval-source-map",
  stats: "minimal",
  context: path.resolve(process.cwd()),
  entry: [
    isDev && "webpack-hot-middleware/client?reload=true",
    "./src/client",
  ].filter(Boolean),
  optimization: { minimizer: [new TerserPlugin(), new CssMinimizerPlugin()] },
  output: {
    path: path.resolve(process.cwd(), "public/assets"),
    publicPath: "/assets/",
    filename: isDev ? "[name].js" : "[name].[contenthash].js",
    chunkFilename: isDev ? "[id].js" : "[id].[contenthash].js",
  },
  module: {
    rules: [
      {
        test: /\.(t|j)sx?$/,
        exclude: /node_modules/,
        loader: "babel-loader",
        options: { cacheDirectory: isDev },
      },
      // All output '.js' files will have any sourcemaps re-processed by source-map-loader.
      // So you can debug your output code as if it was TypeScript.
      {
        enforce: "pre",
        test: /\.js$/,
        loader: "source-map-loader",
      },
      {
        test: /\.css$/,
        use: getStyleLoaders(),
      },
      {
        test: /\.(scss|sass)$/,
        use: getStyleLoaders(true),
      },
      {
        test: /\.(woff2?|eot|ttf|otf)$/i,
        type: "asset",
      },
      {
        test: /\.(png|svg|jpe?g|gif)$/i,
        type: "asset",
      },
    ],
  },
  plugins: [
    new WebpackManifestPlugin({
      fileName: path.resolve(process.cwd(), "public/webpack-assets.json"),
      filter: (file) => file.isInitial,
    }),
    new LoadablePlugin({
      writeToDisk: true,
      filename: "../loadable-stats.json",
    }),
    new MiniCssExtractPlugin({
      // Don't use hash in development, we need the persistent for "renderHtml.ts"
      filename: isDev ? "[name].css" : "[name].[contenthash].css",
      chunkFilename: isDev ? "[id].css" : "[id].[contenthash].css",
    }),
    // Setup global variables for client
    new webpack.DefinePlugin({
      __CLIENT__: true,
      __SERVER__: false,
      __DEV__: isDev,
    }),
    new webpack.ProgressPlugin(),
    isDev && new webpack.HotModuleReplacementPlugin(),
    isDev &&
      new ReactRefreshWebpackPlugin({ overlay: { sockIntegration: "whm" } }),
    // Runs typescript type checker on a separate process
    isDev &&
      new ForkTsCheckerWebpackPlugin({
        // (Required) Same as eslint command
        eslint: { files: "./src/**/*.{js,jsx,ts,tsx}" },
      }),
    // Prepare compressed versions of assets to serve them with Content-Encoding
    !isDev && new CompressionPlugin(),
    !isDev &&
      new ImageMinimizerPlugin({
        // Lossless optimization with default option, feel free to experiment with options for better result for you
        // See https://github.com/webpack-contrib/image-minimizer-webpack-plugin#getting-started
        minimizerOptions: {
          plugins: [["gifsicle"], ["jpegtran"], ["optipng"], ["svgo"]],
        },
      }),
    // Visualize all of the webpack bundles
    // Check "https://github.com/webpack-contrib/webpack-bundle-analyzer#options-for-plugin" for more configurations
    !isDev &&
      new BundleAnalyzerPlugin({
        analyzerMode:
          process.env.NODE_ENV === "analyze" ? "server" : "disabled",
      }),
  ].filter(Boolean),
  resolve: {
    modules: ["src", "node_modules"],
    descriptionFiles: ["package.json"],
    extensions: [".js", ".jsx", ".ts", ".tsx", ".json"],
  },
};
<commit_msg>Chore: remove resolve.descriptionFiles<commit_after>import path from "path";
import webpack from "webpack";
import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin";
import { WebpackManifestPlugin } from "webpack-manifest-plugin";
import TerserPlugin from "terser-webpack-plugin";
import MiniCssExtractPlugin from "mini-css-extract-plugin";
import CssMinimizerPlugin from "css-minimizer-webpack-plugin";
import CompressionPlugin from "compression-webpack-plugin";
import ImageMinimizerPlugin from "image-minimizer-webpack-plugin";
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";
import { BundleAnalyzerPlugin } from "webpack-bundle-analyzer";
import LoadablePlugin from "@loadable/webpack-plugin";

const isDev = process.env.NODE_ENV !== "production";

// Loaders for CSS and SASS
const getStyleLoaders = (sass) =>
  [
    MiniCssExtractPlugin.loader,
    {
      loader: "css-loader",
      options: {
        importLoaders: sass ? 2 : 1,
        modules: {
          auto: true,
          localIdentName: isDev ? "[path][name]__[local]" : "[hash:base64]",
        },
      },
    },
    { loader: "postcss-loader", options: { sourceMap: isDev } },
    sass && { loader: "sass-loader", options: { sourceMap: isDev } },
  ].filter(Boolean);

// Webpack configuration
module.exports = {
  mode: isDev ? "development" : "production",
  devtool: isDev && "eval-source-map",
  stats: "minimal",
  context: path.resolve(process.cwd()),
  entry: [
    isDev && "webpack-hot-middleware/client?reload=true",
    "./src/client",
  ].filter(Boolean),
  optimization: { minimizer: [new TerserPlugin(), new CssMinimizerPlugin()] },
  output: {
    path: path.resolve(process.cwd(), "public/assets"),
    publicPath: "/assets/",
    filename: isDev ? "[name].js" : "[name].[contenthash].js",
    chunkFilename: isDev ? "[id].js" : "[id].[contenthash].js",
  },
  module: {
    rules: [
      {
        test: /\.(t|j)sx?$/,
        exclude: /node_modules/,
        loader: "babel-loader",
        options: { cacheDirectory: isDev },
      },
      // All output '.js' files will have any sourcemaps re-processed by source-map-loader.
      // So you can debug your output code as if it was TypeScript.
      {
        enforce: "pre",
        test: /\.js$/,
        loader: "source-map-loader",
      },
      {
        test: /\.css$/,
        use: getStyleLoaders(),
      },
      {
        test: /\.(scss|sass)$/,
        use: getStyleLoaders(true),
      },
      {
        test: /\.(woff2?|eot|ttf|otf)$/i,
        type: "asset",
      },
      {
        test: /\.(png|svg|jpe?g|gif)$/i,
        type: "asset",
      },
    ],
  },
  plugins: [
    new WebpackManifestPlugin({
      fileName: path.resolve(process.cwd(), "public/webpack-assets.json"),
      filter: (file) => file.isInitial,
    }),
    new LoadablePlugin({
      writeToDisk: true,
      filename: "../loadable-stats.json",
    }),
    new MiniCssExtractPlugin({
      // Don't use hash in development, we need the persistent for "renderHtml.ts"
      filename: isDev ? "[name].css" : "[name].[contenthash].css",
      chunkFilename: isDev ? "[id].css" : "[id].[contenthash].css",
    }),
    // Setup global variables for client
    new webpack.DefinePlugin({
      __CLIENT__: true,
      __SERVER__: false,
      __DEV__: isDev,
    }),
    new webpack.ProgressPlugin(),
    isDev && new webpack.HotModuleReplacementPlugin(),
    isDev &&
      new ReactRefreshWebpackPlugin({ overlay: { sockIntegration: "whm" } }),
    // Runs typescript type checker on a separate process
    isDev &&
      new ForkTsCheckerWebpackPlugin({
        // (Required) Same as eslint command
        eslint: { files: "./src/**/*.{js,jsx,ts,tsx}" },
      }),
    // Prepare compressed versions of assets to serve them with Content-Encoding
    !isDev && new CompressionPlugin(),
    !isDev &&
      new ImageMinimizerPlugin({
        // Lossless optimization with default option, feel free to experiment with options for better result for you
        // See https://github.com/webpack-contrib/image-minimizer-webpack-plugin#getting-started
        minimizerOptions: {
          plugins: [["gifsicle"], ["jpegtran"], ["optipng"], ["svgo"]],
        },
      }),
    // Visualize all of the webpack bundles
    // Check "https://github.com/webpack-contrib/webpack-bundle-analyzer#options-for-plugin" for more configurations
    !isDev &&
      new BundleAnalyzerPlugin({
        analyzerMode:
          process.env.NODE_ENV === "analyze" ? "server" : "disabled",
      }),
  ].filter(Boolean),
  resolve: {
    modules: ["src", "node_modules"],
    extensions: [".js", ".jsx", ".ts", ".tsx", ".json"],
  },
};
<|endoftext|>


<commit_before>/*!
* deja
* Copyright(c) 2011 Mike Cantelon
* MIT Licensed
*/

var path = require('path'),
  fs = require('fs'),
  spawn = require('child_process').spawn,
  wrench = require('wrench'),
  helpers = require('./deja_helpers')

exports.usage = function() {

  return "Usage:\n\
  deja clone <GIT REPO URL>\n\
  deja ls [REPO NAME][/SUBDIRECTORY]\n\
  deja pull <REPO NAME>\n\
  deja rm <REPO NAME>\n\
  deja diff <REPO NAME>\n\
  deja link <REPO NAME>[/SUBDIRECTORY]\n\
  deja unlink <REPO NAME>[/SUBDIRECTORY]\n\
  deja version"
}

exports.ls = function(home, dejaHome, repo) {

  var pathToRepo = dejaHome,
      subDir

  pathToRepo += (repo) ? '/' + repo : ''

  if (repo) {
    var repoAndSubDir = parseOutRepoAndSubdir(repo)
    subDir = repoAndSubDir.subDir
    subDir = (subDir != '')
      ? '/' + subDir
      : ''
  }

  path.exists(pathToRepo, function(exists) {

    if (exists) {
      helpers.traverseDir(pathToRepo, function(entry) {

        if (entry != '.git') {

          // if listing files in a repo, output status info for each file
          (repo)
            ? helpers.outputEntryAndInfo(entry, pathToRepo, home + subDir + '/' + entry)
            : console.log(entry)
        }
      })
    }
    else {
      console.log('Error: directory not found.')
    }
  })
}

exports.cloneRepo = function(home, dejaHome, repoUrl, config) {

  config = config || {}

  // allow user to leave off .git or .git/
  if (repoUrl.indexOf('.git') == -1) {
    repoUrl = repoUrl + '.git'
  }

  // default to Github if protocal not specified
  if (repoUrl.indexOf(':') == -1) {
    // if "username/repo" format not used, get from config
    if (repoUrl.indexOf('/') == -1) {

      if (config.github_user) {

        repoUrl = config.github_user + '/' + repoUrl
      }
      else {

        console.log('Error: Github repo name only specified, but no github_user defined in .dejaconfig.')
        process.exit(1)
      }
    }

    repoUrl = 'git://github.com/' + repoUrl
  }

  var basename = helpers.findUnusedBasename(dejaHome, repoUrl, function(basename) {

    var pathToRepo = dejaHome + '/' + basename

    path.exists(pathToRepo, function(exists) {

      if (exists) {

        console.log('Error: Repo already exists.')
        process.exit(1)
      }
      else {

        console.log('Cloning repository...')

        var clone = spawn('git', ['clone', repoUrl, pathToRepo])

        clone.on('exit', function(code) {

          if (code != 0) {

            console.log('Error: could not clone.')
            process.exit(code)
          }
          else {

            // check if the repo has submodules
            path.exists(pathToRepo + '/.gitmodules', function(exists) {

              // if submodules found, initialize and update them
              if (exists) {

                console.log('Initializing and updating submodules...')
                process.chdir(pathToRepo)

                var submodules = spawn('git', ['submodule', 'update', '--init'])

                submodules.on('exit', function(code) {
                  // create symlinks to items in first level of repo directory
                  exports.linkRepo(home, dejaHome, basename)
                })
              }
              else {

                // create symlinks to items in first level of repo directory
                exports.linkRepo(home, dejaHome, basename)
              }
            })
          }
        })
      }
    })
  })
}

function parseOutRepoAndSubdir(repo) {

  var pathData,
      subDir = ''

  // if repo contains slashes, then user wants to link a repo subdirectory
  if (repo.indexOf('/') != -1) {

    pathData = repo.split('/')
    repo = pathData.shift()
    subDir = pathData.join('/')
  }

  return {
    repo:   repo,
    subDir: subDir
  }
}

exports.linkRepo = function(home, dejaHome, repo) {

  var pathToRepo = dejaHome + '/' + repo,
      subDir

  var repoAndSubDir = parseOutRepoAndSubdir(repo)
  repo = repoAndSubDir.repo
  subDir = repoAndSubDir.subDir
  subDir += (subDir != '')
    ? '/'
    : ''

  var symlinkRootPath = home + '/' + subDir

  path.exists(symlinkRootPath, function(exists) {

    if (exists) {

      console.log('Creating symbolic links...')

      // cycle through cloned repo making symlinks to home
      helpers.traverseDir(pathToRepo, function(file) {

        if (file != '.git') {

          var filePath     = pathToRepo + '/' + file
          var symlinkPath  = symlinkRootPath + file

          helpers.createSymlinkIfPathExists(symlinkPath, filePath)
        }
      })
    }
    else {

      console.log('Error: Not a valid repo.')
    }
  })
}

exports.pullRepo = function (dejaHome, repo) {

  var pathToRepo = dejaHome + '/' + repo

  path.exists(pathToRepo, function(exists) {

    if (exists) {

      console.log('Pulling...')

      process.chdir(pathToRepo)

      var pull = spawn('git', ['pull'])

      pull.on('exit', function(code) {

        console.log((code == 0)
          ? 'Pull complete.'
          : 'Error: Could not pull.'
        )

        process.exit(code)
      })
    }
    else {

      console.log('Error: Not a valid repo.')
    }
  })
}

exports.rmRepo = function(home, dejaHome, repo) {

  var pathToRepo = dejaHome + '/' + repo

  path.exists(pathToRepo, function(exists) {

    if (exists) {

      helpers.deleteSymlinksToRepo(home, pathToRepo)
      wrench.rmdirSyncRecursive(pathToRepo)
      console.log('Repo removed.')
    }
    else {

      console.log('Error: Not a valid repo.')
    }
  })
}

exports.unlinkRepo = function(home, dejaHome, repo) {

  var pathToRepo = dejaHome + '/' + repo,
      subDir

  var repoAndSubDir = parseOutRepoAndSubdir(repo)
  subDir = repoAndSubDir.subDir
  subDir = (subDir != '')
    ? '/' + subDir
    : ''

  path.exists(pathToRepo, function(exists) {

    if (exists) {
      helpers.deleteSymlinksToRepo(home + subDir, pathToRepo)
    }
    else {
      console.log('Error: Not a valid repo.')
    }
  })
}

exports.diffRepo = function (home, dejaHome, repo) {

  var pathToRepo = dejaHome + '/' + repo,
      subDir

  var repoAndSubDir = parseOutRepoAndSubdir(repo)
  repo = repoAndSubDir.repo
  subDir = repoAndSubDir.subDir
  subDir = (subDir != '')
    ? '/' + subDir
    : ''

  path.exists(pathToRepo, function(exists) {

    if (exists) {

      path.exists(home + subDir, function(exists) {

        if (exists) {

          var diff = spawn('diff', [home + subDir, pathToRepo])

          diff.stdout.on('data', function (data) {
            console.log(data.toString())
          })
        }
        else {

          console.log('Error: Not a valid home directory.')
        }
      })
    }
    else {

      console.log('Error: Not a valid repo.')
    }
  })
}

exports.version = function() {

  var package_json = fs.readFileSync(__dirname + '/../package.json')
  var package_data = JSON.parse(package_json)
  return 'deja version ' + package_data.version
}
<commit_msg>Made it so reop clones done with Github username in config default to writable form.<commit_after>/*!
* deja
* Copyright(c) 2011 Mike Cantelon
* MIT Licensed
*/

var path = require('path'),
  fs = require('fs'),
  spawn = require('child_process').spawn,
  wrench = require('wrench'),
  helpers = require('./deja_helpers')

exports.usage = function() {

  return "Usage:\n\
  deja clone <GIT REPO URL>\n\
  deja ls [REPO NAME][/SUBDIRECTORY]\n\
  deja pull <REPO NAME>\n\
  deja rm <REPO NAME>\n\
  deja diff <REPO NAME>\n\
  deja link <REPO NAME>[/SUBDIRECTORY]\n\
  deja unlink <REPO NAME>[/SUBDIRECTORY]\n\
  deja version"
}

exports.ls = function(home, dejaHome, repo) {

  var pathToRepo = dejaHome,
      subDir

  pathToRepo += (repo) ? '/' + repo : ''

  if (repo) {
    var repoAndSubDir = parseOutRepoAndSubdir(repo)
    subDir = repoAndSubDir.subDir
    subDir = (subDir != '')
      ? '/' + subDir
      : ''
  }

  path.exists(pathToRepo, function(exists) {

    if (exists) {
      helpers.traverseDir(pathToRepo, function(entry) {

        if (entry != '.git') {

          // if listing files in a repo, output status info for each file
          (repo)
            ? helpers.outputEntryAndInfo(entry, pathToRepo, home + subDir + '/' + entry)
            : console.log(entry)
        }
      })
    }
    else {
      console.log('Error: directory not found.')
    }
  })
}

exports.cloneRepo = function(home, dejaHome, repoUrl, config) {

  config = config || {}

  // allow user to leave off .git or .git/
  if (repoUrl.indexOf('.git') == -1) {
    repoUrl = repoUrl + '.git'
  }

  // default to Github if protocal not specified
  if (repoUrl.indexOf(':') == -1) {
    // if "username/repo" format not used, get from config
    if (repoUrl.indexOf('/') == -1) {

      if (config.github_user) {

        repoUrl = 'git@github.com:' + config.github_user + '/' + repoUrl
      }
      else {

        console.log('Error: Github repo name only specified, but no github_user defined in .dejaconfig.')
        process.exit(1)
      }
    }
    else {

      repoUrl = 'git://github.com/' + repoUrl
    }
  }

  var basename = helpers.findUnusedBasename(dejaHome, repoUrl, function(basename) {

    var pathToRepo = dejaHome + '/' + basename

    path.exists(pathToRepo, function(exists) {

      if (exists) {

        console.log('Error: Repo already exists.')
        process.exit(1)
      }
      else {

        console.log('Cloning repository...')

        var clone = spawn('git', ['clone', repoUrl, pathToRepo])

        clone.on('exit', function(code) {

          if (code != 0) {

            console.log('Error: could not clone.')
            process.exit(code)
          }
          else {

            // check if the repo has submodules
            path.exists(pathToRepo + '/.gitmodules', function(exists) {

              // if submodules found, initialize and update them
              if (exists) {

                console.log('Initializing and updating submodules...')
                process.chdir(pathToRepo)

                var submodules = spawn('git', ['submodule', 'update', '--init'])

                submodules.on('exit', function(code) {
                  // create symlinks to items in first level of repo directory
                  exports.linkRepo(home, dejaHome, basename)
                })
              }
              else {

                // create symlinks to items in first level of repo directory
                exports.linkRepo(home, dejaHome, basename)
              }
            })
          }
        })
      }
    })
  })
}

function parseOutRepoAndSubdir(repo) {

  var pathData,
      subDir = ''

  // if repo contains slashes, then user wants to link a repo subdirectory
  if (repo.indexOf('/') != -1) {

    pathData = repo.split('/')
    repo = pathData.shift()
    subDir = pathData.join('/')
  }

  return {
    repo:   repo,
    subDir: subDir
  }
}

exports.linkRepo = function(home, dejaHome, repo) {

  var pathToRepo = dejaHome + '/' + repo,
      subDir

  var repoAndSubDir = parseOutRepoAndSubdir(repo)
  repo = repoAndSubDir.repo
  subDir = repoAndSubDir.subDir
  subDir += (subDir != '')
    ? '/'
    : ''

  var symlinkRootPath = home + '/' + subDir

  path.exists(symlinkRootPath, function(exists) {

    if (exists) {

      console.log('Creating symbolic links...')

      // cycle through cloned repo making symlinks to home
      helpers.traverseDir(pathToRepo, function(file) {

        if (file != '.git') {

          var filePath     = pathToRepo + '/' + file
          var symlinkPath  = symlinkRootPath + file

          helpers.createSymlinkIfPathExists(symlinkPath, filePath)
        }
      })
    }
    else {

      console.log('Error: Not a valid repo.')
    }
  })
}

exports.pullRepo = function (dejaHome, repo) {

  var pathToRepo = dejaHome + '/' + repo

  path.exists(pathToRepo, function(exists) {

    if (exists) {

      console.log('Pulling...')

      process.chdir(pathToRepo)

      var pull = spawn('git', ['pull'])

      pull.on('exit', function(code) {

        console.log((code == 0)
          ? 'Pull complete.'
          : 'Error: Could not pull.'
        )

        process.exit(code)
      })
    }
    else {

      console.log('Error: Not a valid repo.')
    }
  })
}

exports.rmRepo = function(home, dejaHome, repo) {

  var pathToRepo = dejaHome + '/' + repo

  path.exists(pathToRepo, function(exists) {

    if (exists) {

      helpers.deleteSymlinksToRepo(home, pathToRepo)
      wrench.rmdirSyncRecursive(pathToRepo)
      console.log('Repo removed.')
    }
    else {

      console.log('Error: Not a valid repo.')
    }
  })
}

exports.unlinkRepo = function(home, dejaHome, repo) {

  var pathToRepo = dejaHome + '/' + repo,
      subDir

  var repoAndSubDir = parseOutRepoAndSubdir(repo)
  subDir = repoAndSubDir.subDir
  subDir = (subDir != '')
    ? '/' + subDir
    : ''

  path.exists(pathToRepo, function(exists) {

    if (exists) {
      helpers.deleteSymlinksToRepo(home + subDir, pathToRepo)
    }
    else {
      console.log('Error: Not a valid repo.')
    }
  })
}

exports.diffRepo = function (home, dejaHome, repo) {

  var pathToRepo = dejaHome + '/' + repo,
      subDir

  var repoAndSubDir = parseOutRepoAndSubdir(repo)
  repo = repoAndSubDir.repo
  subDir = repoAndSubDir.subDir
  subDir = (subDir != '')
    ? '/' + subDir
    : ''

  path.exists(pathToRepo, function(exists) {

    if (exists) {

      path.exists(home + subDir, function(exists) {

        if (exists) {

          var diff = spawn('diff', [home + subDir, pathToRepo])

          diff.stdout.on('data', function (data) {
            console.log(data.toString())
          })
        }
        else {

          console.log('Error: Not a valid home directory.')
        }
      })
    }
    else {

      console.log('Error: Not a valid repo.')
    }
  })
}

exports.version = function() {

  var package_json = fs.readFileSync(__dirname + '/../package.json')
  var package_data = JSON.parse(package_json)
  return 'deja version ' + package_data.version
}
<|endoftext|>


<commit_before>import $ from 'jquery';

import ImageFullscreenWidget from '../../common/Viewer/ImageFullscreenWidget';
import View from '../../view';

import ImageWallTemplate from './imageWall.pug';
import './imageWall.styl';

const ImageWall = View.extend({
    className: 'isic-images-imageWall',

    events: {
        'click .isic-images-imageWall-thumbnail': function (event) {
            let imageId = $(event.currentTarget).data('imageId');
            let clickedImage = this.images.get(imageId);

            if (event.shiftKey) {
                new ImageFullscreenWidget({ // eslint-disable-line no-new
                    el: $('#g-dialog-container'),
                    model: clickedImage,
                    parentView: this
                }).render();
            } else {
                clickedImage.toggleSelected();
            }
        },

        'click .isic-images-imageWall-zoom': function (event) {
            event.stopPropagation();

            let imageId = $(event.currentTarget).parent().parent().data('imageId');
            let clickedImage = this.images.get(imageId);

            new ImageFullscreenWidget({ // eslint-disable-line no-new
                el: $('#g-dialog-container'),
                model: clickedImage,
                parentView: this
            }).render();
        }
    },

    /**
     * @param {SelectableImageCollection} settings.images
     */
    initialize: function (settings) {
        this.images = settings.images;
        // For now we'll hard code this (and probably change it in the future), depending on the
        // page size
        this.thumbnailSize = 128;

        // TODO: could this event be simply 'update'? (it should not fire when sub-models are directly fetched)
        this.listenTo(this.images, 'g:changed', this.render);
        this.listenTo(this.images, 'select:one deselect:one', this._rerenderSelection);
    },

    render: function () {
        // Since tooltip-enabled elements are about to be destroyed, first remove any active
        // tooltips from them.
        this.clearTooltips();

        this.$el.html(ImageWallTemplate({
            apiRoot: this.apiRoot,
            images: this.images,
            thumbnailHeight: this.thumbnailSize * 0.75,
            thumbnailWidth: this.thumbnailSize
        }));

        this.$('[data-toggle="tooltip"]').tooltip({
            placement: 'auto',
            viewport: this.$el,
            trigger: 'hover'
        });

        return this;
    },

    _rerenderSelection: function () {
        this.$('.isic-images-imageWall-thumbnail').removeClass('selected');

        let selectedImage = this.images.selected;
        if (selectedImage) {
            this.$(`.isic-images-imageWall-thumbnail[data-image-id="${selectedImage.id}"]`).addClass('selected');
        }
    },

    clearTooltips: function () {
        this.$('[data-toggle="tooltip"]').tooltip('hide');
        // For unknown reasons, tooltips sometimes remain after they've been hidden, so manually
        // destroy the tooltip element.
        this.$('.tooltip').remove();
    }
});

export default ImageWall;
<commit_msg>Refactor common logic into a utility function<commit_after>import $ from 'jquery';

import ImageFullscreenWidget from '../../common/Viewer/ImageFullscreenWidget';
import View from '../../view';

import ImageWallTemplate from './imageWall.pug';
import './imageWall.styl';

const ImageWall = View.extend({
    className: 'isic-images-imageWall',

    events: {
        'click .isic-images-imageWall-thumbnail': function (event) {
            let imageId = $(event.currentTarget).data('imageId');
            let clickedImage = this.images.get(imageId);

            if (event.shiftKey) {
                this._showImageZoomModal(clickedImage);
            } else {
                clickedImage.toggleSelected();
            }
        },

        'click .isic-images-imageWall-zoom': function (event) {
            event.stopPropagation();

            let imageId = $(event.currentTarget).parent().parent().data('imageId');
            let clickedImage = this.images.get(imageId);

            this._showImageZoomModal(clickedImage);
        }
    },

    /**
     * @param {SelectableImageCollection} settings.images
     */
    initialize: function (settings) {
        this.images = settings.images;
        // For now we'll hard code this (and probably change it in the future), depending on the
        // page size
        this.thumbnailSize = 128;

        // TODO: could this event be simply 'update'? (it should not fire when sub-models are directly fetched)
        this.listenTo(this.images, 'g:changed', this.render);
        this.listenTo(this.images, 'select:one deselect:one', this._rerenderSelection);
    },

    render: function () {
        // Since tooltip-enabled elements are about to be destroyed, first remove any active
        // tooltips from them.
        this.clearTooltips();

        this.$el.html(ImageWallTemplate({
            apiRoot: this.apiRoot,
            images: this.images,
            thumbnailHeight: this.thumbnailSize * 0.75,
            thumbnailWidth: this.thumbnailSize
        }));

        this.$('[data-toggle="tooltip"]').tooltip({
            placement: 'auto',
            viewport: this.$el,
            trigger: 'hover'
        });

        return this;
    },

    _rerenderSelection: function () {
        this.$('.isic-images-imageWall-thumbnail').removeClass('selected');

        let selectedImage = this.images.selected;
        if (selectedImage) {
            this.$(`.isic-images-imageWall-thumbnail[data-image-id="${selectedImage.id}"]`).addClass('selected');
        }
    },

    clearTooltips: function () {
        this.$('[data-toggle="tooltip"]').tooltip('hide');
        // For unknown reasons, tooltips sometimes remain after they've been hidden, so manually
        // destroy the tooltip element.
        this.$('.tooltip').remove();
    },

    _showImageZoomModal: function (image) {
        new ImageFullscreenWidget({ // eslint-disable-line no-new
            el: $('#g-dialog-container'),
            model: image,
            parentView: this
        }).render();
    }
});

export default ImageWall;
<|endoftext|>