<commit_before>function editDetailsGet (req, res) {
  res
    .breadcrumb('Edit details')
    .render('investment-projects/views/details-edit')
}

function editValueGet (req, res) {
  res
    .breadcrumb('Edit value')
    .render('investment-projects/views/value-edit')
}

function editRequirementsGet (req, res) {
  res.render('investment-projects/views/requirements-edit')
}

function editDetailsPost (req, res) {
  if (res.locals.form.errors) {
    return res.render('investment-projects/views/details-edit')
  }
  req.flash('success', 'Updated investment details')
  return res.redirect(`/investment-projects/${res.locals.resultId}/details`)
}

function editValuePost (req, res) {
  if (res.locals.form.errors) {
    return res.render('investment-projects/views/value-edit')
  }
  req.flash('success', 'Updated investment value')
  return res.redirect(`/investment-projects/${res.locals.projectId}/details`)
}

function editRequirementsPost (req, res) {
  if (res.locals.form.errors) {
    req.flash('success', 'Updated investment requirements')
    return res.render('investment-projects/views/requirements-edit')
  }
  return res.redirect(`/investment-projects/${res.locals.projectId}/details`)
}

module.exports = {
  editDetailsGet,
  editValueGet,
  editRequirementsGet,
  editDetailsPost,
  editValuePost,
  editRequirementsPost,
}
<commit_msg>Add breadcrumb to edit value page<commit_after>function editDetailsGet (req, res) {
  res
    .breadcrumb('Edit details')
    .render('investment-projects/views/details-edit')
}

function editValueGet (req, res) {
  res
    .breadcrumb('Edit value')
    .render('investment-projects/views/value-edit')
}

function editRequirementsGet (req, res) {
  res.render('investment-projects/views/requirements-edit')
}

function editDetailsPost (req, res) {
  if (res.locals.form.errors) {
    return res.render('investment-projects/views/details-edit')
  }
  req.flash('success', 'Updated investment details')
  return res.redirect(`/investment-projects/${res.locals.resultId}/details`)
}

function editValuePost (req, res) {
  if (res.locals.form.errors) {
    return res
      .breadcrumb('Edit value')
      .render('investment-projects/views/value-edit')
  }
  req.flash('success', 'Updated investment value')
  return res.redirect(`/investment-projects/${res.locals.projectId}/details`)
}

function editRequirementsPost (req, res) {
  if (res.locals.form.errors) {
    req.flash('success', 'Updated investment requirements')
    return res.render('investment-projects/views/requirements-edit')
  }
  return res.redirect(`/investment-projects/${res.locals.projectId}/details`)
}

module.exports = {
  editDetailsGet,
  editValueGet,
  editRequirementsGet,
  editDetailsPost,
  editValuePost,
  editRequirementsPost,
}
<|endoftext|>


<commit_before>(function () {
  'use strict';

  angular.module('exceptionless.billing')
    .controller('ChangePlanDialog', function ($uibModalInstance, adminService, analyticsService, Common, $ExceptionlessClient, $intercom, INTERCOM_APPID, notificationService, organizationService, stripe, STRIPE_PUBLISHABLE_KEY, userService, translateService, $window, data) {
      var vm = this;
      function cancel() {
        analyticsService.lead(getAnalyticsData());
        $ExceptionlessClient.createFeatureUsage(vm._source + '.cancel')
          .setProperty('CurrentPlan', vm.currentPlan)
          .setProperty('CouponId', vm.coupon)
          .setProperty('IsNewCard', isNewCard())
          .setProperty('OrganizationId', vm.currentOrganization.id)
          .submit();

        $uibModalInstance.dismiss('cancel');
      }

      function createStripeToken() {
        function onSuccess(response) {
          analyticsService.addPaymentInfo();
          return response;
        }

        var expiration = Common.parseExpiry(vm.card.expiry);
        var payload = {
          number: vm.card.number,
          cvc: vm.card.cvc,
          exp_month: expiration.month,
          exp_year: expiration.year,
          name: vm.card.name
        };

        return stripe.card.createToken(payload).then(onSuccess);
      }

      function getAnalyticsData() {
        return { content_name: vm.currentPlan.name, content_ids: [vm.currentPlan.id], content_type: 'product', currency: 'USD', value: vm.currentPlan.price };
      }

      function save(isValid) {
        function onCreateTokenSuccess(response) {
          return changePlan(false, { stripeToken: response.id, last4: response.card.last4, couponId: vm.coupon }).then(onSuccess, onFailure);
        }

        function onSuccess(response) {
          if(!response.data.success) {
            analyticsService.lead(getAnalyticsData());
            vm.paymentMessage = translateService.T('An error occurred while changing plans.') + ' ' + translateService.T('Message:') + ' ' + response.data.message;
            $ExceptionlessClient.createException(new Error(response.data.message))
              .markAsCritical()
              .setSource(vm._source + '.save.error')
              .setProperty('CurrentPlan', vm.currentPlan)
              .setProperty('CouponId', vm.coupon)
              .setProperty('IsNewCard', isNewCard())
              .setProperty('OrganizationId', vm.currentOrganization.id)
              .submit();

            return;
          }

          analyticsService.purchase(getAnalyticsData());
          $ExceptionlessClient.createFeatureUsage(vm._source + '.save')
            .markAsCritical()
            .setMessage(response.data.message)
            .setProperty('CurrentPlan', vm.currentPlan)
            .setProperty('CouponId', vm.coupon)
            .setProperty('IsNewCard', isNewCard())
            .setProperty('OrganizationId', vm.currentOrganization.id)
            .submit();

          $uibModalInstance.close(vm.currentPlan);
          notificationService.success(translateService.T('Thanks! Your billing plan has been successfully changed.'));
        }

        function onFailure(response) {
          if (response.error && response.error.message) {
            vm.paymentMessage = response.error.message;
          } else {
            vm.paymentMessage = translateService.T('An error occurred while changing plans.');
          }

          analyticsService.lead(getAnalyticsData());
          $ExceptionlessClient.createException(new Error(vm.paymentMessage))
            .markAsCritical()
            .setSource(vm._source + '.save.error')
            .setProperty('CurrentPlan', vm.currentPlan)
            .setProperty('CouponId', vm.coupon)
            .setProperty('IsNewCard', isNewCard())
            .setProperty('OrganizationId', vm.currentOrganization.id)
            .submit();
        }

        if (!isValid || !vm.currentPlan) {
          return;
        }

        vm.paymentMessage = null;
        if (vm.currentOrganization.plan_id === vm._freePlanId && vm.currentPlan.id === vm._freePlanId) {
          cancel();
          return;
        }

        if (hasAdminRole() || vm.currentPlan.id === vm._freePlanId) {
          return changePlan(hasAdminRole()).then(onSuccess, onFailure);
        }

        if (vm.currentPlan.price > 0 && isNewCard()) {
          try {
            return createStripeToken().then(onCreateTokenSuccess, onFailure);
          } catch (error) {
            vm.paymentMessage = translateService.T('An error occurred while changing plans.');
            $ExceptionlessClient.createException(error)
              .markAsCritical()
              .setSource(vm._source + '.save.error')
              .setProperty('CurrentPlan', vm.currentPlan)
              .setProperty('CouponId', vm.coupon)
              .setProperty('IsNewCard', isNewCard())
              .setProperty('OrganizationId', vm.currentOrganization.id)
              .submit();
            return null;
          }
        }

        return changePlan(false, { couponId: vm.coupon }).then(onSuccess, onFailure);
      }

      function changeOrganization() {
        vm.card.mode = hasExistingCard() ? 'existing' : 'new';
        return getPlans();
      }

      function changePlan(isAdmin, options) {
        if (isAdmin) {
          return adminService.changePlan({ organizationId: vm.currentOrganization.id, planId: vm.currentPlan.id });
        } else {
          return organizationService.changePlan(vm.currentOrganization.id, angular.extend({}, { planId: vm.currentPlan.id }, options));
        }
      }

      function getOrganizations() {
        function getSelectedOrganization() {
          function onSuccess(response) {
            vm.organizations.push(response.data.plain());
            return vm.organizations;
          }

          if (!data || vm.organizations.filter(function(o) { return o.id === data; })[0])
            return;

          return organizationService.getById(data, false).then(onSuccess);
        }

        function getAllOrganizations() {
          function onSuccess(response) {
            angular.forEach(response.data.plain(), function(value, key) {
              vm.organizations.push(value);
            });

            return vm.organizations;
          }

          return  organizationService.getAll({}, false).then(onSuccess);
        }

        function onSuccess() {
          vm.currentOrganization = vm.organizations.filter(function(o) { return o.id === (vm.currentOrganization.id || data); })[0];
          if (!vm.currentOrganization) {
            vm.currentOrganization = vm.organizations.length > 0 ? vm.organizations[0] : {};
          }

          vm.card.mode = hasExistingCard() ? 'existing' : 'new';
        }

        function onFailure(response) {
          notificationService.error(translateService.T('An error occurred while loading your organizations.') + ' ' + vm._contactSupport);
          $ExceptionlessClient.createFeatureUsage(vm._source + '.getOrganizations.error')
            .markAsCritical()
            .setMessage(response && response.data && response.data.message)
            .submit();

          cancel();
        }

        vm.organizations = [];
        return getAllOrganizations().then(getSelectedOrganization).then(onSuccess, onFailure);
      }

      function getPlans() {
        function onSuccess(response) {
          vm.plans = response.data.plain();

          // Upsell to the next plan.
          var currentPlan = vm.plans.filter(function(p) { return p.id === vm.currentOrganization.plan_id; })[0] || vm.plans[0];
          var currentPlanIndex = vm.plans.indexOf(currentPlan);
          vm.currentPlan = vm.plans.length > currentPlanIndex + 1 ? vm.plans[currentPlanIndex + 1] : currentPlan;

          return vm.plans;
        }

        function onFailure(response) {
          notificationService.error(translateService.T('An error occurred while loading available billing plans.') + ' ' + vm._contactSupport);
          $ExceptionlessClient.createFeatureUsage(vm._source + '.getPlans.error')
            .markAsCritical()
            .setMessage(response && response.data && response.data.message)
            .submit();

          cancel();
        }

        return organizationService.getPlans(vm.currentOrganization.id).then(onSuccess, onFailure);
      }

      function getUser() {
        function onSuccess(response) {
          vm.user = response.data.plain();

          if (!vm.card.name) {
            vm.card.name = vm.user.full_name;
          }

          return vm.user;
        }

        function onFailure(response) {
          notificationService.error(translateService.T('An error occurred while loading your user account.') + ' ' + vm._contactSupport);
          $ExceptionlessClient.createFeatureUsage(vm._source + '.getUser.error')
            .markAsCritical()
            .setMessage(response && response.data && response.data.message)
            .submit();

          cancel();
        }

        return userService.getCurrentUser().then(onSuccess, onFailure);
      }

      function hasAdminRole() {
        return userService.hasAdminRole(vm.user);
      }

      function hasExistingCard() {
        return !!vm.currentOrganization.card_last4;
      }

      function isBillingEnabled() {
        return !!STRIPE_PUBLISHABLE_KEY;
      }

      function isCancellingPlan() {
        return vm.currentPlan && vm.currentPlan.id === vm._freePlanId && vm.currentOrganization.plan_id !== vm._freePlanId;
      }

      function isNewCard() {
        return vm.card && vm.card.mode === 'new';
      }

      function isPaidPlan() {
        return vm.currentPlan && vm.currentPlan.price !== 0;
      }

      function showIntercom() {
        $ExceptionlessClient.submitFeatureUsage(vm._source + '.showIntercom');
        if (INTERCOM_APPID) {
          $intercom.showNewMessage();
        } else {
          $window.open('http://exceptionless.com/contact/', '_blank');
        }
      }

      this.$onInit = function $onInit() {
        vm._source = 'exceptionless.billing.ChangePlanDialog';
        vm._contactSupport = translateService.T('Please contact support for more information.');
        vm._freePlanId = 'EX_FREE';
        vm.cancel = cancel;
        vm.card = {};
        vm.changeOrganization = changeOrganization;
        vm.coupon = null;
        vm.currentOrganization = {};
        vm.currentPlan = {};
        vm.getPlans = getPlans;
        vm.hasAdminRole = hasAdminRole;
        vm.hasExistingCard = hasExistingCard;
        vm.isBillingEnabled = isBillingEnabled;
        vm.isCancellingPlan = isCancellingPlan;
        vm.isNewCard = isNewCard;
        vm.isPaidPlan = isPaidPlan;
        vm.organizations = [];
        vm.paymentMessage = !isBillingEnabled() ? translateService.T('Billing is currently disabled.') : null;
        vm.plans = [];
        vm.save = save;
        vm.showIntercom = showIntercom;
        vm.stripe = {};

        $ExceptionlessClient.submitFeatureUsage(vm._source);
        getOrganizations().then(getPlans).then(getUser);
      };
    });
}());
<commit_msg>Fixed a contact us link in the app<commit_after>(function () {
  'use strict';

  angular.module('exceptionless.billing')
    .controller('ChangePlanDialog', function ($uibModalInstance, adminService, analyticsService, Common, $ExceptionlessClient, $intercom, INTERCOM_APPID, notificationService, organizationService, stripe, STRIPE_PUBLISHABLE_KEY, userService, translateService, $window, data) {
      var vm = this;
      function cancel() {
        analyticsService.lead(getAnalyticsData());
        $ExceptionlessClient.createFeatureUsage(vm._source + '.cancel')
          .setProperty('CurrentPlan', vm.currentPlan)
          .setProperty('CouponId', vm.coupon)
          .setProperty('IsNewCard', isNewCard())
          .setProperty('OrganizationId', vm.currentOrganization.id)
          .submit();

        $uibModalInstance.dismiss('cancel');
      }

      function createStripeToken() {
        function onSuccess(response) {
          analyticsService.addPaymentInfo();
          return response;
        }

        var expiration = Common.parseExpiry(vm.card.expiry);
        var payload = {
          number: vm.card.number,
          cvc: vm.card.cvc,
          exp_month: expiration.month,
          exp_year: expiration.year,
          name: vm.card.name
        };

        return stripe.card.createToken(payload).then(onSuccess);
      }

      function getAnalyticsData() {
        return { content_name: vm.currentPlan.name, content_ids: [vm.currentPlan.id], content_type: 'product', currency: 'USD', value: vm.currentPlan.price };
      }

      function save(isValid) {
        function onCreateTokenSuccess(response) {
          return changePlan(false, { stripeToken: response.id, last4: response.card.last4, couponId: vm.coupon }).then(onSuccess, onFailure);
        }

        function onSuccess(response) {
          if(!response.data.success) {
            analyticsService.lead(getAnalyticsData());
            vm.paymentMessage = translateService.T('An error occurred while changing plans.') + ' ' + translateService.T('Message:') + ' ' + response.data.message;
            $ExceptionlessClient.createException(new Error(response.data.message))
              .markAsCritical()
              .setSource(vm._source + '.save.error')
              .setProperty('CurrentPlan', vm.currentPlan)
              .setProperty('CouponId', vm.coupon)
              .setProperty('IsNewCard', isNewCard())
              .setProperty('OrganizationId', vm.currentOrganization.id)
              .submit();

            return;
          }

          analyticsService.purchase(getAnalyticsData());
          $ExceptionlessClient.createFeatureUsage(vm._source + '.save')
            .markAsCritical()
            .setMessage(response.data.message)
            .setProperty('CurrentPlan', vm.currentPlan)
            .setProperty('CouponId', vm.coupon)
            .setProperty('IsNewCard', isNewCard())
            .setProperty('OrganizationId', vm.currentOrganization.id)
            .submit();

          $uibModalInstance.close(vm.currentPlan);
          notificationService.success(translateService.T('Thanks! Your billing plan has been successfully changed.'));
        }

        function onFailure(response) {
          if (response.error && response.error.message) {
            vm.paymentMessage = response.error.message;
          } else {
            vm.paymentMessage = translateService.T('An error occurred while changing plans.');
          }

          analyticsService.lead(getAnalyticsData());
          $ExceptionlessClient.createException(new Error(vm.paymentMessage))
            .markAsCritical()
            .setSource(vm._source + '.save.error')
            .setProperty('CurrentPlan', vm.currentPlan)
            .setProperty('CouponId', vm.coupon)
            .setProperty('IsNewCard', isNewCard())
            .setProperty('OrganizationId', vm.currentOrganization.id)
            .submit();
        }

        if (!isValid || !vm.currentPlan) {
          return;
        }

        vm.paymentMessage = null;
        if (vm.currentOrganization.plan_id === vm._freePlanId && vm.currentPlan.id === vm._freePlanId) {
          cancel();
          return;
        }

        if (hasAdminRole() || vm.currentPlan.id === vm._freePlanId) {
          return changePlan(hasAdminRole()).then(onSuccess, onFailure);
        }

        if (vm.currentPlan.price > 0 && isNewCard()) {
          try {
            return createStripeToken().then(onCreateTokenSuccess, onFailure);
          } catch (error) {
            vm.paymentMessage = translateService.T('An error occurred while changing plans.');
            $ExceptionlessClient.createException(error)
              .markAsCritical()
              .setSource(vm._source + '.save.error')
              .setProperty('CurrentPlan', vm.currentPlan)
              .setProperty('CouponId', vm.coupon)
              .setProperty('IsNewCard', isNewCard())
              .setProperty('OrganizationId', vm.currentOrganization.id)
              .submit();
            return null;
          }
        }

        return changePlan(false, { couponId: vm.coupon }).then(onSuccess, onFailure);
      }

      function changeOrganization() {
        vm.card.mode = hasExistingCard() ? 'existing' : 'new';
        return getPlans();
      }

      function changePlan(isAdmin, options) {
        if (isAdmin) {
          return adminService.changePlan({ organizationId: vm.currentOrganization.id, planId: vm.currentPlan.id });
        } else {
          return organizationService.changePlan(vm.currentOrganization.id, angular.extend({}, { planId: vm.currentPlan.id }, options));
        }
      }

      function getOrganizations() {
        function getSelectedOrganization() {
          function onSuccess(response) {
            vm.organizations.push(response.data.plain());
            return vm.organizations;
          }

          if (!data || vm.organizations.filter(function(o) { return o.id === data; })[0])
            return;

          return organizationService.getById(data, false).then(onSuccess);
        }

        function getAllOrganizations() {
          function onSuccess(response) {
            angular.forEach(response.data.plain(), function(value, key) {
              vm.organizations.push(value);
            });

            return vm.organizations;
          }

          return  organizationService.getAll({}, false).then(onSuccess);
        }

        function onSuccess() {
          vm.currentOrganization = vm.organizations.filter(function(o) { return o.id === (vm.currentOrganization.id || data); })[0];
          if (!vm.currentOrganization) {
            vm.currentOrganization = vm.organizations.length > 0 ? vm.organizations[0] : {};
          }

          vm.card.mode = hasExistingCard() ? 'existing' : 'new';
        }

        function onFailure(response) {
          notificationService.error(translateService.T('An error occurred while loading your organizations.') + ' ' + vm._contactSupport);
          $ExceptionlessClient.createFeatureUsage(vm._source + '.getOrganizations.error')
            .markAsCritical()
            .setMessage(response && response.data && response.data.message)
            .submit();

          cancel();
        }

        vm.organizations = [];
        return getAllOrganizations().then(getSelectedOrganization).then(onSuccess, onFailure);
      }

      function getPlans() {
        function onSuccess(response) {
          vm.plans = response.data.plain();

          // Upsell to the next plan.
          var currentPlan = vm.plans.filter(function(p) { return p.id === vm.currentOrganization.plan_id; })[0] || vm.plans[0];
          var currentPlanIndex = vm.plans.indexOf(currentPlan);
          vm.currentPlan = vm.plans.length > currentPlanIndex + 1 ? vm.plans[currentPlanIndex + 1] : currentPlan;

          return vm.plans;
        }

        function onFailure(response) {
          notificationService.error(translateService.T('An error occurred while loading available billing plans.') + ' ' + vm._contactSupport);
          $ExceptionlessClient.createFeatureUsage(vm._source + '.getPlans.error')
            .markAsCritical()
            .setMessage(response && response.data && response.data.message)
            .submit();

          cancel();
        }

        return organizationService.getPlans(vm.currentOrganization.id).then(onSuccess, onFailure);
      }

      function getUser() {
        function onSuccess(response) {
          vm.user = response.data.plain();

          if (!vm.card.name) {
            vm.card.name = vm.user.full_name;
          }

          return vm.user;
        }

        function onFailure(response) {
          notificationService.error(translateService.T('An error occurred while loading your user account.') + ' ' + vm._contactSupport);
          $ExceptionlessClient.createFeatureUsage(vm._source + '.getUser.error')
            .markAsCritical()
            .setMessage(response && response.data && response.data.message)
            .submit();

          cancel();
        }

        return userService.getCurrentUser().then(onSuccess, onFailure);
      }

      function hasAdminRole() {
        return userService.hasAdminRole(vm.user);
      }

      function hasExistingCard() {
        return !!vm.currentOrganization.card_last4;
      }

      function isBillingEnabled() {
        return !!STRIPE_PUBLISHABLE_KEY;
      }

      function isCancellingPlan() {
        return vm.currentPlan && vm.currentPlan.id === vm._freePlanId && vm.currentOrganization.plan_id !== vm._freePlanId;
      }

      function isNewCard() {
        return vm.card && vm.card.mode === 'new';
      }

      function isPaidPlan() {
        return vm.currentPlan && vm.currentPlan.price !== 0;
      }

      function showIntercom() {
        $ExceptionlessClient.submitFeatureUsage(vm._source + '.showIntercom');
        if (INTERCOM_APPID) {
          $intercom.showNewMessage();
        } else {
          $window.open('https://exceptionless.com', '_blank');
        }
      }

      this.$onInit = function $onInit() {
        vm._source = 'exceptionless.billing.ChangePlanDialog';
        vm._contactSupport = translateService.T('Please contact support for more information.');
        vm._freePlanId = 'EX_FREE';
        vm.cancel = cancel;
        vm.card = {};
        vm.changeOrganization = changeOrganization;
        vm.coupon = null;
        vm.currentOrganization = {};
        vm.currentPlan = {};
        vm.getPlans = getPlans;
        vm.hasAdminRole = hasAdminRole;
        vm.hasExistingCard = hasExistingCard;
        vm.isBillingEnabled = isBillingEnabled;
        vm.isCancellingPlan = isCancellingPlan;
        vm.isNewCard = isNewCard;
        vm.isPaidPlan = isPaidPlan;
        vm.organizations = [];
        vm.paymentMessage = !isBillingEnabled() ? translateService.T('Billing is currently disabled.') : null;
        vm.plans = [];
        vm.save = save;
        vm.showIntercom = showIntercom;
        vm.stripe = {};

        $ExceptionlessClient.submitFeatureUsage(vm._source);
        getOrganizations().then(getPlans).then(getUser);
      };
    });
}());
<|endoftext|>


<commit_before>var WebGLManager = require('./WebGLManager'),
    AlphaMaskFilter = require('../filters/spriteMask/SpriteMaskFilter');

/**
 * @class
 * @memberof PIXI
 * @param renderer {PIXI.WebGLRenderer} The renderer this manager works for.
 */
function MaskManager(renderer)
{
    WebGLManager.call(this, renderer);

    //TODO - we don't need both!
    this.scissor = false;
    this.scissorData = null;
    this.scissorRenderTarget = null;

    this.enableScissor = true;

    this.alphaMaskPool = [];
    this.alphaMaskIndex = 0;
}

MaskManager.prototype = Object.create(WebGLManager.prototype);
MaskManager.prototype.constructor = MaskManager;
module.exports = MaskManager;

/**
 * Applies the Mask and adds it to the current filter stack.
 *
 * @param target {PIXI.DisplayObject}
 * @param maskData {*[]}
 */
MaskManager.prototype.pushMask = function (target, maskData)
{
    if (maskData.texture)
    {
        this.pushSpriteMask(target, maskData);
    }
    else
    {
        if(this.enableScissor && !this.scissor && !this.renderer.stencilManager.stencilMaskStack.length && maskData.graphicsData[0].shape.type === 1)
        {
            var matrix = maskData.worldTransform;

            var rot = Math.atan2(matrix.b, matrix.a);

            // use the nearest degree!
            rot = Math.round(rot * (180/Math.PI));

            if(rot % 90)
            {
                this.pushStencilMask(maskData);
            }
            else
            {
                this.pushScissorMask(target, maskData);
            }
        }
        else
        {
            this.pushStencilMask(maskData);
        }
    }
};

/**
 * Removes the last mask from the mask stack and doesn't return it.
 *
 * @param target {PIXI.DisplayObject}
 * @param maskData {*[]}
 */
MaskManager.prototype.popMask = function (target, maskData)
{
    if (maskData.texture)
    {
        this.popSpriteMask(target, maskData);
    }
    else
    {
        if(this.enableScissor && !this.renderer.stencilManager.stencilMaskStack.length)
        {
            this.popScissorMask(target, maskData);
        }
        else
        {
            this.popStencilMask(target, maskData);
        }

    }
};

/**
 * Applies the Mask and adds it to the current filter stack.
 *
 * @param target {PIXI.RenderTarget}
 * @param maskData {PIXI.Sprite}
 */
MaskManager.prototype.pushSpriteMask = function (target, maskData)
{
    var alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex];

    if (!alphaMaskFilter)
    {
        alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex] = [new AlphaMaskFilter(maskData)];
    }

    alphaMaskFilter[0].maskSprite = maskData;

    //TODO - may cause issues!
    target.filterArea = maskData.getBounds();

    this.renderer.filterManager.pushFilter(target, alphaMaskFilter);

    this.alphaMaskIndex++;
};

/**
 * Removes the last filter from the filter stack and doesn't return it.
 *
 */
MaskManager.prototype.popSpriteMask = function ()
{
    this.renderer.filterManager.popFilter();
    this.alphaMaskIndex--;
};

/**
 * Applies the Mask and adds it to the current filter stack.
 *
 * @param maskData {*[]}
 */
MaskManager.prototype.pushStencilMask = function (maskData)
{
    this.renderer.currentRenderer.stop();
    this.renderer.stencilManager.pushStencil(maskData);
};

/**
 * Removes the last filter from the filter stack and doesn't return it.
 *
 */
MaskManager.prototype.popStencilMask = function ()
{
    this.renderer.currentRenderer.stop();
    this.renderer.stencilManager.popStencil();
};

MaskManager.prototype.pushScissorMask = function (target, maskData)
{
    maskData.renderable = true;

    var renderTarget = this.renderer._activeRenderTarget;

    var bounds = maskData.getBounds();

    bounds.fit(renderTarget.size);
    maskData.renderable = false;

    this.renderer.gl.enable(this.renderer.gl.SCISSOR_TEST);

    this.renderer.gl.scissor(bounds.x,
                           renderTarget.root ? renderTarget.size.height - bounds.y - bounds.height : bounds.y,
                           bounds.width ,
                           bounds.height);

    this.scissorRenderTarget = renderTarget;
    this.scissorData = maskData;
    this.scissor = true;
};

MaskManager.prototype.popScissorMask = function ()
{
    this.scissorRenderTarget = null;
    this.scissorData = null;
    this.scissor = false;

    // must be scissor!
    var gl = this.renderer.gl;
    gl.disable(gl.SCISSOR_TEST);
};
<commit_msg>scissor resolution fix #2545<commit_after>var WebGLManager = require('./WebGLManager'),
    AlphaMaskFilter = require('../filters/spriteMask/SpriteMaskFilter');

/**
 * @class
 * @memberof PIXI
 * @param renderer {PIXI.WebGLRenderer} The renderer this manager works for.
 */
function MaskManager(renderer)
{
    WebGLManager.call(this, renderer);

    //TODO - we don't need both!
    this.scissor = false;
    this.scissorData = null;
    this.scissorRenderTarget = null;

    this.enableScissor = true;

    this.alphaMaskPool = [];
    this.alphaMaskIndex = 0;
}

MaskManager.prototype = Object.create(WebGLManager.prototype);
MaskManager.prototype.constructor = MaskManager;
module.exports = MaskManager;

/**
 * Applies the Mask and adds it to the current filter stack.
 *
 * @param target {PIXI.DisplayObject}
 * @param maskData {*[]}
 */
MaskManager.prototype.pushMask = function (target, maskData)
{
    if (maskData.texture)
    {
        this.pushSpriteMask(target, maskData);
    }
    else
    {
        if(this.enableScissor && !this.scissor && !this.renderer.stencilManager.stencilMaskStack.length && maskData.graphicsData[0].shape.type === 1)
        {
            var matrix = maskData.worldTransform;

            var rot = Math.atan2(matrix.b, matrix.a);

            // use the nearest degree!
            rot = Math.round(rot * (180/Math.PI));

            if(rot % 90)
            {
                this.pushStencilMask(maskData);
            }
            else
            {
                this.pushScissorMask(target, maskData);
            }
        }
        else
        {
            this.pushStencilMask(maskData);
        }
    }
};

/**
 * Removes the last mask from the mask stack and doesn't return it.
 *
 * @param target {PIXI.DisplayObject}
 * @param maskData {*[]}
 */
MaskManager.prototype.popMask = function (target, maskData)
{
    if (maskData.texture)
    {
        this.popSpriteMask(target, maskData);
    }
    else
    {
        if(this.enableScissor && !this.renderer.stencilManager.stencilMaskStack.length)
        {
            this.popScissorMask(target, maskData);
        }
        else
        {
            this.popStencilMask(target, maskData);
        }

    }
};

/**
 * Applies the Mask and adds it to the current filter stack.
 *
 * @param target {PIXI.RenderTarget}
 * @param maskData {PIXI.Sprite}
 */
MaskManager.prototype.pushSpriteMask = function (target, maskData)
{
    var alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex];

    if (!alphaMaskFilter)
    {
        alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex] = [new AlphaMaskFilter(maskData)];
    }

    alphaMaskFilter[0].maskSprite = maskData;

    //TODO - may cause issues!
    target.filterArea = maskData.getBounds();

    this.renderer.filterManager.pushFilter(target, alphaMaskFilter);

    this.alphaMaskIndex++;
};

/**
 * Removes the last filter from the filter stack and doesn't return it.
 *
 */
MaskManager.prototype.popSpriteMask = function ()
{
    this.renderer.filterManager.popFilter();
    this.alphaMaskIndex--;
};

/**
 * Applies the Mask and adds it to the current filter stack.
 *
 * @param maskData {*[]}
 */
MaskManager.prototype.pushStencilMask = function (maskData)
{
    this.renderer.currentRenderer.stop();
    this.renderer.stencilManager.pushStencil(maskData);
};

/**
 * Removes the last filter from the filter stack and doesn't return it.
 *
 */
MaskManager.prototype.popStencilMask = function ()
{
    this.renderer.currentRenderer.stop();
    this.renderer.stencilManager.popStencil();
};

MaskManager.prototype.pushScissorMask = function (target, maskData)
{
    maskData.renderable = true;

    var renderTarget = this.renderer._activeRenderTarget;

    var bounds = maskData.getBounds();

    bounds.fit(renderTarget.size);
    maskData.renderable = false;

    this.renderer.gl.enable(this.renderer.gl.SCISSOR_TEST);

    var resolution = this.renderer.resolution;
    this.renderer.gl.scissor(bounds.x * resolution,
        (renderTarget.root ? renderTarget.size.height - bounds.y - bounds.height : bounds.y) * resolution,
                           bounds.width * resolution,
                           bounds.height * resolution);

    this.scissorRenderTarget = renderTarget;
    this.scissorData = maskData;
    this.scissor = true;
};

MaskManager.prototype.popScissorMask = function ()
{
    this.scissorRenderTarget = null;
    this.scissorData = null;
    this.scissor = false;

    // must be scissor!
    var gl = this.renderer.gl;
    gl.disable(gl.SCISSOR_TEST);
};
<|endoftext|>


<commit_before>// @flow

import flatten from 'lodash/flatten'
import compact from 'lodash/compact'
import some from 'lodash/some'
import zip from 'lodash/zip'
import {List} from 'immutable'

import ordinal from 'ord'
import oxford from 'listify'
import {findTimeConflicts} from '@gob/schedule-conflicts'
import {expandYear, semesterName} from '@gob/school-st-olaf-college'

import type {Course as CourseType, CourseError} from '@gob/types'
import {Schedule} from './schedule'

export type WarningTypeEnum =
	| 'invalid-semester'
	| 'invalid-year'
	| 'time-conflict'

export type WarningType = {
	warning: true,
	type: WarningTypeEnum,
	msg: string,
}

type Course = CourseType | FabricationType

export function checkForInvalidYear(
	course: Course,
	scheduleYear: number,
	thisYear: number = new Date().getFullYear(),
): ?WarningType {
	if (course.semester === 9 || course.semester === undefined) {
		return null
	}

	if (course.year !== scheduleYear && scheduleYear <= thisYear) {
		const yearString = expandYear(course.year, true, '–')
		return {
			warning: true,
			type: 'invalid-year',
			msg: `Wrong Year (originally from ${yearString})`,
		}
	}

	return null
}

export function checkForInvalidSemester(
	course: Course,
	scheduleSemester: number,
): ?WarningType {
	if (course.semester === undefined) {
		return null
	}

	if (course.semester !== scheduleSemester) {
		const semString = semesterName(course.semester)
		return {
			warning: true,
			type: 'invalid-semester',
			msg: `Wrong Semester (originally from ${semString})`,
		}
	}

	return null
}

export function checkForInvalidity(
	courses: List<Course>,
	{year, semester}: {year: number, semester: number},
): List<List<?WarningType>> {
	return courses.map(course => {
		let invalidYear = checkForInvalidYear(course, year)
		let invalidSemester = checkForInvalidSemester(course, semester)
		return List([invalidYear, invalidSemester])
	})
}

export function checkForTimeConflicts(
	courses: List<Course>,
): List<?WarningType> {
	let conflicts = List(findTimeConflicts(courses.toArray()))

	conflicts = conflicts.map(conflictSet => {
		if (some(conflictSet)) {
			// +1 to the indices because humans don't 0-index lists
			const conflicts = compact(
				conflictSet.map(
					(possibility, i) => (possibility === true ? i + 1 : false),
				),
			)
			const conflicted = conflicts.map(i => `${i}${ordinal(i)}`)

			const conflictsStr = oxford(conflicted, {oxfordComma: true})
			const word = conflicts.length === 1 ? 'course' : 'courses'
			return {
				warning: true,
				type: 'time-conflict',
				msg: `Time conflict with the ${conflictsStr} ${word}`,
			}
		}

		return null
	})

	return conflicts
}

export function findWarnings(
	courses: List<Course | CourseError>,
	schedule: Schedule,
): Array<Array<?WarningType>> {
	let [year, semester] = [schedule.get('year'), schedule.get('semester')]

	let onlyCourses = courses.filterNot(c => !c.error)

	let warningsOfInvalidity = checkForInvalidity(onlyCourses, {year, semester})
	let timeConflicts = checkForTimeConflicts(onlyCourses)

	let nearlyMerged: List<
		List<List<?WarningType>>,
	> = warningsOfInvalidity.zip(timeConflicts)

	let allWarnings = nearlyMerged.flatten(1)

	return allWarnings
}
<commit_msg>continue poking at findCourseWarnings<commit_after>// @flow

import compact from 'lodash/compact'
import some from 'lodash/some'
import {List, Map} from 'immutable'

import ordinal from 'ord'
import oxford from 'listify'
import {findTimeConflicts} from '@gob/schedule-conflicts'
import {expandYear, semesterName} from '@gob/school-st-olaf-college'

import type {Course as CourseType, CourseError} from '@gob/types'
import {Schedule} from './schedule'

export type WarningTypeEnum =
	| 'invalid-semester'
	| 'invalid-year'
	| 'time-conflict'

export type WarningType = {
	warning: true,
	type: WarningTypeEnum,
	msg: string,
}

type Course = CourseType | FabricationType

export function checkForInvalidYear(
	course: Course,
	scheduleYear: number,
	thisYear: number = new Date().getFullYear(),
): ?WarningType {
	if (course.semester === 9 || course.semester === undefined) {
		return null
	}

	if (course.year !== scheduleYear && scheduleYear <= thisYear) {
		const yearString = expandYear(course.year, true, '–')
		return {
			warning: true,
			type: 'invalid-year',
			msg: `Wrong Year (originally from ${yearString})`,
		}
	}

	return null
}

export function checkForInvalidSemester(
	course: Course,
	scheduleSemester: number,
): ?WarningType {
	if (course.semester === undefined) {
		return null
	}

	if (course.semester !== scheduleSemester) {
		const semString = semesterName(course.semester)
		return {
			warning: true,
			type: 'invalid-semester',
			msg: `Wrong Semester (originally from ${semString})`,
		}
	}

	return null
}

export function checkForInvalidity(
	courses: List<Course>,
	{year, semester}: {year: number, semester: number},
): List<List<?WarningType>> {
	return courses.map(course => {
		let invalidYear = checkForInvalidYear(course, year)
		let invalidSemester = checkForInvalidSemester(course, semester)
		return List([invalidYear, invalidSemester])
	})
}

export function checkForTimeConflicts(
	courses: List<Course>,
): List<?WarningType> {
	let conflicts = List(findTimeConflicts(courses.toArray()))

	conflicts = conflicts.map(conflictSet => {
		if (some(conflictSet)) {
			// +1 to the indices because humans don't 0-index lists
			const conflicts = compact(
				conflictSet.map(
					(possibility, i) => (possibility === true ? i + 1 : false),
				),
			)
			const conflicted = conflicts.map(i => `${i}${ordinal(i)}`)

			const conflictsStr = oxford(conflicted, {oxfordComma: true})
			const word = conflicts.length === 1 ? 'course' : 'courses'
			return {
				warning: true,
				type: 'time-conflict',
				msg: `Time conflict with the ${conflictsStr} ${word}`,
			}
		}

		return null
	})

	return conflicts
}

export function findWarnings(
	courses: List<Course | CourseError>,
	schedule: Schedule,
): Map<string, List<?WarningType>> {
	let [year, semester] = [schedule.get('year'), schedule.get('semester')]

	let onlyCourses = courses.filterNot(c => !c.error)

	let warningsOfInvalidity = checkForInvalidity(onlyCourses, {year, semester})
	let timeConflicts = checkForTimeConflicts(onlyCourses)

	let nearlyMerged: List<
		List<List<?WarningType>>,
	> = warningsOfInvalidity.zip(timeConflicts)

	let allWarnings = nearlyMerged.flatten(1)

	return allWarnings
}
<|endoftext|>


<commit_before>
$.widget("ui.search_ui", {

	_create: function() {

        var me = this;

        $(document).on('widgetmanager:loaded', $.proxy(me.init, this));

	},

	init: function() {

        //after all widget's _create function

		var me = this,
			inputSearch = $(document).find('.input-search'),
            queryString = $.url().param('searchterm');

		inputSearch.focus();

        $('.search__top__container').find('.btn--result-option').on('click', function() {
            $.proxy(me._toggleView($(this).attr('href').substring(1)), me);
            return false;
        });

        $('.global-search__submit').on('click', function(event){
            event.preventDefault();
            me.doSearch(true);
        });

        $(document).on('search:inputChanged', function() {
            me.doSearch(true);
        });

        $('.search__filters__mobile').on('click', function(event){
            event.preventDefault();
            me.toggleSearchOptions();
        });

        $('.search__filters__title').on('click', function(event){
            event.preventDefault();
            me.toggleSearchSection($(this));
        });

        me.searched = [];

        me._toggleView('list');

	},

    _toggleView: function(type){

        var me = this,
            type;

        $('.btn--result-option').removeClass('is-active');

        var buttonEl = $('[href="#' + type + '"]');

        buttonEl.addClass('is-active');
        $('.search__result__container').hide();
        $('#search-' + type ).show();
        $('#search-' + type ).css('visibility', 'visible');

        if (jQuery.inArray(type, me.searched) == -1) {
            me.doSearch();
        }

    },

	doSearch: function(reset) {

		var me = this,
			checkboxValue,
			inputfieldValue,
            type,
            widgetEls = $("[class*='do_search_cmp']"),
            widgetRefs = [],
            mergedValues = {};

        $.each(widgetEls, function(i, element){
            var classnames = element.className.split(/\s+/),
                element = $(element);

            $.each(classnames, function(j, classname) {

                if (classname.match(/do_search_cmp/)) {
                    var widgetName = classname.replace(/^do_/, '');
                    widgetRefs.push(element.data('ui-' + widgetName));
                }
            });
        });

        $.each(widgetRefs, function(i, widget) {

            var widgetVals = widget.getValues();

            if (Array.isArray(widgetVals) ) {
                 $.each(widgetVals, function(j, val) {
                    if (mergedValues[val.type]) {
                        mergedValues[val.type] = mergedValues[val.type].concat(val.values);
                    } else {
                        mergedValues[val.type] = val.values;
                    }
                });
            }
        });

        type = me.getType();

        if (reset) me.searched = [];

		$(document).trigger("search:doSearch", {'values': mergedValues, 'type': me.getType() });

        if (jQuery.inArray(type, me.searched) == -1) me.searched.push(type);
	},

    getType: function() {
        var el = $('.btn--result-option.is-active');
        return (el.size() > 0) ? el.attr('href').replace(/#/, '') : false;
    },

    toggleSearchOptions: function(){
        $('.search__filters').toggleClass('is-open');
    },

    toggleSearchSection: function(title){
        $('.search__filters__section').removeClass('is-open');
        title.parent().toggleClass('is-open');
    }

});
<commit_msg>[base] sibling selector instead of all filter sections<commit_after>
$.widget("ui.search_ui", {

	_create: function() {

        var me = this;

        $(document).on('widgetmanager:loaded', $.proxy(me.init, this));

	},

	init: function() {

        //after all widget's _create function

		var me = this,
			inputSearch = $(document).find('.input-search'),
            queryString = $.url().param('searchterm');

		inputSearch.focus();

        $('.search__top__container').find('.btn--result-option').on('click', function() {
            $.proxy(me._toggleView($(this).attr('href').substring(1)), me);
            return false;
        });

        $('.global-search__submit').on('click', function(event){
            event.preventDefault();
            me.doSearch(true);
        });

        $(document).on('search:inputChanged', function() {
            me.doSearch(true);
        });

        $('.search__filters__mobile').on('click', function(event){
            event.preventDefault();
            me.toggleSearchOptions();
        });

        $('.search__filters__title').on('click', function(event){
            event.preventDefault();
            me.toggleSearchSection($(this));
        });

        me.searched = [];

        me._toggleView('list');

	},

    _toggleView: function(type){

        var me = this,
            type;

        $('.btn--result-option').removeClass('is-active');

        var buttonEl = $('[href="#' + type + '"]');

        buttonEl.addClass('is-active');
        $('.search__result__container').hide();
        $('#search-' + type ).show();
        $('#search-' + type ).css('visibility', 'visible');

        if (jQuery.inArray(type, me.searched) == -1) {
            me.doSearch();
        }

    },

	doSearch: function(reset) {

		var me = this,
			checkboxValue,
			inputfieldValue,
            type,
            widgetEls = $("[class*='do_search_cmp']"),
            widgetRefs = [],
            mergedValues = {};

        $.each(widgetEls, function(i, element){
            var classnames = element.className.split(/\s+/),
                element = $(element);

            $.each(classnames, function(j, classname) {

                if (classname.match(/do_search_cmp/)) {
                    var widgetName = classname.replace(/^do_/, '');
                    widgetRefs.push(element.data('ui-' + widgetName));
                }
            });
        });

        $.each(widgetRefs, function(i, widget) {

            var widgetVals = widget.getValues();

            if (Array.isArray(widgetVals) ) {
                 $.each(widgetVals, function(j, val) {
                    if (mergedValues[val.type]) {
                        mergedValues[val.type] = mergedValues[val.type].concat(val.values);
                    } else {
                        mergedValues[val.type] = val.values;
                    }
                });
            }
        });

        type = me.getType();

        if (reset) me.searched = [];

		$(document).trigger("search:doSearch", {'values': mergedValues, 'type': me.getType() });

        if (jQuery.inArray(type, me.searched) == -1) me.searched.push(type);
	},

    getType: function() {
        var el = $('.btn--result-option.is-active');
        return (el.size() > 0) ? el.attr('href').replace(/#/, '') : false;
    },

    toggleSearchOptions: function(){
        $('.search__filters').toggleClass('is-open');
    },

    toggleSearchSection: function(title){
        title.parent().siblings().removeClass('is-open');
        title.parent().toggleClass('is-open');
    }

});
<|endoftext|>


<commit_before>define(
  'ephox.darwin.demo.DarwinTableDemo',

  [
    'ephox.compass.Arr',
    'ephox.darwin.api.Darwin',
    'ephox.darwin.api.TableKeys',
    'ephox.fussy.api.SelectionRange',
    'ephox.fussy.api.Situ',
    'ephox.fussy.api.WindowSelection',
    'ephox.oath.proximity.Awareness',
    'ephox.peanut.Fun',
    'ephox.perhaps.Option',
    'ephox.robin.api.dom.DomParent',
    'ephox.sugar.api.Class',
    'ephox.sugar.api.Compare',
    'ephox.sugar.api.DomEvent',
    'ephox.sugar.api.Element',
    'ephox.sugar.api.Insert',
    'ephox.sugar.api.SelectorFilter',
    'ephox.sugar.api.SelectorFind',
    'global!Math',
    'global!document'
  ],

  function (Arr, Darwin, TableKeys, SelectionRange, Situ, WindowSelection, Awareness, Fun, Option, DomParent, Class, Compare, DomEvent, Element, Insert, SelectorFilter, SelectorFind, Math, document) {
    return function () {
      console.log('darwin table');

      var ephoxUi = SelectorFind.first('#ephox-ui').getOrDie();

      var style = Element.fromHtml(
        ''
      );

      var table = Element.fromHtml(
        '
' +
          '
' +
            '
' +
              'A1	' +
              'B1
	' +
              'C1

	' +
              'D1	' +
            '
' +
            '
' +
              'A2	' +
              'B2	' +
              '
C2

More
	' +
              '
D2	' +
            '
' +
            '
' +
              'A3	' +
              'B3	' +
              'C3	' +
              'D3	' +
            '
' +
          '
' +
        '
'
      );

      Insert.append(ephoxUi, table);
      Insert.append(Element.fromDom(document.head), style);

      var findInTable = function (container, cell) {
        return findColumn(cell).bind(function (colIndex) {
          return findRow(cell).map(function (rowIndex) {
            return {
              rowIndex: Fun.constant(rowIndex),
              colIndex: Fun.constant(colIndex),
            };
          });
        });
      };

      var findColumn = function (cell) {
        return SelectorFind.ancestor(cell, 'tr').bind(function (tr) {
          var cells = SelectorFilter.descendants(tr, 'td,th');
          var isElem = Fun.curry(Compare.eq, cell);
          var index = Arr.findIndex(cells, isElem);
          return index !== -1 ? Option.some(index) : Option.none();
        });
      };

      var findRow = function (cell) {
        return SelectorFind.ancestor(cell, 'tbody,thead').bind(function (section) {
          return SelectorFind.ancestor(cell, 'tr').bind(function (row) {
            var rows = SelectorFilter.descendants(section, 'tr');
            var isRow = Fun.curry(Compare.eq, row);
            var index = Arr.findIndex(rows, isRow);
            return index !== -1 ? Option.some(index) : Option.none();
          });
        });
      };

      var lookupTable = function (scope) {
        return SelectorFind.ancestor(scope, 'table');
      };

      var boxIt = function (start, finish) {
        // Check they have the same table.
        return DomParent.sharedOne(lookupTable, [ start, finish ]).bind(function (tbl) {
          // For all the rows, identify the information.
          var rows = SelectorFilter.descendants(tbl, 'tr');
          return findInTable(tbl, start).bind(function (startData) {
            return findInTable(tbl, finish).map(function (finishData) {
              console.log('startData', startData, 'finishData', finishData);
              var minRowIndex = Math.min(startData.rowIndex(), finishData.rowIndex());
              var maxRowIndex = Math.max(startData.rowIndex(), finishData.rowIndex());
              var subrows = rows.slice(minRowIndex, maxRowIndex + 1);
              console.log('subrows', Arr.map(subrows, function (r) { return r.dom(); }));
              return Arr.bind(subrows, function (r) {
                var cells = SelectorFilter.children(r, 'td,th');
                var minCellIndex = Math.min(startData.colIndex(), finishData.colIndex());
                var maxCellIndex = Math.max(startData.colIndex(), finishData.colIndex());
                var blah = cells.slice(minCellIndex, maxCellIndex + 1);
                console.log('blah', Arr.map(blah, function (b) { return b.dom(); }));
                return blah;
              });
            });
          });
        });
      };

      var magic = function () {
        var cursor = Option.none();
        DomEvent.bind(table, 'mousedown', function (event) {
          var selected = SelectorFilter.descendants(table, '.selected');
          Arr.each(selected, function (td) {
            Class.remove(td, 'selected');
          });

          cursor = SelectorFind.closest(event.target(), 'td,th');
          console.log('mousedown');
        });

        DomEvent.bind(table, 'mouseover', function (event) {

          var boxes = cursor.bind(function (cur) {
            var selected = SelectorFilter.descendants(table, '.selected');
            Arr.each(selected, function (td) {
              Class.remove(td, 'selected');
            });

            var boxes = SelectorFind.closest(event.target(), 'td,th').bind(function (finish) {
              console.log('start', cur.dom(), 'finish', finish.dom());
              return boxIt(cur, finish);
            }).getOr([]);

            if (boxes.length > 0) {
              console.log('boxing');
              Arr.each(boxes, function (box) {
                Class.add(box, 'selected');
              });

              window.getSelection().removeAllRanges();
            }
            console.log('mouseover', boxes);
          });
        });

        DomEvent.bind(table, 'mouseup', function (event) {
          cursor = Option.none();
        });

        DomEvent.bind(table, 'keydown', function (event) {
          WindowSelection.get(window).each(function (sel) {
            if (event.raw().which === 40 || event.raw().which === 38) {
              var mover = event.raw().which === 40 ? TableKeys.handleDown : TableKeys.handleUp;
              mover(window, Fun.constant(false), sel.finish(), sel.foffset()).each(function (exact) {
                WindowSelection.set(window, SelectionRange.write(
                  event.raw().shiftKey ? Situ.on(sel.start(), sel.soffset()) : Situ.on(exact.start(), exact.soffset()),
                  Situ.on(exact.start(), exact.soffset())
                ));
                event.kill();
                console.log('next', exact.start().dom(), exact.soffset(), exact.start().dom().childNodes.length);
              });
            }
          });
        });

      };

      magic();
    };
  }
);<commit_msg>TBIO-2087: reintroduced styles<commit_after>define(
  'ephox.darwin.demo.DarwinTableDemo',

  [
    'ephox.compass.Arr',
    'ephox.darwin.api.Darwin',
    'ephox.darwin.api.TableKeys',
    'ephox.fussy.api.SelectionRange',
    'ephox.fussy.api.Situ',
    'ephox.fussy.api.WindowSelection',
    'ephox.oath.proximity.Awareness',
    'ephox.peanut.Fun',
    'ephox.perhaps.Option',
    'ephox.robin.api.dom.DomParent',
    'ephox.sugar.api.Class',
    'ephox.sugar.api.Compare',
    'ephox.sugar.api.DomEvent',
    'ephox.sugar.api.Element',
    'ephox.sugar.api.Insert',
    'ephox.sugar.api.SelectorFilter',
    'ephox.sugar.api.SelectorFind',
    'global!Math',
    'global!document'
  ],

  function (Arr, Darwin, TableKeys, SelectionRange, Situ, WindowSelection, Awareness, Fun, Option, DomParent, Class, Compare, DomEvent, Element, Insert, SelectorFilter, SelectorFind, Math, document) {
    return function () {
      console.log('darwin table');

      var ephoxUi = SelectorFind.first('#ephox-ui').getOrDie();

      var style = Element.fromHtml(
        ''
      );

      var table = Element.fromHtml(
        '
' +
          '
' +
            '
' +
              'A1	' +
              'B1
	' +
              'C1

	' +
              'D1	' +
            '
' +
            '
' +
              'A2	' +
              'B2	' +
              '
C2

More
	' +
              '
D2	' +
            '
' +
            '
' +
              'A3	' +
              'B3	' +
              'C3	' +
              'D3	' +
            '
' +
          '
' +
        '
'
      );

      Insert.append(ephoxUi, table);
      Insert.append(Element.fromDom(document.head), style);

      var findInTable = function (container, cell) {
        return findColumn(cell).bind(function (colIndex) {
          return findRow(cell).map(function (rowIndex) {
            return {
              rowIndex: Fun.constant(rowIndex),
              colIndex: Fun.constant(colIndex),
            };
          });
        });
      };

      var findColumn = function (cell) {
        return SelectorFind.ancestor(cell, 'tr').bind(function (tr) {
          var cells = SelectorFilter.descendants(tr, 'td,th');
          var isElem = Fun.curry(Compare.eq, cell);
          var index = Arr.findIndex(cells, isElem);
          return index !== -1 ? Option.some(index) : Option.none();
        });
      };

      var findRow = function (cell) {
        return SelectorFind.ancestor(cell, 'tbody,thead').bind(function (section) {
          return SelectorFind.ancestor(cell, 'tr').bind(function (row) {
            var rows = SelectorFilter.descendants(section, 'tr');
            var isRow = Fun.curry(Compare.eq, row);
            var index = Arr.findIndex(rows, isRow);
            return index !== -1 ? Option.some(index) : Option.none();
          });
        });
      };

      var lookupTable = function (scope) {
        return SelectorFind.ancestor(scope, 'table');
      };

      var boxIt = function (start, finish) {
        // Check they have the same table.
        return DomParent.sharedOne(lookupTable, [ start, finish ]).bind(function (tbl) {
          // For all the rows, identify the information.
          var rows = SelectorFilter.descendants(tbl, 'tr');
          return findInTable(tbl, start).bind(function (startData) {
            return findInTable(tbl, finish).map(function (finishData) {
              console.log('startData', startData, 'finishData', finishData);
              var minRowIndex = Math.min(startData.rowIndex(), finishData.rowIndex());
              var maxRowIndex = Math.max(startData.rowIndex(), finishData.rowIndex());
              var subrows = rows.slice(minRowIndex, maxRowIndex + 1);
              console.log('subrows', Arr.map(subrows, function (r) { return r.dom(); }));
              return Arr.bind(subrows, function (r) {
                var cells = SelectorFilter.children(r, 'td,th');
                var minCellIndex = Math.min(startData.colIndex(), finishData.colIndex());
                var maxCellIndex = Math.max(startData.colIndex(), finishData.colIndex());
                var blah = cells.slice(minCellIndex, maxCellIndex + 1);
                console.log('blah', Arr.map(blah, function (b) { return b.dom(); }));
                return blah;
              });
            });
          });
        });
      };

      var magic = function () {
        var cursor = Option.none();
        DomEvent.bind(table, 'mousedown', function (event) {
          var selected = SelectorFilter.descendants(table, '.selected');
          Arr.each(selected, function (td) {
            Class.remove(td, 'selected');
          });

          cursor = SelectorFind.closest(event.target(), 'td,th');
          console.log('mousedown');
        });

        DomEvent.bind(table, 'mouseover', function (event) {

          var boxes = cursor.bind(function (cur) {
            var selected = SelectorFilter.descendants(table, '.selected');
            Arr.each(selected, function (td) {
              Class.remove(td, 'selected');
            });

            var boxes = SelectorFind.closest(event.target(), 'td,th').bind(function (finish) {
              console.log('start', cur.dom(), 'finish', finish.dom());
              return boxIt(cur, finish);
            }).getOr([]);

            if (boxes.length > 0) {
              console.log('boxing');
              Arr.each(boxes, function (box) {
                Class.add(box, 'selected');
              });

              window.getSelection().removeAllRanges();
            }
            console.log('mouseover', boxes);
          });
        });

        DomEvent.bind(table, 'mouseup', function (event) {
          cursor = Option.none();
        });

        DomEvent.bind(table, 'keydown', function (event) {
          WindowSelection.get(window).each(function (sel) {
            if (event.raw().which === 40 || event.raw().which === 38) {
              var mover = event.raw().which === 40 ? TableKeys.handleDown : TableKeys.handleUp;
              mover(window, Fun.constant(false), sel.finish(), sel.foffset()).each(function (exact) {
                WindowSelection.set(window, SelectionRange.write(
                  event.raw().shiftKey ? Situ.on(sel.start(), sel.soffset()) : Situ.on(exact.start(), exact.soffset()),
                  Situ.on(exact.start(), exact.soffset())
                ));
                event.kill();
                console.log('next', exact.start().dom(), exact.soffset(), exact.start().dom().childNodes.length);
              });
            }
          });
        });

      };

      magic();
    };
  }
);<|endoftext|>


<commit_before>import React, {Component} from "react";

export default class Money extends Component {

  constructor() {
    super();
    this.state = {
      money: 0,
      count: 0,
      moneyBag: ["💰"]
    };
  }

  handleClick = (value) => {
    this.state.moneyBag.push("💰");
    this.setState({
      money: value,
      count: this.state.count + 1,
      moneyBag: this.state.moneyBag
    });
  }

  render() {
    // const {children, title, description} = this.props;
    console.log("moneybag: ", this.state.moneyBag);

    return (

 this.handleClick(this.state.money + 5)}>
        {this.state.moneyBag.map(() => {
          return
        })
        }

    )
      ;
  };
}<commit_msg>money money money<commit_after>import React, {Component} from "react";

export default class Money extends Component {

  constructor() {
    super();
    this.state = {
      money: 0,
      count: 0,
      moneyBag: ["💰"]
    };
  }

  handleClick = (value) => {
    if (this.state.count < 8) {
      this.state.moneyBag.push("💰");
    }
    this.setState({
      money: value,
      count: this.state.count + 1,
      moneyBag: this.state.moneyBag
    });
    if (this.state.count > 9) {
      this.setState(
        {
          moneyBag: ["💰"],
          count: 1
        });
    }
  }

  render() {
    // const {children, title, description} = this.props;
    console.log("moneybag: ", this.state.moneyBag);

    return (
      // 9

 this.handleClick(this.state.money + 5)}>
        { this.state.moneyBag.map(() => {
          if (this.state.count < 8) {
            return
          } else {
            return
          }
        })
        }

    )
      ;
  };
}<|endoftext|>


<commit_before>import EVENTS from '../events.js';
import {
  tap,
  doubleTap,
  touchStart,
  touchStartActive,
  touchDrag,
  touchEnd,
  touchPress,
  touchPinch,
  onImageRendered
} from './touchEventHandlers/index.js';

/**
 * These listeners are emitted in order, and can be cancelled/prevented from bubbling
 * by any previous event.
 * - tap:
 * - touchStart: check to see if we are close to an existing annotation, grab it
 * - touchDrag:
 * - touchStartActive: createNewMeasurement (usually)
 * - touchPress:
 * - doubleTap: usually a one-time apply specialty action
 * - touchPinch:
 * - onImageRendered: redraw visible tool data
 * @param {*} element
 */
const enable = function (element) {
  console.log('enableTouch', element);
  element.addEventListener(EVENTS.TAP, tap);
  element.addEventListener(EVENTS.TOUCH_START, touchStart);
  element.addEventListener(EVENTS.TOUCH_DRAG, touchDrag);
  element.addEventListener(EVENTS.TOUCH_END, touchEnd);
  // Mouse equivelant is `mouse_down_activate`
  // Should the naming pattern here match?
  element.addEventListener(EVENTS.TOUCH_START_ACTIVE, touchStartActive);
  element.addEventListener(EVENTS.TOUCH_PRESS, touchPress);
  element.addEventListener(EVENTS.DOUBLE_TAP, doubleTap);
  element.addEventListener(EVENTS.TOUCH_PINCH, touchPinch);
  element.addEventListener(EVENTS.IMAGE_RENDERED, onImageRendered);
};

export default {
  enable
  // Disable
};
<commit_msg>Add a disable method for touchToolEventDispatcher<commit_after>import EVENTS from '../events.js';
import {
  tap,
  doubleTap,
  touchStart,
  touchStartActive,
  touchDrag,
  touchEnd,
  touchPress,
  touchPinch,
  onImageRendered
} from './touchEventHandlers/index.js';

/**
 * These listeners are emitted in order, and can be cancelled/prevented from bubbling
 * by any previous event.
 * - tap:
 * - touchStart: check to see if we are close to an existing annotation, grab it
 * - touchDrag:
 * - touchStartActive: createNewMeasurement (usually)
 * - touchPress:
 * - doubleTap: usually a one-time apply specialty action
 * - touchPinch:
 * - onImageRendered: redraw visible tool data
 * @param {*} element
 */
const enable = function (element) {
  console.log('enableTouch', element);
  element.addEventListener(EVENTS.TAP, tap);
  element.addEventListener(EVENTS.TOUCH_START, touchStart);
  element.addEventListener(EVENTS.TOUCH_DRAG, touchDrag);
  element.addEventListener(EVENTS.TOUCH_END, touchEnd);
  // Mouse equivelant is `mouse_down_activate`
  // Should the naming pattern here match?
  element.addEventListener(EVENTS.TOUCH_START_ACTIVE, touchStartActive);
  element.addEventListener(EVENTS.TOUCH_PRESS, touchPress);
  element.addEventListener(EVENTS.DOUBLE_TAP, doubleTap);
  element.addEventListener(EVENTS.TOUCH_PINCH, touchPinch);
  element.addEventListener(EVENTS.IMAGE_RENDERED, onImageRendered);
};

const disable = function (element) {
  console.log('enableTouch', element);
  element.removeEventListener(EVENTS.TAP, tap);
  element.removeEventListener(EVENTS.TOUCH_START, touchStart);
  element.removeEventListener(EVENTS.TOUCH_DRAG, touchDrag);
  element.removeEventListener(EVENTS.TOUCH_END, touchEnd);
  // Mouse equivelant is `mouse_down_activate`
  // Should the naming pattern here match?
  element.removeEventListener(EVENTS.TOUCH_START_ACTIVE, touchStartActive);
  element.removeEventListener(EVENTS.TOUCH_PRESS, touchPress);
  element.removeEventListener(EVENTS.DOUBLE_TAP, doubleTap);
  element.removeEventListener(EVENTS.TOUCH_PINCH, touchPinch);
  element.removeEventListener(EVENTS.IMAGE_RENDERED, onImageRendered);
};

export default {
  enable,
  disable
};
<|endoftext|>


<commit_before>;(function($$){

	var CanvasRenderer = $$('renderer', 'canvas');

	CanvasRenderer.prototype.getPixelRatio = function(){
		var canvas = this.data.canvases[0];
		var context = canvas.getContext("2d");

		var backingStore = context.backingStorePixelRatio ||
			context.webkitBackingStorePixelRatio ||
			context.mozBackingStorePixelRatio ||
			context.msBackingStorePixelRatio ||
			context.oBackingStorePixelRatio ||
			context.backingStorePixelRatio || 1;

		//console.log(window.devicePixelRatio, backingStore);

		var isFirefox = typeof InstallTrigger !== 'undefined';

		if( isFirefox ){ // because ff can't scale canvas properly
			return 1;
		}

		return (window.devicePixelRatio || 1) / backingStore;
	}

	// Resize canvas
	CanvasRenderer.prototype.matchCanvasSize = function(container) {
		var data = this.data; var width = container.clientWidth; var height = container.clientHeight;

		var canvas, canvasWidth = width, canvasHeight = height;
		var pixelRatio = this.getPixelRatio();

		// apply pixel ratio
		canvasWidth *= pixelRatio;
		canvasHeight *= pixelRatio;

		var canvasContainer = data.canvasContainer;
		canvasContainer.style.width = width + 'px';
		canvasContainer.style.height = height + 'px';

		for (var i = 0; i < CanvasRenderer.CANVAS_LAYERS; i++) {

			canvas = data.canvases[i];

			if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {

				canvas.width = canvasWidth;
				canvas.height = canvasHeight;

				canvas.style.width = width + 'px';
				canvas.style.height = height + 'px';
			}
		}

		for (var i = 0; i < CanvasRenderer.BUFFER_COUNT; i++) {

			canvas = data.bufferCanvases[i];

			if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {

				canvas.width = canvasWidth;
				canvas.height = canvasHeight;
			}
		}

	}

	CanvasRenderer.prototype.renderTo = function( cxt, zoom, pan ){
		this.redraw({
			forcedContext: cxt,
			forcedZoom: zoom,
			forcedPan: pan,
			drawAllLayers: true
		});
	};

	// Redraw frame
	CanvasRenderer.prototype.redraw = function( options ) {
		options = options || {};

		var forcedContext = options.forcedContext;
		var drawAllLayers = options.drawAllLayers;
		var forcedZoom = options.forcedZoom;
		var forcedPan = options.forcedPan;
		var r = this;
		var pixelRatio = this.getPixelRatio();
		var cy = r.data.cy; var data = r.data;

		clearTimeout( this.redrawTimeout );

		if( this.averageRedrawTime === undefined ){ this.averageRedrawTime = 0; }

		var minRedrawLimit = 1000/60; // people can't see much better than 60fps
		var maxRedrawLimit = 1000; // don't cap max b/c it's more important to be responsive than smooth

		var redrawLimit = this.averageRedrawTime; // estimate the ideal redraw limit based on how fast we can draw
		redrawLimit = Math.max(minRedrawLimit, redrawLimit);
		redrawLimit = Math.min(redrawLimit, maxRedrawLimit);

		//console.log('--\nideal: %i; effective: %i', this.averageRedrawTime, redrawLimit);

		if( this.lastDrawTime === undefined ){ this.lastDrawTime = 0; }

		var nowTime = +new Date;
		var timeElapsed = nowTime - this.lastDrawTime;
		var callAfterLimit = timeElapsed >= redrawLimit;

		if( !forcedContext ){
			if( !callAfterLimit ){
				clearTimeout( this.redrawTimeout );
				this.redrawTimeout = setTimeout(function(){
					r.redraw();
				}, redrawLimit);
				return;
			}

			this.lastDrawTime = nowTime;
		}

		var startTime = nowTime;

		var looperMax = 100;
		//console.log('-- redraw --')

		// console.time('init'); for( var looper = 0; looper <= looperMax; looper++ ){

		// } console.timeEnd('init')

		function drawToContext(){
			var nodes = r.getCachedNodes(); var edges = r.getCachedEdges();

			if( !forcedContext ){
				r.matchCanvasSize(data.container);
			}

			var zoom = cy.zoom();
			var effectiveZoom = forcedZoom !== undefined ? forcedZoom : zoom;
			var pan = cy.pan();
			var effectivePan = {
				x: pan.x,
				y: pan.y
			};

			if( forcedPan ){
				effectivePan = forcedPan;
			}

			// apply pixel ratio
			effectiveZoom *= pixelRatio;
			effectivePan.x *= pixelRatio;
			effectivePan.y *= pixelRatio;

			var elements;
			var elesInDragLayer;
			var elesNotInDragLayer;
			var element;

			function setContextTransform(context){
				context.setTransform(1, 0, 0, 1, 0, 0);
				!forcedContext && context.clearRect(0, 0, context.canvas.width, context.canvas.height);

				if( !drawAllLayers ){
					context.translate(effectivePan.x, effectivePan.y);
					context.scale(effectiveZoom, effectiveZoom);
				}
				if( forcedPan ){
					context.translate(forcedPan.x, forcedPan.y);
				}
				if( forcedZoom ){
					context.scale(forcedZoom, forcedZoom);
				}
			}

			if (data.canvasNeedsRedraw[CanvasRenderer.DRAG] || data.canvasNeedsRedraw[CanvasRenderer.NODE] || drawAllLayers) {
				//NB : VERY EXPENSIVE
				//console.time('edgectlpts'); for( var looper = 0; looper <= looperMax; looper++ ){

				if( r.hideEdgesOnViewport && (r.pinching || r.hoverData.dragging || r.data.wheel || r.swipePanning) ){
				} else {
					r.findEdgeControlPoints(edges);
				}

				//} console.timeEnd('edgectlpts')

				// console.time('sort'); for( var looper = 0; looper <= looperMax; looper++ ){
				elements = r.getCachedZSortedEles();
				// } console.timeEnd('sort')

				elesInDragLayer = [];
				elesNotInDragLayer = [];

				for (var index = 0; index < elements.length; index++) {
					element = elements[index];

					if ( element._private.rscratch.inDragLayer ) {
						elesInDragLayer.push( element );
					} else {
						elesNotInDragLayer.push( element );
					}
				}

				// console.time('updatecompounds'); for( var looper = 0; looper <= looperMax; looper++ ){
				// no need to update graph if there is no compound node
				if ( cy.hasCompoundNodes() )
				{
					r.updateAllCompounds(elements);
				}
				// } console.timeEnd('updatecompounds')
			}

			function drawElements( eleList, context ){
				for (var i = 0; i < eleList.length; i++) {
					element = eleList[i];

					if (element._private.group == "nodes") {
						r.drawNode(context, element);

					} else if (element._private.group == "edges") {
						r.drawEdge(context, element);
					}
				}

				for (var i = 0; i < eleList.length; i++) {
					element = eleList[i];

					if (element._private.group == "nodes") {
						r.drawNodeText(context, element);
					} else if (element._private.group == "edges") {
						r.drawEdgeText(context, element);
					}

					// draw the overlay
					if (element._private.group == "nodes") {
						r.drawNode(context, element, true);
					} else if (element._private.group == "edges") {
						r.drawEdge(context, element, true);
					}
				}
			}

			// console.time('drawing'); for( var looper = 0; looper <= looperMax; looper++ ){
			if (data.canvasNeedsRedraw[CanvasRenderer.NODE] || drawAllLayers) {
				// console.log("redrawing node layer");

				var context = forcedContext || data.canvases[CanvasRenderer.NODE].getContext("2d");

				setContextTransform( context );
				drawElements(elesNotInDragLayer, context);

				if( !drawAllLayers ){
					data.canvasNeedsRedraw[CanvasRenderer.NODE] = false;
				}
			}

			if (data.canvasNeedsRedraw[CanvasRenderer.DRAG] || drawAllLayers) {

				var context = forcedContext || data.canvases[CanvasRenderer.DRAG].getContext("2d");

				setContextTransform( context );
				drawElements(elesInDragLayer, context);

				if( !drawAllLayers ){
					data.canvasNeedsRedraw[CanvasRenderer.DRAG] = false;
				}
			}

			if (data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] && !drawAllLayers) {
				// console.log("redrawing selection box");

				var context = forcedContext || data.canvases[CanvasRenderer.SELECT_BOX].getContext("2d");

				setContextTransform( context );

				var coreStyle = cy.style()._private.coreStyle;

				if (data.select[4] == 1) {
					var zoom = data.cy.zoom();
					var borderWidth = coreStyle["selection-box-border-width"].value / zoom;

					context.lineWidth = borderWidth;
					context.fillStyle = "rgba("
						+ coreStyle["selection-box-color"].value[0] + ","
						+ coreStyle["selection-box-color"].value[1] + ","
						+ coreStyle["selection-box-color"].value[2] + ","
						+ coreStyle["selection-box-opacity"].value + ")";

					context.fillRect(
						data.select[0],
						data.select[1],
						data.select[2] - data.select[0],
						data.select[3] - data.select[1]);

					if (borderWidth > 0) {
						context.strokeStyle = "rgba("
							+ coreStyle["selection-box-border-color"].value[0] + ","
							+ coreStyle["selection-box-border-color"].value[1] + ","
							+ coreStyle["selection-box-border-color"].value[2] + ","
							+ coreStyle["selection-box-opacity"].value + ")";

						context.strokeRect(
							data.select[0],
							data.select[1],
							data.select[2] - data.select[0],
							data.select[3] - data.select[1]);
					}
				}

				if( data.bgActivePosistion ){
					var zoom = data.cy.zoom();
					var pos = data.bgActivePosistion;

					context.fillStyle = "rgba("
						+ coreStyle["active-bg-color"].value[0] + ","
						+ coreStyle["active-bg-color"].value[1] + ","
						+ coreStyle["active-bg-color"].value[2] + ","
						+ coreStyle["active-bg-opacity"].value + ")";

					context.beginPath();
					context.arc(pos.x, pos.y, coreStyle["active-bg-size"].pxValue / zoom, 0, 2 * Math.PI);
					context.fill();
				}

				if( !drawAllLayers ){
					data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = false;
				}
			}

			// } console.timeEnd('drawing')

			var endTime = +new Date;

			if( r.averageRedrawTime === undefined ){
				r.averageRedrawTime = endTime - startTime;
			}

			// use a weighted average with a bias from the previous average so we don't spike so easily
			r.averageRedrawTime = r.averageRedrawTime/2 + (endTime - startTime)/2;
			//console.log('actual: %i, average: %i', endTime - startTime, this.averageRedrawTime);
		}

		if( !forcedContext ){
			setTimeout(drawToContext, 0); // makes direct renders to screen a bit more responsive
		} else {
			drawToContext();
		}

		if( !forcedContext && !r.initrender ){
			r.initrender = true;
			cy.trigger('initrender');
		}

	};

})( cytoscape );
<commit_msg>revise drawing so it's a bit more efficient; also revise draw order of labels; fix #417<commit_after>;(function($$){

	var CanvasRenderer = $$('renderer', 'canvas');

	CanvasRenderer.prototype.getPixelRatio = function(){
		var canvas = this.data.canvases[0];
		var context = canvas.getContext("2d");

		var backingStore = context.backingStorePixelRatio ||
			context.webkitBackingStorePixelRatio ||
			context.mozBackingStorePixelRatio ||
			context.msBackingStorePixelRatio ||
			context.oBackingStorePixelRatio ||
			context.backingStorePixelRatio || 1;

		//console.log(window.devicePixelRatio, backingStore);

		var isFirefox = typeof InstallTrigger !== 'undefined';

		if( isFirefox ){ // because ff can't scale canvas properly
			return 1;
		}

		return (window.devicePixelRatio || 1) / backingStore;
	}

	// Resize canvas
	CanvasRenderer.prototype.matchCanvasSize = function(container) {
		var data = this.data; var width = container.clientWidth; var height = container.clientHeight;

		var canvas, canvasWidth = width, canvasHeight = height;
		var pixelRatio = this.getPixelRatio();

		// apply pixel ratio
		canvasWidth *= pixelRatio;
		canvasHeight *= pixelRatio;

		var canvasContainer = data.canvasContainer;
		canvasContainer.style.width = width + 'px';
		canvasContainer.style.height = height + 'px';

		for (var i = 0; i < CanvasRenderer.CANVAS_LAYERS; i++) {

			canvas = data.canvases[i];

			if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {

				canvas.width = canvasWidth;
				canvas.height = canvasHeight;

				canvas.style.width = width + 'px';
				canvas.style.height = height + 'px';
			}
		}

		for (var i = 0; i < CanvasRenderer.BUFFER_COUNT; i++) {

			canvas = data.bufferCanvases[i];

			if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {

				canvas.width = canvasWidth;
				canvas.height = canvasHeight;
			}
		}

	}

	CanvasRenderer.prototype.renderTo = function( cxt, zoom, pan ){
		this.redraw({
			forcedContext: cxt,
			forcedZoom: zoom,
			forcedPan: pan,
			drawAllLayers: true
		});
	};

	// Redraw frame
	CanvasRenderer.prototype.redraw = function( options ) {
		options = options || {};

		var forcedContext = options.forcedContext;
		var drawAllLayers = options.drawAllLayers;
		var forcedZoom = options.forcedZoom;
		var forcedPan = options.forcedPan;
		var r = this;
		var pixelRatio = this.getPixelRatio();
		var cy = r.data.cy; var data = r.data;

		clearTimeout( this.redrawTimeout );

		if( this.averageRedrawTime === undefined ){ this.averageRedrawTime = 0; }

		var minRedrawLimit = 1000/60; // people can't see much better than 60fps
		var maxRedrawLimit = 1000; // don't cap max b/c it's more important to be responsive than smooth

		var redrawLimit = this.averageRedrawTime; // estimate the ideal redraw limit based on how fast we can draw
		redrawLimit = Math.max(minRedrawLimit, redrawLimit);
		redrawLimit = Math.min(redrawLimit, maxRedrawLimit);

		//console.log('--\nideal: %i; effective: %i', this.averageRedrawTime, redrawLimit);

		if( this.lastDrawTime === undefined ){ this.lastDrawTime = 0; }

		var nowTime = +new Date;
		var timeElapsed = nowTime - this.lastDrawTime;
		var callAfterLimit = timeElapsed >= redrawLimit;

		if( !forcedContext ){
			if( !callAfterLimit ){
				clearTimeout( this.redrawTimeout );
				this.redrawTimeout = setTimeout(function(){
					r.redraw();
				}, redrawLimit);
				return;
			}

			this.lastDrawTime = nowTime;
		}

		var startTime = nowTime;

		var looperMax = 100;
		//console.log('-- redraw --')

		// console.time('init'); for( var looper = 0; looper <= looperMax; looper++ ){

		// } console.timeEnd('init')

		function drawToContext(){
			var nodes = r.getCachedNodes(); var edges = r.getCachedEdges();

			if( !forcedContext ){
				r.matchCanvasSize(data.container);
			}

			var zoom = cy.zoom();
			var effectiveZoom = forcedZoom !== undefined ? forcedZoom : zoom;
			var pan = cy.pan();
			var effectivePan = {
				x: pan.x,
				y: pan.y
			};

			if( forcedPan ){
				effectivePan = forcedPan;
			}

			// apply pixel ratio
			effectiveZoom *= pixelRatio;
			effectivePan.x *= pixelRatio;
			effectivePan.y *= pixelRatio;

			var elements;
			var elesInDragLayer;
			var elesNotInDragLayer;
			var element;

			function setContextTransform(context){
				context.setTransform(1, 0, 0, 1, 0, 0);
				!forcedContext && context.clearRect(0, 0, context.canvas.width, context.canvas.height);

				if( !drawAllLayers ){
					context.translate(effectivePan.x, effectivePan.y);
					context.scale(effectiveZoom, effectiveZoom);
				}
				if( forcedPan ){
					context.translate(forcedPan.x, forcedPan.y);
				}
				if( forcedZoom ){
					context.scale(forcedZoom, forcedZoom);
				}
			}

			if (data.canvasNeedsRedraw[CanvasRenderer.DRAG] || data.canvasNeedsRedraw[CanvasRenderer.NODE] || drawAllLayers) {
				//NB : VERY EXPENSIVE
				//console.time('edgectlpts'); for( var looper = 0; looper <= looperMax; looper++ ){

				if( r.hideEdgesOnViewport && (r.pinching || r.hoverData.dragging || r.data.wheel || r.swipePanning) ){
				} else {
					r.findEdgeControlPoints(edges);
				}

				//} console.timeEnd('edgectlpts')

				// console.time('sort'); for( var looper = 0; looper <= looperMax; looper++ ){
				elements = r.getCachedZSortedEles();
				// } console.timeEnd('sort')

				elesInDragLayer = [];
				elesNotInDragLayer = [];

				for (var index = 0; index < elements.length; index++) {
					element = elements[index];

					if ( element._private.rscratch.inDragLayer ) {
						elesInDragLayer.push( element );
					} else {
						elesNotInDragLayer.push( element );
					}
				}

				// console.time('updatecompounds'); for( var looper = 0; looper <= looperMax; looper++ ){
				// no need to update graph if there is no compound node
				if ( cy.hasCompoundNodes() )
				{
					r.updateAllCompounds(elements);
				}
				// } console.timeEnd('updatecompounds')
			}

			function drawElements( eleList, context ){
				var edges = [];

				for (var i = 0; i < eleList.length; i++) {
					element = eleList[i];

					if ( element.isNode() ) {
						r.drawNode(context, element);
						r.drawNodeText(context, element);
						r.drawNode(context, element, true);

					} else if ( element.isEdge() ) {
						r.drawEdge(context, element);
						edges.push( element );
					}
				}

				for (var i = 0; i < edges.length; i++) {
					element = edges[i];

					r.drawEdgeText(context, element);
					r.drawEdge(context, element, true);
				}
			}

			// console.time('drawing'); for( var looper = 0; looper <= looperMax; looper++ ){
			if (data.canvasNeedsRedraw[CanvasRenderer.NODE] || drawAllLayers) {
				// console.log("redrawing node layer");

				var context = forcedContext || data.canvases[CanvasRenderer.NODE].getContext("2d");

				setContextTransform( context );
				drawElements(elesNotInDragLayer, context);

				if( !drawAllLayers ){
					data.canvasNeedsRedraw[CanvasRenderer.NODE] = false;
				}
			}

			if (data.canvasNeedsRedraw[CanvasRenderer.DRAG] || drawAllLayers) {

				var context = forcedContext || data.canvases[CanvasRenderer.DRAG].getContext("2d");

				setContextTransform( context );
				drawElements(elesInDragLayer, context);

				if( !drawAllLayers ){
					data.canvasNeedsRedraw[CanvasRenderer.DRAG] = false;
				}
			}

			if (data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] && !drawAllLayers) {
				// console.log("redrawing selection box");

				var context = forcedContext || data.canvases[CanvasRenderer.SELECT_BOX].getContext("2d");

				setContextTransform( context );

				var coreStyle = cy.style()._private.coreStyle;

				if (data.select[4] == 1) {
					var zoom = data.cy.zoom();
					var borderWidth = coreStyle["selection-box-border-width"].value / zoom;

					context.lineWidth = borderWidth;
					context.fillStyle = "rgba("
						+ coreStyle["selection-box-color"].value[0] + ","
						+ coreStyle["selection-box-color"].value[1] + ","
						+ coreStyle["selection-box-color"].value[2] + ","
						+ coreStyle["selection-box-opacity"].value + ")";

					context.fillRect(
						data.select[0],
						data.select[1],
						data.select[2] - data.select[0],
						data.select[3] - data.select[1]);

					if (borderWidth > 0) {
						context.strokeStyle = "rgba("
							+ coreStyle["selection-box-border-color"].value[0] + ","
							+ coreStyle["selection-box-border-color"].value[1] + ","
							+ coreStyle["selection-box-border-color"].value[2] + ","
							+ coreStyle["selection-box-opacity"].value + ")";

						context.strokeRect(
							data.select[0],
							data.select[1],
							data.select[2] - data.select[0],
							data.select[3] - data.select[1]);
					}
				}

				if( data.bgActivePosistion ){
					var zoom = data.cy.zoom();
					var pos = data.bgActivePosistion;

					context.fillStyle = "rgba("
						+ coreStyle["active-bg-color"].value[0] + ","
						+ coreStyle["active-bg-color"].value[1] + ","
						+ coreStyle["active-bg-color"].value[2] + ","
						+ coreStyle["active-bg-opacity"].value + ")";

					context.beginPath();
					context.arc(pos.x, pos.y, coreStyle["active-bg-size"].pxValue / zoom, 0, 2 * Math.PI);
					context.fill();
				}

				if( !drawAllLayers ){
					data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = false;
				}
			}

			// } console.timeEnd('drawing')

			var endTime = +new Date;

			if( r.averageRedrawTime === undefined ){
				r.averageRedrawTime = endTime - startTime;
			}

			// use a weighted average with a bias from the previous average so we don't spike so easily
			r.averageRedrawTime = r.averageRedrawTime/2 + (endTime - startTime)/2;
			//console.log('actual: %i, average: %i', endTime - startTime, this.averageRedrawTime);
		}

		if( !forcedContext ){
			setTimeout(drawToContext, 0); // makes direct renders to screen a bit more responsive
		} else {
			drawToContext();
		}

		if( !forcedContext && !r.initrender ){
			r.initrender = true;
			cy.trigger('initrender');
		}

	};

})( cytoscape );
<|endoftext|>


<commit_before>/*
  backgrid-select-all
  http://github.com/wyuenho/backgrid

  Copyright (c) 2013 Jimmy Yuen Ho Wong
  Licensed under the MIT @license.
*/
(function (window, $, _, Backbone, Backgrid)  {

  /**
     Renders a checkbox for row selection.

     @class Backgrid.Extension.SelectRowCell
     @extends Backbone.View
   */
  var SelectRowCell = Backgrid.Extension.SelectRowCell = Backbone.View.extend({

    /** @property */
    className: "select-row-cell",

    /** @property */
    tagName: "td",

    /** @property */
    events: {
      "change": "onChange"
    },

    /**
       Initializer. Listens to the model's `select` event and check or uncheck
       this cell's checkbox accordingly.

       @param {Object} options
       @param {Backgrid.Column} options.column
       @param {Backbone.Model} options.model
     */
    initialize: function (options) {

      this.column = options.column;
      if (!(this.column instanceof Backgrid.Column)) {
        this.column = new Backgrid.Column(this.column);
      }

      this.listenTo(this.model, "select", function (model, selected) {
        this.$el.find(":checkbox").prop("checked", selected);
      });

    },

    /**
       When the checkbox's value changes, this method will trigger a Backbone
       `selected` event with a reference of the model and the checkbox''
       `checked` value.
     */
    onChange: function (e) {
      this.model.trigger("selected", this.model, $(e.target).prop("checked"));
    },

    /**
       Renders a checkbox in a table cell.
     */
    render: function () {
      this.$el.empty().append("<input type='checkbox' />");
      return this;
    }

  });

  /**
     Renders a checkbox to select all rows on the current page.

     @class Backgrid.Extension.SelectAllHeaderCell
     @extends Backgrid.Extension.SelectRowCell
   */
  Backgrid.Extension.SelectAllHeaderCell = SelectRowCell.extend({

    /** @property */
    className: "select-all-header-cell",

    /** @property */
    tagName: "th",

    /**
       Initializer.

       If all of the models on the current page has been selected, this header
       cell will check its checkbox. If the underlying collection has been
       emptied, the checkbox will uncheck. If the checkbox is checked when the
       entire grid refreshes itself, this header cell will trigger a Backbone
       `select` event on each model in the underlying collection, passing the
       model and the current `checked` checkbox value in each event.

       @param {Object} options
       @param {Backgrid.Column} options.column
       @param {Backbone.Collection} options.collection
     */
    initialize: function (options) {

      this.column = options.column;
      if (!(this.column instanceof Backgrid.Column)) {
        this.column = new Backgrid.Column(this.column);
      }

      var collection = this.collection;
      var selectedCount = 0;
      this.listenTo(collection, "selected", function (model, selected) {
        if (!selected) {
          this.$el.find(":checkbox").prop("checked", selected);
          selectedCount--;
        }
        else {
          selectedCount++;
        }

        if (collection.length && selectedCount === collection.length) {
          this.undelegateEvents();
          this.$el.find(":checkbox").prop("checked", true);
          this.delegateEvents();
        }
      });

      this.listenTo(collection, "remove reset", function () {
        if (!collection.length) {
          this.$el.find(":checkbox").prop("checked", false);
        }
      });

      this.listenTo(Backbone, "backgrid:refresh", function () {
        if (this.$el.find(":checkbox").prop("checked")) {
          collection.each(function (model) {
            model.trigger("select", model, true);
          });
        }
      });
    },

    /**
       Progagates the checked value of this checkbox to all the models of the
       underlying collection by triggering a Backbone `select` event on the
       models themselves, passing each model and the current `checked` value of
       the checkbox in each event.
     */
    onChange: function (e) {
      var checked = $(e.target).prop("checked");

      var collection = this.collection;
      collection.each(function (model) {
        model.trigger("select", model, checked);
      });
    }

  });

}(window, jQuery, _, Backbone, Backgrid));
<commit_msg>Force a change event for webkit after changing checked property<commit_after>/*
  backgrid-select-all
  http://github.com/wyuenho/backgrid

  Copyright (c) 2013 Jimmy Yuen Ho Wong
  Licensed under the MIT @license.
*/
(function (window, $, _, Backbone, Backgrid)  {

  /**
     Renders a checkbox for row selection.

     @class Backgrid.Extension.SelectRowCell
     @extends Backbone.View
   */
  var SelectRowCell = Backgrid.Extension.SelectRowCell = Backbone.View.extend({

    /** @property */
    className: "select-row-cell",

    /** @property */
    tagName: "td",

    /** @property */
    events: {
      "change": "onChange"
    },

    /**
       Initializer. Listens to the model's `select` event and check or uncheck
       this cell's checkbox accordingly.

       @param {Object} options
       @param {Backgrid.Column} options.column
       @param {Backbone.Model} options.model
     */
    initialize: function (options) {

      this.column = options.column;
      if (!(this.column instanceof Backgrid.Column)) {
        this.column = new Backgrid.Column(this.column);
      }

      this.listenTo(this.model, "select", function (model, selected) {
        this.$el.find(":checkbox").prop("checked", selected).change();
      });

    },

    /**
       When the checkbox's value changes, this method will trigger a Backbone
       `selected` event with a reference of the model and the checkbox''
       `checked` value.
     */
    onChange: function (e) {
      this.model.trigger("selected", this.model, $(e.target).prop("checked"));
    },

    /**
       Renders a checkbox in a table cell.
     */
    render: function () {
      this.$el.empty().append("<input type='checkbox' />");
      return this;
    }

  });

  /**
     Renders a checkbox to select all rows on the current page.

     @class Backgrid.Extension.SelectAllHeaderCell
     @extends Backgrid.Extension.SelectRowCell
   */
  Backgrid.Extension.SelectAllHeaderCell = SelectRowCell.extend({

    /** @property */
    className: "select-all-header-cell",

    /** @property */
    tagName: "th",

    /**
       Initializer.

       If all of the models on the current page has been selected, this header
       cell will check its checkbox. If the underlying collection has been
       emptied, the checkbox will uncheck. If the checkbox is checked when the
       entire grid refreshes itself, this header cell will trigger a Backbone
       `select` event on each model in the underlying collection, passing the
       model and the current `checked` checkbox value in each event.

       @param {Object} options
       @param {Backgrid.Column} options.column
       @param {Backbone.Collection} options.collection
     */
    initialize: function (options) {

      this.column = options.column;
      if (!(this.column instanceof Backgrid.Column)) {
        this.column = new Backgrid.Column(this.column);
      }

      var collection = this.collection;
      var selectedCount = 0;
      this.listenTo(collection, "selected", function (model, selected) {
        if (!selected) {
          this.$el.find(":checkbox").prop("checked", selected);
          selectedCount--;
        }
        else {
          selectedCount++;
        }

        if (collection.length && selectedCount === collection.length) {
          this.undelegateEvents();
          this.$el.find(":checkbox").prop("checked", true);
          this.delegateEvents();
        }
      });

      this.listenTo(collection, "remove reset", function () {
        if (!collection.length) {
          this.$el.find(":checkbox").prop("checked", false);
        }
      });

      this.listenTo(Backbone, "backgrid:refresh", function () {
        if (this.$el.find(":checkbox").prop("checked")) {
          collection.each(function (model) {
            model.trigger("select", model, true);
          });
        }
      });
    },

    /**
       Progagates the checked value of this checkbox to all the models of the
       underlying collection by triggering a Backbone `select` event on the
       models themselves, passing each model and the current `checked` value of
       the checkbox in each event.
     */
    onChange: function (e) {
      var checked = $(e.target).prop("checked");

      var collection = this.collection;
      collection.each(function (model) {
        model.trigger("select", model, checked);
      });
    }

  });

}(window, jQuery, _, Backbone, Backgrid));
<|endoftext|>