virtualcommons-svn Mailing List for Virtual Commons Experiment Software (Page 2)
Status: Beta
Brought to you by:
alllee
You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(21) |
Aug
(31) |
Sep
(6) |
Oct
(15) |
Nov
(2) |
Dec
(9) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(4) |
Feb
(6) |
Mar
(12) |
Apr
(52) |
May
(14) |
Jun
(19) |
Jul
(81) |
Aug
(115) |
Sep
(36) |
Oct
(88) |
Nov
(46) |
Dec
(58) |
2010 |
Jan
(52) |
Feb
(55) |
Mar
(48) |
Apr
(15) |
May
(5) |
Jun
(38) |
Jul
(27) |
Aug
(24) |
Sep
(28) |
Oct
(1) |
Nov
(2) |
Dec
(29) |
2011 |
Jan
(87) |
Feb
(39) |
Mar
(63) |
Apr
(42) |
May
(26) |
Jun
(53) |
Jul
(23) |
Aug
(43) |
Sep
(37) |
Oct
(25) |
Nov
(4) |
Dec
(7) |
2012 |
Jan
(73) |
Feb
(79) |
Mar
(62) |
Apr
(28) |
May
(12) |
Jun
(2) |
Jul
(9) |
Aug
(1) |
Sep
(8) |
Oct
|
Nov
(3) |
Dec
(3) |
2013 |
Jan
(8) |
Feb
(16) |
Mar
(38) |
Apr
(74) |
May
(62) |
Jun
(15) |
Jul
(49) |
Aug
(19) |
Sep
(9) |
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
(25) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <com...@bi...> - 2014-04-08 20:33:39
|
1 new commit in foraging: https://bitbucket.org/virtualcommons/foraging/commits/1fa58fd4e98c/ Changeset: 1fa58fd4e98c User: alllee Date: 2014-04-08 22:30:51 Summary: merging stable back into default and adding ResourceOverTimeProcessor to report simple resource distribution / size Affected #: 3 files diff -r 4aeac01665735e7d2c07775fb9139394218a2394 -r 1fa58fd4e98ca404d4f53f1183fb733d9bbd7e53 build.xml --- a/build.xml +++ b/build.xml @@ -5,7 +5,7 @@ --><project xmlns:ivy="antlib:org.apache.ivy.ant" name="foraging" default="build-all" basedir="."><!-- ensure ivy availability --> - <property name="ivy.install.version" value="2.2.0"/> + <property name="ivy.install.version" value="2.3.0"/><condition property="ivy.home" value="${env.IVY_HOME}"><isset property="env.IVY_HOME"/></condition> diff -r 4aeac01665735e7d2c07775fb9139394218a2394 -r 1fa58fd4e98ca404d4f53f1183fb733d9bbd7e53 src/main/java/edu/asu/commons/foraging/data/ForagingSaveFileConverter.java --- a/src/main/java/edu/asu/commons/foraging/data/ForagingSaveFileConverter.java +++ b/src/main/java/edu/asu/commons/foraging/data/ForagingSaveFileConverter.java @@ -25,7 +25,8 @@ if (allSaveFilesDirectory.exists() && allSaveFilesDirectory.isDirectory()) { List<SaveFileProcessor> processors = new ArrayList<SaveFileProcessor>(); processors.addAll(Arrays.asList( - new AllDataProcessor(), + new AllDataProcessor(), + new ResourceOverTimeProcessor(), new AggregateTimeIntervalProcessor(), new SummaryProcessor(), new AggregateTokenSpatialDistributionProcessor(), diff -r 4aeac01665735e7d2c07775fb9139394218a2394 -r 1fa58fd4e98ca404d4f53f1183fb733d9bbd7e53 src/main/java/edu/asu/commons/foraging/data/ResourceOverTimeProcessor.java --- /dev/null +++ b/src/main/java/edu/asu/commons/foraging/data/ResourceOverTimeProcessor.java @@ -0,0 +1,85 @@ +package edu.asu.commons.foraging.data; + +import java.io.PrintWriter; +import java.util.List; + +import edu.asu.commons.event.PersistableEvent; +import edu.asu.commons.experiment.SaveFileProcessor; +import edu.asu.commons.experiment.SavedRoundData; +import edu.asu.commons.foraging.event.ClientPoseUpdate; +import edu.asu.commons.foraging.event.MovementEvent; +import edu.asu.commons.foraging.event.ResourceAddedEvent; +import edu.asu.commons.foraging.event.ResourcesAddedEvent; +import edu.asu.commons.foraging.event.TokenCollectedEvent; +import edu.asu.commons.foraging.model.ClientData; +import edu.asu.commons.foraging.model.GroupDataModel; +import edu.asu.commons.foraging.model.ServerDataModel; +import edu.asu.commons.util.Utils; + +/** + * $Id$ + * + * Generates a simple resource over time data file. + * + * @author <a href='mailto:all...@as...'>Allen Lee</a> + * @version $Rev: 526 $ + */ +public class ResourceOverTimeProcessor extends SaveFileProcessor.Base { + public ResourceOverTimeProcessor() { + setSecondsPerInterval(1); + } + + public void process(SavedRoundData savedRoundData, PrintWriter writer) { + // populate ordered identifiers, first try directly from the participant tokens map that + // is persisted in later versions of the experiment. + ServerDataModel serverDataModel = (ServerDataModel) savedRoundData.getDataModel(); + for (ClientData clientData : serverDataModel.getClientDataMap().values()) { + clientData.initializePosition(); + } + List<GroupDataModel> groups = serverDataModel.getOrderedGroups(); + writer.println("Group, Time, Resource Size"); + for (PersistableEvent event : savedRoundData.getActions()) { + long secondsElapsed = savedRoundData.getElapsedTimeInSeconds(event); + // see if the current persistable event is past the threshold, + // meaning we should take a snapshot of our currently + // accumulated stats + if (isIntervalElapsed(secondsElapsed)) { + // generate group expected token counts + for (GroupDataModel group : groups) { + writer.println(Utils.join(',', group.toString(), secondsElapsed, group.getResourceDistributionSize())); + } + } + // next, process the current persistable event + if (event instanceof MovementEvent) { + MovementEvent movementEvent = (MovementEvent) event; + serverDataModel.moveClient(movementEvent.getId(), movementEvent.getDirection()); + } + else if (event instanceof ClientPoseUpdate) { + ClientPoseUpdate clientPoseUpdate = (ClientPoseUpdate) event; + serverDataModel.getClientDataMap().get(event.getId()).setPosition(clientPoseUpdate.getPosition()); + } + else if (event instanceof TokenCollectedEvent) { + TokenCollectedEvent tokenCollectedEvent = (TokenCollectedEvent) event; + GroupDataModel group = serverDataModel.getGroup(tokenCollectedEvent.getId()); + assert serverDataModel.getGroups().contains(group); + group.removeResource(tokenCollectedEvent.getLocation()); + } + else if (event instanceof ResourceAddedEvent) { + ResourceAddedEvent resourceAddedEvent = (ResourceAddedEvent) event; + assert serverDataModel.getGroups().contains(resourceAddedEvent.getGroup()); + resourceAddedEvent.getGroup().addResource(resourceAddedEvent.getPosition()); + } + else if (event instanceof ResourcesAddedEvent) { + ResourcesAddedEvent resourcesAddedEvent = (ResourcesAddedEvent) event; + assert serverDataModel.getGroups().contains(resourcesAddedEvent.getGroup()); + resourcesAddedEvent.getGroup().addResources(resourcesAddedEvent.getResources()); + } + } + } + + @Override + public String getOutputFileExtension() { + return "-resource-over-time.txt"; + } + +} Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2014-04-08 20:09:44
|
1 new commit in foraging: https://bitbucket.org/virtualcommons/foraging/commits/1fdfca014454/ Changeset: 1fdfca014454 Branch: stable User: alllee Date: 2014-04-08 22:09:34 Summary: ivy version bump Affected #: 1 file diff -r 9a85c86b5535bbce0764dcb500812e2475989254 -r 1fdfca0144542d350e511d5bee24c58b7c960aae build.xml --- a/build.xml +++ b/build.xml @@ -5,7 +5,7 @@ --><project xmlns:ivy="antlib:org.apache.ivy.ant" name="foraging" default="build-all" basedir="."><!-- ensure ivy availability --> - <property name="ivy.install.version" value="2.2.0"/> + <property name="ivy.install.version" value="2.3.0"/><condition property="ivy.home" value="${env.IVY_HOME}"><isset property="env.IVY_HOME"/></condition> Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-09-10 19:15:57
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/c62d69c5e3f2/ Changeset: c62d69c5e3f2 User: alllee Date: 2013-09-10 21:15:46 Summary: replacing validation plugin reference with CDN Affected #: 2 files diff -r 9a811282c6b908b58e108f2e6a61477d851d55ac -r c62d69c5e3f269f26963f2e= 701cd161938ac2512 vcweb/core/templates/includes/jquery.forms.html --- a/vcweb/core/templates/includes/jquery.forms.html +++ b/vcweb/core/templates/includes/jquery.forms.html @@ -1,1 +1,4 @@ -<script type=3D'text/javascript' src=3D'{{STATIC_URL}}js/jquery.validate.m= in.js'></script> +{% with jquery_validate_version=3D"1.11.1" %} +<script type=3D'text/javascript' src=3D'//ajax.aspnetcdn.com/ajax/jquery.v= alidate/{{jquery_validate_version}}/jquery.validate.min.js'></script> +{% endwith %} + diff -r 9a811282c6b908b58e108f2e6a61477d851d55ac -r c62d69c5e3f269f26963f2e= 701cd161938ac2512 vcweb/static/js/jquery.validate.min.js --- a/vcweb/static/js/jquery.validate.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery Validation Plugin - v1.11.1 - 3/22/2013\n* https://github.com/j= zaefferer/jquery-validation -* Copyright (c) 2013 J=C3=B6rn Zaefferer; Licensed MIT */(function(t){t.ex= tend(t.fn,{validate:function(e){if(!this.length)return e&&e.debug&&window.c= onsole&&console.warn("Nothing selected, can't validate, returning nothing."= ),void 0;var i=3Dt.data(this[0],"validator");return i?i:(this.attr("novalid= ate","novalidate"),i=3Dnew t.validator(e,this[0]),t.data(this[0],"validator= ",i),i.settings.onsubmit&&(this.validateDelegate(":submit","click",function= (e){i.settings.submitHandler&&(i.submitButton=3De.target),t(e.target).hasCl= ass("cancel")&&(i.cancelSubmit=3D!0),void 0!=3D=3Dt(e.target).attr("formnov= alidate")&&(i.cancelSubmit=3D!0)}),this.submit(function(e){function s(){var= s;return i.settings.submitHandler?(i.submitButton&&(s=3Dt("<input type=3D'= hidden'/>").attr("name",i.submitButton.name).val(t(i.submitButton).val()).a= ppendTo(i.currentForm)),i.settings.submitHandler.call(i,i.currentForm,e),i.= submitButton&&s.remove(),!1):!0}return i.settings.debug&&e.preventDefault()= ,i.cancelSubmit?(i.cancelSubmit=3D!1,s()):i.form()?i.pendingRequest?(i.form= Submitted=3D!0,!1):s():(i.focusInvalid(),!1)})),i)},valid:function(){if(t(t= his[0]).is("form"))return this.validate().form();var e=3D!0,i=3Dt(this[0].f= orm).validate();return this.each(function(){e=3De&&i.element(this)}),e},rem= oveAttrs:function(e){var i=3D{},s=3Dthis;return t.each(e.split(/\s/),functi= on(t,e){i[e]=3Ds.attr(e),s.removeAttr(e)}),i},rules:function(e,i){var s=3Dt= his[0];if(e){var r=3Dt.data(s.form,"validator").settings,n=3Dr.rules,a=3Dt.= validator.staticRules(s);switch(e){case"add":t.extend(a,t.validator.normali= zeRule(i)),delete a.messages,n[s.name]=3Da,i.messages&&(r.messages[s.name]= =3Dt.extend(r.messages[s.name],i.messages));break;case"remove":if(!i)return= delete n[s.name],a;var u=3D{};return t.each(i.split(/\s/),function(t,e){u[= e]=3Da[e],delete a[e]}),u}}var o=3Dt.validator.normalizeRules(t.extend({},t= .validator.classRules(s),t.validator.attributeRules(s),t.validator.dataRule= s(s),t.validator.staticRules(s)),s);if(o.required){var l=3Do.required;delet= e o.required,o=3Dt.extend({required:l},o)}return o}}),t.extend(t.expr[":"],= {blank:function(e){return!t.trim(""+t(e).val())},filled:function(e){return!= !t.trim(""+t(e).val())},unchecked:function(e){return!t(e).prop("checked")}}= ),t.validator=3Dfunction(e,i){this.settings=3Dt.extend(!0,{},t.validator.de= faults,e),this.currentForm=3Di,this.init()},t.validator.format=3Dfunction(e= ,i){return 1=3D=3D=3Darguments.length?function(){var i=3Dt.makeArray(argume= nts);return i.unshift(e),t.validator.format.apply(this,i)}:(arguments.lengt= h>2&&i.constructor!=3D=3DArray&&(i=3Dt.makeArray(arguments).slice(1)),i.con= structor!=3D=3DArray&&(i=3D[i]),t.each(i,function(t,i){e=3De.replace(RegExp= ("\\{"+t+"\\}","g"),function(){return i})}),e)},t.extend(t.validator,{defau= lts:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",e= rrorElement:"label",focusInvalid:!0,errorContainer:t([]),errorLabelContaine= r:t([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(t){t= his.lastActive=3Dt,this.settings.focusCleanup&&!this.blockFocusCleanup&&(th= is.settings.unhighlight&&this.settings.unhighlight.call(this,t,this.setting= s.errorClass,this.settings.validClass),this.addWrapper(this.errorsFor(t)).h= ide())},onfocusout:function(t){this.checkable(t)||!(t.name in this.submitte= d)&&this.optional(t)||this.element(t)},onkeyup:function(t,e){(9!=3D=3De.whi= ch||""!=3D=3Dthis.elementValue(t))&&(t.name in this.submitted||t=3D=3D=3Dth= is.lastElement)&&this.element(t)},onclick:function(t){t.name in this.submit= ted?this.element(t):t.parentNode.name in this.submitted&&this.element(t.par= entNode)},highlight:function(e,i,s){"radio"=3D=3D=3De.type?this.findByName(= e.name).addClass(i).removeClass(s):t(e).addClass(i).removeClass(s)},unhighl= ight:function(e,i,s){"radio"=3D=3D=3De.type?this.findByName(e.name).removeC= lass(i).addClass(s):t(e).removeClass(i).addClass(s)}},setDefaults:function(= e){t.extend(t.validator.defaults,e)},messages:{required:"This field is requ= ired.",remote:"Please fix this field.",email:"Please enter a valid email ad= dress.",url:"Please enter a valid URL.",date:"Please enter a valid date.",d= ateISO:"Please enter a valid date (ISO).",number:"Please enter a valid numb= er.",digits:"Please enter only digits.",creditcard:"Please enter a valid cr= edit card number.",equalTo:"Please enter the same value again.",maxlength:t= .validator.format("Please enter no more than {0} characters."),minlength:t.= validator.format("Please enter at least {0} characters."),rangelength:t.val= idator.format("Please enter a value between {0} and {1} characters long."),= range:t.validator.format("Please enter a value between {0} and {1}."),max:t= .validator.format("Please enter a value less than or equal to {0}."),min:t.= validator.format("Please enter a value greater than or equal to {0}.")},aut= oCreateRanges:!1,prototype:{init:function(){function e(e){var i=3Dt.data(th= is[0].form,"validator"),s=3D"on"+e.type.replace(/^validate/,"");i.settings[= s]&&i.settings[s].call(i,this[0],e)}this.labelContainer=3Dt(this.settings.e= rrorLabelContainer),this.errorContext=3Dthis.labelContainer.length&&this.la= belContainer||t(this.currentForm),this.containers=3Dt(this.settings.errorCo= ntainer).add(this.settings.errorLabelContainer),this.submitted=3D{},this.va= lueCache=3D{},this.pendingRequest=3D0,this.pending=3D{},this.invalid=3D{},t= his.reset();var i=3Dthis.groups=3D{};t.each(this.settings.groups,function(e= ,s){"string"=3D=3Dtypeof s&&(s=3Ds.split(/\s/)),t.each(s,function(t,s){i[s]= =3De})});var s=3Dthis.settings.rules;t.each(s,function(e,i){s[e]=3Dt.valida= tor.normalizeRule(i)}),t(this.currentForm).validateDelegate(":text, [type= =3D'password'], [type=3D'file'], select, textarea, [type=3D'number'], [type= =3D'search'] ,[type=3D'tel'], [type=3D'url'], [type=3D'email'], [type=3D'da= tetime'], [type=3D'date'], [type=3D'month'], [type=3D'week'], [type=3D'time= '], [type=3D'datetime-local'], [type=3D'range'], [type=3D'color'] ","focusi= n focusout keyup",e).validateDelegate("[type=3D'radio'], [type=3D'checkbox'= ], select, option","click",e),this.settings.invalidHandler&&t(this.currentF= orm).bind("invalid-form.validate",this.settings.invalidHandler)},form:funct= ion(){return this.checkForm(),t.extend(this.submitted,this.errorMap),this.i= nvalid=3Dt.extend({},this.errorMap),this.valid()||t(this.currentForm).trigg= erHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:= function(){this.prepareForm();for(var t=3D0,e=3Dthis.currentElements=3Dthis= .elements();e[t];t++)this.check(e[t]);return this.valid()},element:function= (e){e=3Dthis.validationTargetFor(this.clean(e)),this.lastElement=3De,this.p= repareElement(e),this.currentElements=3Dt(e);var i=3Dthis.check(e)!=3D=3D!1= ;return i?delete this.invalid[e.name]:this.invalid[e.name]=3D!0,this.number= OfInvalids()||(this.toHide=3Dthis.toHide.add(this.containers)),this.showErr= ors(),i},showErrors:function(e){if(e){t.extend(this.errorMap,e),this.errorL= ist=3D[];for(var i in e)this.errorList.push({message:e[i],element:this.find= ByName(i)[0]});this.successList=3Dt.grep(this.successList,function(t){retur= n!(t.name in e)})}this.settings.showErrors?this.settings.showErrors.call(th= is,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:functi= on(){t.fn.resetForm&&t(this.currentForm).resetForm(),this.submitted=3D{},th= is.lastElement=3Dnull,this.prepareForm(),this.hideErrors(),this.elements().= removeClass(this.settings.errorClass).removeData("previousValue")},numberOf= Invalids:function(){return this.objectLength(this.invalid)},objectLength:fu= nction(t){var e=3D0;for(var i in t)e++;return e},hideErrors:function(){this= .addWrapper(this.toHide).hide()},valid:function(){return 0=3D=3D=3Dthis.siz= e()},size:function(){return this.errorList.length},focusInvalid:function(){= if(this.settings.focusInvalid)try{t(this.findLastActive()||this.errorList.l= ength&&this.errorList[0].element||[]).filter(":visible").focus().trigger("f= ocusin")}catch(e){}},findLastActive:function(){var e=3Dthis.lastActive;retu= rn e&&1=3D=3D=3Dt.grep(this.errorList,function(t){return t.element.name=3D= =3D=3De.name}).length&&e},elements:function(){var e=3Dthis,i=3D{};return t(= this.currentForm).find("input, select, textarea").not(":submit, :reset, :im= age, [disabled]").not(this.settings.ignore).filter(function(){return!this.n= ame&&e.settings.debug&&window.console&&console.error("%o has no name assign= ed",this),this.name in i||!e.objectLength(t(this).rules())?!1:(i[this.name]= =3D!0,!0)})},clean:function(e){return t(e)[0]},errors:function(){var e=3Dth= is.settings.errorClass.replace(" ",".");return t(this.settings.errorElement= +"."+e,this.errorContext)},reset:function(){this.successList=3D[],this.erro= rList=3D[],this.errorMap=3D{},this.toShow=3Dt([]),this.toHide=3Dt([]),this.= currentElements=3Dt([])},prepareForm:function(){this.reset(),this.toHide=3D= this.errors().add(this.containers)},prepareElement:function(t){this.reset()= ,this.toHide=3Dthis.errorsFor(t)},elementValue:function(e){var i=3Dt(e).att= r("type"),s=3Dt(e).val();return"radio"=3D=3D=3Di||"checkbox"=3D=3D=3Di?t("i= nput[name=3D'"+t(e).attr("name")+"']:checked").val():"string"=3D=3Dtypeof s= ?s.replace(/\r/g,""):s},check:function(e){e=3Dthis.validationTargetFor(this= .clean(e));var i,s=3Dt(e).rules(),r=3D!1,n=3Dthis.elementValue(e);for(var a= in s){var u=3D{method:a,parameters:s[a]};try{if(i=3Dt.validator.methods[a]= .call(this,n,e,u.parameters),"dependency-mismatch"=3D=3D=3Di){r=3D!0;contin= ue}if(r=3D!1,"pending"=3D=3D=3Di)return this.toHide=3Dthis.toHide.not(this.= errorsFor(e)),void 0;if(!i)return this.formatAndAdd(e,u),!1}catch(o){throw = this.settings.debug&&window.console&&console.log("Exception occurred when c= hecking element "+e.id+", check the '"+u.method+"' method.",o),o}}return r?= void 0:(this.objectLength(s)&&this.successList.push(e),!0)},customDataMessa= ge:function(e,i){return t(e).data("msg-"+i.toLowerCase())||e.attributes&&t(= e).attr("data-msg-"+i.toLowerCase())},customMessage:function(t,e){var i=3Dt= his.settings.messages[t];return i&&(i.constructor=3D=3D=3DString?i:i[e])},f= indDefined:function(){for(var t=3D0;arguments.length>t;t++)if(void 0!=3D=3D= arguments[t])return arguments[t];return void 0},defaultMessage:function(e,i= ){return this.findDefined(this.customMessage(e.name,i),this.customDataMessa= ge(e,i),!this.settings.ignoreTitle&&e.title||void 0,t.validator.messages[i]= ,"<strong>Warning: No message defined for "+e.name+"</strong>")},formatAndA= dd:function(e,i){var s=3Dthis.defaultMessage(e,i.method),r=3D/\$?\{(\d+)\}/= g;"function"=3D=3Dtypeof s?s=3Ds.call(this,i.parameters,e):r.test(s)&&(s=3D= t.validator.format(s.replace(r,"{$1}"),i.parameters)),this.errorList.push({= message:s,element:e}),this.errorMap[e.name]=3Ds,this.submitted[e.name]=3Ds}= ,addWrapper:function(t){return this.settings.wrapper&&(t=3Dt.add(t.parent(t= his.settings.wrapper))),t},defaultShowErrors:function(){var t,e;for(t=3D0;t= his.errorList[t];t++){var i=3Dthis.errorList[t];this.settings.highlight&&th= is.settings.highlight.call(this,i.element,this.settings.errorClass,this.set= tings.validClass),this.showLabel(i.element,i.message)}if(this.errorList.len= gth&&(this.toShow=3Dthis.toShow.add(this.containers)),this.settings.success= )for(t=3D0;this.successList[t];t++)this.showLabel(this.successList[t]);if(t= his.settings.unhighlight)for(t=3D0,e=3Dthis.validElements();e[t];t++)this.s= ettings.unhighlight.call(this,e[t],this.settings.errorClass,this.settings.v= alidClass);this.toHide=3Dthis.toHide.not(this.toShow),this.hideErrors(),thi= s.addWrapper(this.toShow).show()},validElements:function(){return this.curr= entElements.not(this.invalidElements())},invalidElements:function(){return = t(this.errorList).map(function(){return this.element})},showLabel:function(= e,i){var s=3Dthis.errorsFor(e);s.length?(s.removeClass(this.settings.validC= lass).addClass(this.settings.errorClass),s.html(i)):(s=3Dt("<"+this.setting= s.errorElement+">").attr("for",this.idOrName(e)).addClass(this.settings.err= orClass).html(i||""),this.settings.wrapper&&(s=3Ds.hide().show().wrap("<"+t= his.settings.wrapper+"/>").parent()),this.labelContainer.append(s).length||= (this.settings.errorPlacement?this.settings.errorPlacement(s,t(e)):s.insert= After(e))),!i&&this.settings.success&&(s.text(""),"string"=3D=3Dtypeof this= .settings.success?s.addClass(this.settings.success):this.settings.success(s= ,e)),this.toShow=3Dthis.toShow.add(s)},errorsFor:function(e){var i=3Dthis.i= dOrName(e);return this.errors().filter(function(){return t(this).attr("for"= )=3D=3D=3Di})},idOrName:function(t){return this.groups[t.name]||(this.check= able(t)?t.name:t.id||t.name)},validationTargetFor:function(t){return this.c= heckable(t)&&(t=3Dthis.findByName(t.name).not(this.settings.ignore)[0]),t},= checkable:function(t){return/radio|checkbox/i.test(t.type)},findByName:func= tion(e){return t(this.currentForm).find("[name=3D'"+e+"']")},getLength:func= tion(e,i){switch(i.nodeName.toLowerCase()){case"select":return t("option:se= lected",i).length;case"input":if(this.checkable(i))return this.findByName(i= .name).filter(":checked").length}return e.length},depend:function(t,e){retu= rn this.dependTypes[typeof t]?this.dependTypes[typeof t](t,e):!0},dependTyp= es:{"boolean":function(t){return t},string:function(e,i){return!!t(e,i.form= ).length},"function":function(t,e){return t(e)}},optional:function(e){var i= =3Dthis.elementValue(e);return!t.validator.methods.required.call(this,i,e)&= &"dependency-mismatch"},startRequest:function(t){this.pending[t.name]||(thi= s.pendingRequest++,this.pending[t.name]=3D!0)},stopRequest:function(e,i){th= is.pendingRequest--,0>this.pendingRequest&&(this.pendingRequest=3D0),delete= this.pending[e.name],i&&0=3D=3D=3Dthis.pendingRequest&&this.formSubmitted&= &this.form()?(t(this.currentForm).submit(),this.formSubmitted=3D!1):!i&&0= =3D=3D=3Dthis.pendingRequest&&this.formSubmitted&&(t(this.currentForm).trig= gerHandler("invalid-form",[this]),this.formSubmitted=3D!1)},previousValue:f= unction(e){return t.data(e,"previousValue")||t.data(e,"previousValue",{old:= null,valid:!0,message:this.defaultMessage(e,"remote")})}},classRuleSettings= :{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateI= SO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcar= d:!0}},addClassRules:function(e,i){e.constructor=3D=3D=3DString?this.classR= uleSettings[e]=3Di:t.extend(this.classRuleSettings,e)},classRules:function(= e){var i=3D{},s=3Dt(e).attr("class");return s&&t.each(s.split(" "),function= (){this in t.validator.classRuleSettings&&t.extend(i,t.validator.classRuleS= ettings[this])}),i},attributeRules:function(e){var i=3D{},s=3Dt(e),r=3Ds[0]= .getAttribute("type");for(var n in t.validator.methods){var a;"required"=3D= =3D=3Dn?(a=3Ds.get(0).getAttribute(n),""=3D=3D=3Da&&(a=3D!0),a=3D!!a):a=3Ds= .attr(n),/min|max/.test(n)&&(null=3D=3D=3Dr||/number|range|text/.test(r))&&= (a=3DNumber(a)),a?i[n]=3Da:r=3D=3D=3Dn&&"range"!=3D=3Dr&&(i[n]=3D!0)}return= i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,= i},dataRules:function(e){var i,s,r=3D{},n=3Dt(e);for(i in t.validator.metho= ds)s=3Dn.data("rule-"+i.toLowerCase()),void 0!=3D=3Ds&&(r[i]=3Ds);return r}= ,staticRules:function(e){var i=3D{},s=3Dt.data(e.form,"validator");return s= .settings.rules&&(i=3Dt.validator.normalizeRule(s.settings.rules[e.name])||= {}),i},normalizeRules:function(e,i){return t.each(e,function(s,r){if(r=3D= =3D=3D!1)return delete e[s],void 0;if(r.param||r.depends){var n=3D!0;switch= (typeof r.depends){case"string":n=3D!!t(r.depends,i.form).length;break;case= "function":n=3Dr.depends.call(i,i)}n?e[s]=3Dvoid 0!=3D=3Dr.param?r.param:!0= :delete e[s]}}),t.each(e,function(s,r){e[s]=3Dt.isFunction(r)?r(i):r}),t.ea= ch(["minlength","maxlength"],function(){e[this]&&(e[this]=3DNumber(e[this])= )}),t.each(["rangelength","range"],function(){var i;e[this]&&(t.isArray(e[t= his])?e[this]=3D[Number(e[this][0]),Number(e[this][1])]:"string"=3D=3Dtypeo= f e[this]&&(i=3De[this].split(/[\s,]+/),e[this]=3D[Number(i[0]),Number(i[1]= )]))}),t.validator.autoCreateRanges&&(e.min&&e.max&&(e.range=3D[e.min,e.max= ],delete e.min,delete e.max),e.minlength&&e.maxlength&&(e.rangelength=3D[e.= minlength,e.maxlength],delete e.minlength,delete e.maxlength)),e},normalize= Rule:function(e){if("string"=3D=3Dtypeof e){var i=3D{};t.each(e.split(/\s/)= ,function(){i[this]=3D!0}),e=3Di}return e},addMethod:function(e,i,s){t.vali= dator.methods[e]=3Di,t.validator.messages[e]=3Dvoid 0!=3D=3Ds?s:t.validator= .messages[e],3>i.length&&t.validator.addClassRules(e,t.validator.normalizeR= ule(e))},methods:{required:function(e,i,s){if(!this.depend(s,i))return"depe= ndency-mismatch";if("select"=3D=3D=3Di.nodeName.toLowerCase()){var r=3Dt(i)= .val();return r&&r.length>0}return this.checkable(i)?this.getLength(e,i)>0:= t.trim(e).length>0},email:function(t,e){return this.optional(e)||/^((([a-z]= |\d|[!#\$%&'\*\+\-\/=3D\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFE= F])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=3D\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDC= F\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x0= 1-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF= 900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\u= F900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22= )))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00= A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF90= 0-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]= )))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\= uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\u= FDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.= test(t)},url:function(t,e){return this.optional(e)||/^(https?|s?ftp):\/\/((= (([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2}= )|[!\$&'\(\)\*\+,;=3D]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-= 9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9= ]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-= \uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\= .|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\u= F900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\= uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|= ~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\u= FDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF9= 00-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=3D]|:|@)+(\/(([a-z]= |\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&= '\(\)\*\+,;=3D]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uF= DCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=3D]|:|@)|[\uE000-\uF8FF]|= \/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|= (%[\da-f]{2})|[!\$&'\(\)\*\+,;=3D]|:|@)|\/|\?)*)?$/i.test(t)},date:function= (t,e){return this.optional(e)||!/Invalid|NaN/.test(""+new Date(t))},dateISO= :function(t,e){return this.optional(e)||/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/= .test(t)},number:function(t,e){return this.optional(e)||/^-?(?:\d+|\d{1,3}(= ?:,\d{3})+)?(?:\.\d+)?$/.test(t)},digits:function(t,e){return this.optional= (e)||/^\d+$/.test(t)},creditcard:function(t,e){if(this.optional(e))return"d= ependency-mismatch";if(/[^0-9 \-]+/.test(t))return!1;var i=3D0,s=3D0,r=3D!1= ;t=3Dt.replace(/\D/g,"");for(var n=3Dt.length-1;n>=3D0;n--){var a=3Dt.charA= t(n);s=3DparseInt(a,10),r&&(s*=3D2)>9&&(s-=3D9),i+=3Ds,r=3D!r}return 0=3D= =3D=3Di%10},minlength:function(e,i,s){var r=3Dt.isArray(e)?e.length:this.ge= tLength(t.trim(e),i);return this.optional(i)||r>=3Ds},maxlength:function(e,= i,s){var r=3Dt.isArray(e)?e.length:this.getLength(t.trim(e),i);return this.= optional(i)||s>=3Dr},rangelength:function(e,i,s){var r=3Dt.isArray(e)?e.len= gth:this.getLength(t.trim(e),i);return this.optional(i)||r>=3Ds[0]&&s[1]>= =3Dr},min:function(t,e,i){return this.optional(e)||t>=3Di},max:function(t,e= ,i){return this.optional(e)||i>=3Dt},range:function(t,e,i){return this.opti= onal(e)||t>=3Di[0]&&i[1]>=3Dt},equalTo:function(e,i,s){var r=3Dt(s);return = this.settings.onfocusout&&r.unbind(".validate-equalTo").bind("blur.validate= -equalTo",function(){t(i).valid()}),e=3D=3D=3Dr.val()},remote:function(e,i,= s){if(this.optional(i))return"dependency-mismatch";var r=3Dthis.previousVal= ue(i);if(this.settings.messages[i.name]||(this.settings.messages[i.name]=3D= {}),r.originalMessage=3Dthis.settings.messages[i.name].remote,this.settings= .messages[i.name].remote=3Dr.message,s=3D"string"=3D=3Dtypeof s&&{url:s}||s= ,r.old=3D=3D=3De)return r.valid;r.old=3De;var n=3Dthis;this.startRequest(i)= ;var a=3D{};return a[i.name]=3De,t.ajax(t.extend(!0,{url:s,mode:"abort",por= t:"validate"+i.name,dataType:"json",data:a,success:function(s){n.settings.m= essages[i.name].remote=3Dr.originalMessage;var a=3Ds=3D=3D=3D!0||"true"=3D= =3D=3Ds;if(a){var u=3Dn.formSubmitted;n.prepareElement(i),n.formSubmitted= =3Du,n.successList.push(i),delete n.invalid[i.name],n.showErrors()}else{var= o=3D{},l=3Ds||n.defaultMessage(i,"remote");o[i.name]=3Dr.message=3Dt.isFun= ction(l)?l(e):l,n.invalid[i.name]=3D!0,n.showErrors(o)}r.valid=3Da,n.stopRe= quest(i,a)}},s)),"pending"}}}),t.format=3Dt.validator.format})(jQuery),func= tion(t){var e=3D{};if(t.ajaxPrefilter)t.ajaxPrefilter(function(t,i,s){var r= =3Dt.port;"abort"=3D=3D=3Dt.mode&&(e[r]&&e[r].abort(),e[r]=3Ds)});else{var = i=3Dt.ajax;t.ajax=3Dfunction(s){var r=3D("mode"in s?s:t.ajaxSettings).mode,= n=3D("port"in s?s:t.ajaxSettings).port;return"abort"=3D=3D=3Dr?(e[n]&&e[n].= abort(),e[n]=3Di.apply(this,arguments),e[n]):i.apply(this,arguments)}}}(jQu= ery),function(t){t.extend(t.fn,{validateDelegate:function(e,i,s){return thi= s.bind(i,function(i){var r=3Dt(i.target);return r.is(e)?s.apply(r,arguments= ):void 0})}})}(jQuery); \ No newline at end of file Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-09-10 19:09:36
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/9a811282c6b9/ Changeset: 9a811282c6b9 User: alllee Date: 2013-09-10 21:09:24 Summary: version bump on jquery validation plugin Affected #: 1 file diff -r add25b5702b022fbf1211ab44919b49c3df4868f -r 9a811282c6b908b58e108f2= e6a61477d851d55ac vcweb/static/js/jquery.validate.min.js --- a/vcweb/static/js/jquery.validate.min.js +++ b/vcweb/static/js/jquery.validate.min.js @@ -1,4 +1,2 @@ -/*! jQuery Validation Plugin - v1.10.0 - 9/7/2012 -* https://github.com/jzaefferer/jquery-validation -* Copyright (c) 2012 J=C3=B6rn Zaefferer; Licensed MIT, GPL */ -(function(a){a.extend(a.fn,{validate:function(b){if(!this.length){b&&b.deb= ug&&window.console&&console.warn("nothing selected, can't validate, returni= ng nothing");return}var c=3Da.data(this[0],"validator");return c?c:(this.at= tr("novalidate","novalidate"),c=3Dnew a.validator(b,this[0]),a.data(this[0]= ,"validator",c),c.settings.onsubmit&&(this.validateDelegate(":submit","clic= k",function(b){c.settings.submitHandler&&(c.submitButton=3Db.target),a(b.ta= rget).hasClass("cancel")&&(c.cancelSubmit=3D!0)}),this.submit(function(b){f= unction d(){var d;return c.settings.submitHandler?(c.submitButton&&(d=3Da("= <input type=3D'hidden'/>").attr("name",c.submitButton.name).val(c.submitBut= ton.value).appendTo(c.currentForm)),c.settings.submitHandler.call(c,c.curre= ntForm,b),c.submitButton&&d.remove(),!1):!0}return c.settings.debug&&b.prev= entDefault(),c.cancelSubmit?(c.cancelSubmit=3D!1,d()):c.form()?c.pendingReq= uest?(c.formSubmitted=3D!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:funct= ion(){if(a(this[0]).is("form"))return this.validate().form();var b=3D!0,c= =3Da(this[0].form).validate();return this.each(function(){b&=3Dc.element(th= is)}),b},removeAttrs:function(b){var c=3D{},d=3Dthis;return a.each(b.split(= /\s/),function(a,b){c[b]=3Dd.attr(b),d.removeAttr(b)}),c},rules:function(b,= c){var d=3Dthis[0];if(b){var e=3Da.data(d.form,"validator").settings,f=3De.= rules,g=3Da.validator.staticRules(d);switch(b){case"add":a.extend(g,a.valid= ator.normalizeRule(c)),f[d.name]=3Dg,c.messages&&(e.messages[d.name]=3Da.ex= tend(e.messages[d.name],c.messages));break;case"remove":if(!c)return delete= f[d.name],g;var h=3D{};return a.each(c.split(/\s/),function(a,b){h[b]=3Dg[= b],delete g[b]}),h}}var i=3Da.validator.normalizeRules(a.extend({},a.valida= tor.metadataRules(d),a.validator.classRules(d),a.validator.attributeRules(d= ),a.validator.staticRules(d)),d);if(i.required){var j=3Di.required;delete i= .required,i=3Da.extend({required:j},i)}return i}}),a.extend(a.expr[":"],{bl= ank:function(b){return!a.trim(""+b.value)},filled:function(b){return!!a.tri= m(""+b.value)},unchecked:function(a){return!a.checked}}),a.validator=3Dfunc= tion(b,c){this.settings=3Da.extend(!0,{},a.validator.defaults,b),this.curre= ntForm=3Dc,this.init()},a.validator.format=3Dfunction(b,c){return arguments= .length=3D=3D=3D1?function(){var c=3Da.makeArray(arguments);return c.unshif= t(b),a.validator.format.apply(this,c)}:(arguments.length>2&&c.constructor!= =3D=3DArray&&(c=3Da.makeArray(arguments).slice(1)),c.constructor!=3D=3DArra= y&&(c=3D[c]),a.each(c,function(a,c){b=3Db.replace(new RegExp("\\{"+a+"\\}",= "g"),c)}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{= },errorClass:"error",validClass:"valid",errorElement:"label",focusInvalid:!= 0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidde= n",ignoreTitle:!1,onfocusin:function(a,b){this.lastActive=3Da,this.settings= .focusCleanup&&!this.blockFocusCleanup&&(this.settings.unhighlight&&this.se= ttings.unhighlight.call(this,a,this.settings.errorClass,this.settings.valid= Class),this.addWrapper(this.errorsFor(a)).hide())},onfocusout:function(a,b)= {!this.checkable(a)&&(a.name in this.submitted||!this.optional(a))&&this.el= ement(a)},onkeyup:function(a,b){if(b.which=3D=3D=3D9&&this.elementValue(a)= =3D=3D=3D"")return;(a.name in this.submitted||a=3D=3D=3Dthis.lastActive)&&t= his.element(a)},onclick:function(a,b){a.name in this.submitted?this.element= (a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highli= ght:function(b,c,d){b.type=3D=3D=3D"radio"?this.findByName(b.name).addClass= (c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,= c,d){b.type=3D=3D=3D"radio"?this.findByName(b.name).removeClass(c).addClass= (d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.va= lidator.defaults,b)},messages:{required:"This field is required.",remote:"P= lease fix this field.",email:"Please enter a valid email address.",url:"Ple= ase enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please e= nter a valid date (ISO).",number:"Please enter a valid number.",digits:"Ple= ase enter only digits.",creditcard:"Please enter a valid credit card number= .",equalTo:"Please enter the same value again.",maxlength:a.validator.forma= t("Please enter no more than {0} characters."),minlength:a.validator.format= ("Please enter at least {0} characters."),rangelength:a.validator.format("P= lease enter a value between {0} and {1} characters long."),range:a.validato= r.format("Please enter a value between {0} and {1}."),max:a.validator.forma= t("Please enter a value less than or equal to {0}."),min:a.validator.format= ("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1= ,prototype:{init:function(){function d(b){var c=3Da.data(this[0].form,"vali= dator"),d=3D"on"+b.type.replace(/^validate/,"");c.settings[d]&&c.settings[d= ].call(c,this[0],b)}this.labelContainer=3Da(this.settings.errorLabelContain= er),this.errorContext=3Dthis.labelContainer.length&&this.labelContainer||a(= this.currentForm),this.containers=3Da(this.settings.errorContainer).add(thi= s.settings.errorLabelContainer),this.submitted=3D{},this.valueCache=3D{},th= is.pendingRequest=3D0,this.pending=3D{},this.invalid=3D{},this.reset();var = b=3Dthis.groups=3D{};a.each(this.settings.groups,function(c,d){a.each(d.spl= it(/\s/),function(a,d){b[d]=3Dc})});var c=3Dthis.settings.rules;a.each(c,fu= nction(b,d){c[b]=3Da.validator.normalizeRule(d)}),a(this.currentForm).valid= ateDelegate(":text, [type=3D'password'], [type=3D'file'], select, textarea,= [type=3D'number'], [type=3D'search'] ,[type=3D'tel'], [type=3D'url'], [typ= e=3D'email'], [type=3D'datetime'], [type=3D'date'], [type=3D'month'], [type= =3D'week'], [type=3D'time'], [type=3D'datetime-local'], [type=3D'range'], [= type=3D'color'] ","focusin focusout keyup",d).validateDelegate("[type=3D'ra= dio'], [type=3D'checkbox'], select, option","click",d),this.settings.invali= dHandler&&a(this.currentForm).bind("invalid-form.validate",this.settings.in= validHandler)},form:function(){return this.checkForm(),a.extend(this.submit= ted,this.errorMap),this.invalid=3Da.extend({},this.errorMap),this.valid()||= a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors()= ,this.valid()},checkForm:function(){this.prepareForm();for(var a=3D0,b=3Dth= is.currentElements=3Dthis.elements();b[a];a++)this.check(b[a]);return this.= valid()},element:function(b){b=3Dthis.validationTargetFor(this.clean(b)),th= is.lastElement=3Db,this.prepareElement(b),this.currentElements=3Da(b);var c= =3Dthis.check(b)!=3D=3D!1;return c?delete this.invalid[b.name]:this.invalid= [b.name]=3D!0,this.numberOfInvalids()||(this.toHide=3Dthis.toHide.add(this.= containers)),this.showErrors(),c},showErrors:function(b){if(b){a.extend(thi= s.errorMap,b),this.errorList=3D[];for(var c in b)this.errorList.push({messa= ge:b[c],element:this.findByName(c)[0]});this.successList=3Da.grep(this.succ= essList,function(a){return!(a.name in b)})}this.settings.showErrors?this.se= ttings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowE= rrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm= (),this.submitted=3D{},this.lastElement=3Dnull,this.prepareForm(),this.hide= Errors(),this.elements().removeClass(this.settings.errorClass).removeData("= previousValue")},numberOfInvalids:function(){return this.objectLength(this.= invalid)},objectLength:function(a){var b=3D0;for(var c in a)b++;return b},h= ideErrors:function(){this.addWrapper(this.toHide).hide()},valid:function(){= return this.size()=3D=3D=3D0},size:function(){return this.errorList.length}= ,focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastA= ctive()||this.errorList.length&&this.errorList[0].element||[]).filter(":vis= ible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var= b=3Dthis.lastActive;return b&&a.grep(this.errorList,function(a){return a.e= lement.name=3D=3D=3Db.name}).length=3D=3D=3D1&&b},elements:function(){var b= =3Dthis,c=3D{};return a(this.currentForm).find("input, select, textarea").n= ot(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(= function(){return!this.name&&b.settings.debug&&window.console&&console.erro= r("%o has no name assigned",this),this.name in c||!b.objectLength(a(this).r= ules())?!1:(c[this.name]=3D!0,!0)})},clean:function(b){return a(b)[0]},erro= rs:function(){var b=3Dthis.settings.errorClass.replace(" ",".");return a(th= is.settings.errorElement+"."+b,this.errorContext)},reset:function(){this.su= ccessList=3D[],this.errorList=3D[],this.errorMap=3D{},this.toShow=3Da([]),t= his.toHide=3Da([]),this.currentElements=3Da([])},prepareForm:function(){thi= s.reset(),this.toHide=3Dthis.errors().add(this.containers)},prepareElement:= function(a){this.reset(),this.toHide=3Dthis.errorsFor(a)},elementValue:func= tion(b){var c=3Da(b).attr("type"),d=3Da(b).val();return c=3D=3D=3D"radio"||= c=3D=3D=3D"checkbox"?a('input[name=3D"'+a(b).attr("name")+'"]:checked').val= ():typeof d=3D=3D"string"?d.replace(/\r/g,""):d},check:function(b){b=3Dthis= .validationTargetFor(this.clean(b));var c=3Da(b).rules(),d=3D!1,e=3Dthis.el= ementValue(b),f;for(var g in c){var h=3D{method:g,parameters:c[g]};try{f=3D= a.validator.methods[g].call(this,e,b,h.parameters);if(f=3D=3D=3D"dependency= -mismatch"){d=3D!0;continue}d=3D!1;if(f=3D=3D=3D"pending"){this.toHide=3Dth= is.toHide.not(this.errorsFor(b));return}if(!f)return this.formatAndAdd(b,h)= ,!1}catch(i){throw this.settings.debug&&window.console&&console.log("except= ion occured when checking element "+b.id+", check the '"+h.method+"' method= ",i),i}}if(d)return;return this.objectLength(c)&&this.successList.push(b),!= 0},customMetaMessage:function(b,c){if(!a.metadata)return;var d=3Dthis.setti= ngs.meta?a(b).metadata()[this.settings.meta]:a(b).metadata();return d&&d.me= ssages&&d.messages[c]},customDataMessage:function(b,c){return a(b).data("ms= g-"+c.toLowerCase())||b.attributes&&a(b).attr("data-msg-"+c.toLowerCase())}= ,customMessage:function(a,b){var c=3Dthis.settings.messages[a];return c&&(c= .constructor=3D=3D=3DString?c:c[b])},findDefined:function(){for(var a=3D0;a= <arguments.length;a++)if(arguments[a]!=3D=3Dundefined)return arguments[a];r= eturn undefined},defaultMessage:function(b,c){return this.findDefined(this.= customMessage(b.name,c),this.customDataMessage(b,c),this.customMetaMessage(= b,c),!this.settings.ignoreTitle&&b.title||undefined,a.validator.messages[c]= ,"<strong>Warning: No message defined for "+b.name+"</strong>")},formatAndA= dd:function(b,c){var d=3Dthis.defaultMessage(b,c.method),e=3D/\$?\{(\d+)\}/= g;typeof d=3D=3D"function"?d=3Dd.call(this,c.parameters,b):e.test(d)&&(d=3D= a.validator.format(d.replace(e,"{$1}"),c.parameters)),this.errorList.push({= message:d,element:b}),this.errorMap[b.name]=3Dd,this.submitted[b.name]=3Dd}= ,addWrapper:function(a){return this.settings.wrapper&&(a=3Da.add(a.parent(t= his.settings.wrapper))),a},defaultShowErrors:function(){var a,b;for(a=3D0;t= his.errorList[a];a++){var c=3Dthis.errorList[a];this.settings.highlight&&th= is.settings.highlight.call(this,c.element,this.settings.errorClass,this.set= tings.validClass),this.showLabel(c.element,c.message)}this.errorList.length= &&(this.toShow=3Dthis.toShow.add(this.containers));if(this.settings.success= )for(a=3D0;this.successList[a];a++)this.showLabel(this.successList[a]);if(t= his.settings.unhighlight)for(a=3D0,b=3Dthis.validElements();b[a];a++)this.s= ettings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.v= alidClass);this.toHide=3Dthis.toHide.not(this.toShow),this.hideErrors(),thi= s.addWrapper(this.toShow).show()},validElements:function(){return this.curr= entElements.not(this.invalidElements())},invalidElements:function(){return = a(this.errorList).map(function(){return this.element})},showLabel:function(= b,c){var d=3Dthis.errorsFor(b);d.length?(d.removeClass(this.settings.validC= lass).addClass(this.settings.errorClass),d.attr("generated")&&d.html(c)):(d= =3Da("<"+this.settings.errorElement+"/>").attr({"for":this.idOrName(b),gene= rated:!0}).addClass(this.settings.errorClass).html(c||""),this.settings.wra= pper&&(d=3Dd.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),t= his.labelContainer.append(d).length||(this.settings.errorPlacement?this.set= tings.errorPlacement(d,a(b)):d.insertAfter(b))),!c&&this.settings.success&&= (d.text(""),typeof this.settings.success=3D=3D"string"?d.addClass(this.sett= ings.success):this.settings.success(d,b)),this.toShow=3Dthis.toShow.add(d)}= ,errorsFor:function(b){var c=3Dthis.idOrName(b);return this.errors().filter= (function(){return a(this).attr("for")=3D=3D=3Dc})},idOrName:function(a){re= turn this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validati= onTargetFor:function(a){return this.checkable(a)&&(a=3Dthis.findByName(a.na= me).not(this.settings.ignore)[0]),a},checkable:function(a){return/radio|che= ckbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).fin= d('[name=3D"'+b+'"]')},getLength:function(b,c){switch(c.nodeName.toLowerCas= e()){case"select":return a("option:selected",c).length;case"input":if(this.= checkable(c))return this.findByName(c.name).filter(":checked").length}retur= n b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dep= endTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a,b){return a},= string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){r= eturn a(b)}},optional:function(b){var c=3Dthis.elementValue(b);return!a.val= idator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest= :function(a){this.pending[a.name]||(this.pendingRequest++,this.pending[a.na= me]=3D!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequ= est<0&&(this.pendingRequest=3D0),delete this.pending[b.name],c&&this.pendin= gRequest=3D=3D=3D0&&this.formSubmitted&&this.form()?(a(this.currentForm).su= bmit(),this.formSubmitted=3D!1):!c&&this.pendingRequest=3D=3D=3D0&&this.for= mSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this= .formSubmitted=3D!1)},previousValue:function(b){return a.data(b,"previousVa= lue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMess= age(b,"remote")})}},classRuleSettings:{required:{required:!0},email:{email:= !0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},dig= its:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.c= onstructor=3D=3D=3DString?this.classRuleSettings[b]=3Dc:a.extend(this.class= RuleSettings,b)},classRules:function(b){var c=3D{},d=3Da(b).attr("class");r= eturn d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettin= gs&&a.extend(c,a.validator.classRuleSettings[this])}),c},attributeRules:fun= ction(b){var c=3D{},d=3Da(b);for(var e in a.validator.methods){var f;e=3D= =3D=3D"required"?(f=3Dd.get(0).getAttribute(e),f=3D=3D=3D""&&(f=3D!0),f=3D!= !f):f=3Dd.attr(e),f?c[e]=3Df:d[0].getAttribute("type")=3D=3D=3De&&(c[e]=3D!= 0)}return c.maxlength&&/-1|2147483647|524288/.test(c.maxlength)&&delete c.m= axlength,c},metadataRules:function(b){if(!a.metadata)return{};var c=3Da.dat= a(b.form,"validator").settings.meta;return c?a(b).metadata()[c]:a(b).metada= ta()},staticRules:function(b){var c=3D{},d=3Da.data(b.form,"validator");ret= urn d.settings.rules&&(c=3Da.validator.normalizeRule(d.settings.rules[b.nam= e])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e= =3D=3D=3D!1){delete b[d];return}if(e.param||e.depends){var f=3D!0;switch(ty= peof e.depends){case"string":f=3D!!a(e.depends,c.form).length;break;case"fu= nction":f=3De.depends.call(c,c)}f?b[d]=3De.param!=3D=3Dundefined?e.param:!0= :delete b[d]}}),a.each(b,function(d,e){b[d]=3Da.isFunction(e)?e(c):e}),a.ea= ch(["minlength","maxlength","min","max"],function(){b[this]&&(b[this]=3DNum= ber(b[this]))}),a.each(["rangelength","range"],function(){b[this]&&(b[this]= =3D[Number(b[this][0]),Number(b[this][1])])}),a.validator.autoCreateRanges&= &(b.min&&b.max&&(b.range=3D[b.min,b.max],delete b.min,delete b.max),b.minle= ngth&&b.maxlength&&(b.rangelength=3D[b.minlength,b.maxlength],delete b.minl= ength,delete b.maxlength)),b.messages&&delete b.messages,b},normalizeRule:f= unction(b){if(typeof b=3D=3D"string"){var c=3D{};a.each(b.split(/\s/),funct= ion(){c[this]=3D!0}),b=3Dc}return b},addMethod:function(b,c,d){a.validator.= methods[b]=3Dc,a.validator.messages[b]=3Dd!=3D=3Dundefined?d:a.validator.me= ssages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule= (b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"depende= ncy-mismatch";if(c.nodeName.toLowerCase()=3D=3D=3D"select"){var e=3Da(c).va= l();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:a.t= rim(b).length>0},remote:function(b,c,d){if(this.optional(c))return"dependen= cy-mismatch";var e=3Dthis.previousValue(c);this.settings.messages[c.name]||= (this.settings.messages[c.name]=3D{}),e.originalMessage=3Dthis.settings.mes= sages[c.name].remote,this.settings.messages[c.name].remote=3De.message,d=3D= typeof d=3D=3D"string"&&{url:d}||d;if(this.pending[c.name])return"pending";= if(e.old=3D=3D=3Db)return e.valid;e.old=3Db;var f=3Dthis;this.startRequest(= c);var g=3D{};return g[c.name]=3Db,a.ajax(a.extend(!0,{url:d,mode:"abort",p= ort:"validate"+c.name,dataType:"json",data:g,success:function(d){f.settings= .messages[c.name].remote=3De.originalMessage;var g=3Dd=3D=3D=3D!0||d=3D=3D= =3D"true";if(g){var h=3Df.formSubmitted;f.prepareElement(c),f.formSubmitted= =3Dh,f.successList.push(c),delete f.invalid[c.name],f.showErrors()}else{var= i=3D{},j=3Dd||f.defaultMessage(c,"remote");i[c.name]=3De.message=3Da.isFun= ction(j)?j(b):j,f.invalid[c.name]=3D!0,f.showErrors(i)}e.valid=3Dg,f.stopRe= quest(c,g)}},d)),"pending"},minlength:function(b,c,d){var e=3Da.isArray(b)?= b.length:this.getLength(a.trim(b),c);return this.optional(c)||e>=3Dd},maxle= ngth:function(b,c,d){var e=3Da.isArray(b)?b.length:this.getLength(a.trim(b)= ,c);return this.optional(c)||e<=3Dd},rangelength:function(b,c,d){var e=3Da.= isArray(b)?b.length:this.getLength(a.trim(b),c);return this.optional(c)||e>= =3Dd[0]&&e<=3Dd[1]},min:function(a,b,c){return this.optional(b)||a>=3Dc},ma= x:function(a,b,c){return this.optional(b)||a<=3Dc},range:function(a,b,c){re= turn this.optional(b)||a>=3Dc[0]&&a<=3Dc[1]},email:function(a,b){return thi= s.optional(b)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=3D\?\^_`{\|}~]|[\u00A0-\uD7FF= \uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=3D\?\^_`{\|}~]|[= \u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x= 0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5= d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x= 0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\= x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-= \uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\= .|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\u= F900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\= uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|= ~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\u= FDCF\uFDF0-\uFFEF])))$/i.test(a)},url:function(a,b){return this.optional(b)= ||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF= 0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=3D]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0= -4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-= 4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD= 7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF= 0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a= -z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7= FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\u= FFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|= [\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.= |_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\= +,;=3D]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFE= F])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=3D]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[= \u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=3D= ]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF90= 0-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=3D]|:|@)|\/|\?)*)?$/= i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(= new Date(a))},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-]\= d{1,2}[\/\-]\d{1,2}$/.test(a)},number:function(a,b){return this.optional(b)= ||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b)= {return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this= .optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;v= ar c=3D0,d=3D0,e=3D!1;a=3Da.replace(/\D/g,"");for(var f=3Da.length-1;f>=3D0= ;f--){var g=3Da.charAt(f);d=3DparseInt(g,10),e&&(d*=3D2)>9&&(d-=3D9),c+=3Dd= ,e=3D!e}return c%10=3D=3D=3D0},equalTo:function(b,c,d){var e=3Da(d);return = this.settings.onfocusout&&e.unbind(".validate-equalTo").bind("blur.validate= -equalTo",function(){a(c).valid()}),b=3D=3D=3De.val()}}}),a.format=3Da.vali= dator.format})(jQuery),function(a){var b=3D{};if(a.ajaxPrefilter)a.ajaxPref= ilter(function(a,c,d){var e=3Da.port;a.mode=3D=3D=3D"abort"&&(b[e]&&b[e].ab= ort(),b[e]=3Dd)});else{var c=3Da.ajax;a.ajax=3Dfunction(d){var e=3D("mode"i= n d?d:a.ajaxSettings).mode,f=3D("port"in d?d:a.ajaxSettings).port;return e= =3D=3D=3D"abort"?(b[f]&&b[f].abort(),b[f]=3Dc.apply(this,arguments)):c.appl= y(this,arguments)}}}(jQuery),function(a){!jQuery.event.special.focusin&&!jQ= uery.event.special.focusout&&document.addEventListener&&a.each({focus:"focu= sin",blur:"focusout"},function(b,c){function d(b){return b=3Da.event.fix(b)= ,b.type=3Dc,a.event.handle.call(this,b)}a.event.special[c]=3D{setup:functio= n(){this.addEventListener(b,d,!0)},teardown:function(){this.removeEventList= ener(b,d,!0)},handler:function(b){var d=3Darguments;return d[0]=3Da.event.f= ix(b),d[0].type=3Dc,a.event.handle.apply(this,d)}}}),a.extend(a.fn,{validat= eDelegate:function(b,c,d){return this.bind(c,function(c){var e=3Da(c.target= );if(e.is(b))return d.apply(e,arguments)})}})}(jQuery) \ No newline at end of file +/*! jQuery Validation Plugin - v1.11.1 - 3/22/2013\n* https://github.com/j= zaefferer/jquery-validation +* Copyright (c) 2013 J=C3=B6rn Zaefferer; Licensed MIT */(function(t){t.ex= tend(t.fn,{validate:function(e){if(!this.length)return e&&e.debug&&window.c= onsole&&console.warn("Nothing selected, can't validate, returning nothing."= ),void 0;var i=3Dt.data(this[0],"validator");return i?i:(this.attr("novalid= ate","novalidate"),i=3Dnew t.validator(e,this[0]),t.data(this[0],"validator= ",i),i.settings.onsubmit&&(this.validateDelegate(":submit","click",function= (e){i.settings.submitHandler&&(i.submitButton=3De.target),t(e.target).hasCl= ass("cancel")&&(i.cancelSubmit=3D!0),void 0!=3D=3Dt(e.target).attr("formnov= alidate")&&(i.cancelSubmit=3D!0)}),this.submit(function(e){function s(){var= s;return i.settings.submitHandler?(i.submitButton&&(s=3Dt("<input type=3D'= hidden'/>").attr("name",i.submitButton.name).val(t(i.submitButton).val()).a= ppendTo(i.currentForm)),i.settings.submitHandler.call(i,i.currentForm,e),i.= submitButton&&s.remove(),!1):!0}return i.settings.debug&&e.preventDefault()= ,i.cancelSubmit?(i.cancelSubmit=3D!1,s()):i.form()?i.pendingRequest?(i.form= Submitted=3D!0,!1):s():(i.focusInvalid(),!1)})),i)},valid:function(){if(t(t= his[0]).is("form"))return this.validate().form();var e=3D!0,i=3Dt(this[0].f= orm).validate();return this.each(function(){e=3De&&i.element(this)}),e},rem= oveAttrs:function(e){var i=3D{},s=3Dthis;return t.each(e.split(/\s/),functi= on(t,e){i[e]=3Ds.attr(e),s.removeAttr(e)}),i},rules:function(e,i){var s=3Dt= his[0];if(e){var r=3Dt.data(s.form,"validator").settings,n=3Dr.rules,a=3Dt.= validator.staticRules(s);switch(e){case"add":t.extend(a,t.validator.normali= zeRule(i)),delete a.messages,n[s.name]=3Da,i.messages&&(r.messages[s.name]= =3Dt.extend(r.messages[s.name],i.messages));break;case"remove":if(!i)return= delete n[s.name],a;var u=3D{};return t.each(i.split(/\s/),function(t,e){u[= e]=3Da[e],delete a[e]}),u}}var o=3Dt.validator.normalizeRules(t.extend({},t= .validator.classRules(s),t.validator.attributeRules(s),t.validator.dataRule= s(s),t.validator.staticRules(s)),s);if(o.required){var l=3Do.required;delet= e o.required,o=3Dt.extend({required:l},o)}return o}}),t.extend(t.expr[":"],= {blank:function(e){return!t.trim(""+t(e).val())},filled:function(e){return!= !t.trim(""+t(e).val())},unchecked:function(e){return!t(e).prop("checked")}}= ),t.validator=3Dfunction(e,i){this.settings=3Dt.extend(!0,{},t.validator.de= faults,e),this.currentForm=3Di,this.init()},t.validator.format=3Dfunction(e= ,i){return 1=3D=3D=3Darguments.length?function(){var i=3Dt.makeArray(argume= nts);return i.unshift(e),t.validator.format.apply(this,i)}:(arguments.lengt= h>2&&i.constructor!=3D=3DArray&&(i=3Dt.makeArray(arguments).slice(1)),i.con= structor!=3D=3DArray&&(i=3D[i]),t.each(i,function(t,i){e=3De.replace(RegExp= ("\\{"+t+"\\}","g"),function(){return i})}),e)},t.extend(t.validator,{defau= lts:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",e= rrorElement:"label",focusInvalid:!0,errorContainer:t([]),errorLabelContaine= r:t([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(t){t= his.lastActive=3Dt,this.settings.focusCleanup&&!this.blockFocusCleanup&&(th= is.settings.unhighlight&&this.settings.unhighlight.call(this,t,this.setting= s.errorClass,this.settings.validClass),this.addWrapper(this.errorsFor(t)).h= ide())},onfocusout:function(t){this.checkable(t)||!(t.name in this.submitte= d)&&this.optional(t)||this.element(t)},onkeyup:function(t,e){(9!=3D=3De.whi= ch||""!=3D=3Dthis.elementValue(t))&&(t.name in this.submitted||t=3D=3D=3Dth= is.lastElement)&&this.element(t)},onclick:function(t){t.name in this.submit= ted?this.element(t):t.parentNode.name in this.submitted&&this.element(t.par= entNode)},highlight:function(e,i,s){"radio"=3D=3D=3De.type?this.findByName(= e.name).addClass(i).removeClass(s):t(e).addClass(i).removeClass(s)},unhighl= ight:function(e,i,s){"radio"=3D=3D=3De.type?this.findByName(e.name).removeC= lass(i).addClass(s):t(e).removeClass(i).addClass(s)}},setDefaults:function(= e){t.extend(t.validator.defaults,e)},messages:{required:"This field is requ= ired.",remote:"Please fix this field.",email:"Please enter a valid email ad= dress.",url:"Please enter a valid URL.",date:"Please enter a valid date.",d= ateISO:"Please enter a valid date (ISO).",number:"Please enter a valid numb= er.",digits:"Please enter only digits.",creditcard:"Please enter a valid cr= edit card number.",equalTo:"Please enter the same value again.",maxlength:t= .validator.format("Please enter no more than {0} characters."),minlength:t.= validator.format("Please enter at least {0} characters."),rangelength:t.val= idator.format("Please enter a value between {0} and {1} characters long."),= range:t.validator.format("Please enter a value between {0} and {1}."),max:t= .validator.format("Please enter a value less than or equal to {0}."),min:t.= validator.format("Please enter a value greater than or equal to {0}.")},aut= oCreateRanges:!1,prototype:{init:function(){function e(e){var i=3Dt.data(th= is[0].form,"validator"),s=3D"on"+e.type.replace(/^validate/,"");i.settings[= s]&&i.settings[s].call(i,this[0],e)}this.labelContainer=3Dt(this.settings.e= rrorLabelContainer),this.errorContext=3Dthis.labelContainer.length&&this.la= belContainer||t(this.currentForm),this.containers=3Dt(this.settings.errorCo= ntainer).add(this.settings.errorLabelContainer),this.submitted=3D{},this.va= lueCache=3D{},this.pendingRequest=3D0,this.pending=3D{},this.invalid=3D{},t= his.reset();var i=3Dthis.groups=3D{};t.each(this.settings.groups,function(e= ,s){"string"=3D=3Dtypeof s&&(s=3Ds.split(/\s/)),t.each(s,function(t,s){i[s]= =3De})});var s=3Dthis.settings.rules;t.each(s,function(e,i){s[e]=3Dt.valida= tor.normalizeRule(i)}),t(this.currentForm).validateDelegate(":text, [type= =3D'password'], [type=3D'file'], select, textarea, [type=3D'number'], [type= =3D'search'] ,[type=3D'tel'], [type=3D'url'], [type=3D'email'], [type=3D'da= tetime'], [type=3D'date'], [type=3D'month'], [type=3D'week'], [type=3D'time= '], [type=3D'datetime-local'], [type=3D'range'], [type=3D'color'] ","focusi= n focusout keyup",e).validateDelegate("[type=3D'radio'], [type=3D'checkbox'= ], select, option","click",e),this.settings.invalidHandler&&t(this.currentF= orm).bind("invalid-form.validate",this.settings.invalidHandler)},form:funct= ion(){return this.checkForm(),t.extend(this.submitted,this.errorMap),this.i= nvalid=3Dt.extend({},this.errorMap),this.valid()||t(this.currentForm).trigg= erHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:= function(){this.prepareForm();for(var t=3D0,e=3Dthis.currentElements=3Dthis= .elements();e[t];t++)this.check(e[t]);return this.valid()},element:function= (e){e=3Dthis.validationTargetFor(this.clean(e)),this.lastElement=3De,this.p= repareElement(e),this.currentElements=3Dt(e);var i=3Dthis.check(e)!=3D=3D!1= ;return i?delete this.invalid[e.name]:this.invalid[e.name]=3D!0,this.number= OfInvalids()||(this.toHide=3Dthis.toHide.add(this.containers)),this.showErr= ors(),i},showErrors:function(e){if(e){t.extend(this.errorMap,e),this.errorL= ist=3D[];for(var i in e)this.errorList.push({message:e[i],element:this.find= ByName(i)[0]});this.successList=3Dt.grep(this.successList,function(t){retur= n!(t.name in e)})}this.settings.showErrors?this.settings.showErrors.call(th= is,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:functi= on(){t.fn.resetForm&&t(this.currentForm).resetForm(),this.submitted=3D{},th= is.lastElement=3Dnull,this.prepareForm(),this.hideErrors(),this.elements().= removeClass(this.settings.errorClass).removeData("previousValue")},numberOf= Invalids:function(){return this.objectLength(this.invalid)},objectLength:fu= nction(t){var e=3D0;for(var i in t)e++;return e},hideErrors:function(){this= .addWrapper(this.toHide).hide()},valid:function(){return 0=3D=3D=3Dthis.siz= e()},size:function(){return this.errorList.length},focusInvalid:function(){= if(this.settings.focusInvalid)try{t(this.findLastActive()||this.errorList.l= ength&&this.errorList[0].element||[]).filter(":visible").focus().trigger("f= ocusin")}catch(e){}},findLastActive:function(){var e=3Dthis.lastActive;retu= rn e&&1=3D=3D=3Dt.grep(this.errorList,function(t){return t.element.name=3D= =3D=3De.name}).length&&e},elements:function(){var e=3Dthis,i=3D{};return t(= this.currentForm).find("input, select, textarea").not(":submit, :reset, :im= age, [disabled]").not(this.settings.ignore).filter(function(){return!this.n= ame&&e.settings.debug&&window.console&&console.error("%o has no name assign= ed",this),this.name in i||!e.objectLength(t(this).rules())?!1:(i[this.name]= =3D!0,!0)})},clean:function(e){return t(e)[0]},errors:function(){var e=3Dth= is.settings.errorClass.replace(" ",".");return t(this.settings.errorElement= +"."+e,this.errorContext)},reset:function(){this.successList=3D[],this.erro= rList=3D[],this.errorMap=3D{},this.toShow=3Dt([]),this.toHide=3Dt([]),this.= currentElements=3Dt([])},prepareForm:function(){this.reset(),this.toHide=3D= this.errors().add(this.containers)},prepareElement:function(t){this.reset()= ,this.toHide=3Dthis.errorsFor(t)},elementValue:function(e){var i=3Dt(e).att= r("type"),s=3Dt(e).val();return"radio"=3D=3D=3Di||"checkbox"=3D=3D=3Di?t("i= nput[name=3D'"+t(e).attr("name")+"']:checked").val():"string"=3D=3Dtypeof s= ?s.replace(/\r/g,""):s},check:function(e){e=3Dthis.validationTargetFor(this= .clean(e));var i,s=3Dt(e).rules(),r=3D!1,n=3Dthis.elementValue(e);for(var a= in s){var u=3D{method:a,parameters:s[a]};try{if(i=3Dt.validator.methods[a]= .call(this,n,e,u.parameters),"dependency-mismatch"=3D=3D=3Di){r=3D!0;contin= ue}if(r=3D!1,"pending"=3D=3D=3Di)return this.toHide=3Dthis.toHide.not(this.= errorsFor(e)),void 0;if(!i)return this.formatAndAdd(e,u),!1}catch(o){throw = this.settings.debug&&window.console&&console.log("Exception occurred when c= hecking element "+e.id+", check the '"+u.method+"' method.",o),o}}return r?= void 0:(this.objectLength(s)&&this.successList.push(e),!0)},customDataMessa= ge:function(e,i){return t(e).data("msg-"+i.toLowerCase())||e.attributes&&t(= e).attr("data-msg-"+i.toLowerCase())},customMessage:function(t,e){var i=3Dt= his.settings.messages[t];return i&&(i.constructor=3D=3D=3DString?i:i[e])},f= indDefined:function(){for(var t=3D0;arguments.length>t;t++)if(void 0!=3D=3D= arguments[t])return arguments[t];return void 0},defaultMessage:function(e,i= ){return this.findDefined(this.customMessage(e.name,i),this.customDataMessa= ge(e,i),!this.settings.ignoreTitle&&e.title||void 0,t.validator.messages[i]= ,"<strong>Warning: No message defined for "+e.name+"</strong>")},formatAndA= dd:function(e,i){var s=3Dthis.defaultMessage(e,i.method),r=3D/\$?\{(\d+)\}/= g;"function"=3D=3Dtypeof s?s=3Ds.call(this,i.parameters,e):r.test(s)&&(s=3D= t.validator.format(s.replace(r,"{$1}"),i.parameters)),this.errorList.push({= message:s,element:e}),this.errorMap[e.name]=3Ds,this.submitted[e.name]=3Ds}= ,addWrapper:function(t){return this.settings.wrapper&&(t=3Dt.add(t.parent(t= his.settings.wrapper))),t},defaultShowErrors:function(){var t,e;for(t=3D0;t= his.errorList[t];t++){var i=3Dthis.errorList[t];this.settings.highlight&&th= is.settings.highlight.call(this,i.element,this.settings.errorClass,this.set= tings.validClass),this.showLabel(i.element,i.message)}if(this.errorList.len= gth&&(this.toShow=3Dthis.toShow.add(this.containers)),this.settings.success= )for(t=3D0;this.successList[t];t++)this.showLabel(this.successList[t]);if(t= his.settings.unhighlight)for(t=3D0,e=3Dthis.validElements();e[t];t++)this.s= ettings.unhighlight.call(this,e[t],this.settings.errorClass,this.settings.v= alidClass);this.toHide=3Dthis.toHide.not(this.toShow),this.hideErrors(),thi= s.addWrapper(this.toShow).show()},validElements:function(){return this.curr= entElements.not(this.invalidElements())},invalidElements:function(){return = t(this.errorList).map(function(){return this.element})},showLabel:function(= e,i){var s=3Dthis.errorsFor(e);s.length?(s.removeClass(this.settings.validC= lass).addClass(this.settings.errorClass),s.html(i)):(s=3Dt("<"+this.setting= s.errorElement+">").attr("for",this.idOrName(e)).addClass(this.settings.err= orClass).html(i||""),this.settings.wrapper&&(s=3Ds.hide().show().wrap("<"+t= his.settings.wrapper+"/>").parent()),this.labelContainer.append(s).length||= (this.settings.errorPlacement?this.settings.errorPlacement(s,t(e)):s.insert= After(e))),!i&&this.settings.success&&(s.text(""),"string"=3D=3Dtypeof this= .settings.success?s.addClass(this.settings.success):this.settings.success(s= ,e)),this.toShow=3Dthis.toShow.add(s)},errorsFor:function(e){var i=3Dthis.i= dOrName(e);return this.errors().filter(function(){return t(this).attr("for"= )=3D=3D=3Di})},idOrName:function(t){return this.groups[t.name]||(this.check= able(t)?t.name:t.id||t.name)},validationTargetFor:function(t){return this.c= heckable(t)&&(t=3Dthis.findByName(t.name).not(this.settings.ignore)[0]),t},= checkable:function(t){return/radio|checkbox/i.test(t.type)},findByName:func= tion(e){return t(this.currentForm).find("[name=3D'"+e+"']")},getLength:func= tion(e,i){switch(i.nodeName.toLowerCase()){case"select":return t("option:se= lected",i).length;case"input":if(this.checkable(i))return this.findByName(i= .name).filter(":checked").length}return e.length},depend:function(t,e){retu= rn this.dependTypes[typeof t]?this.dependTypes[typeof t](t,e):!0},dependTyp= es:{"boolean":function(t){return t},string:function(e,i){return!!t(e,i.form= ).length},"function":function(t,e){return t(e)}},optional:function(e){var i= =3Dthis.elementValue(e);return!t.validator.methods.required.call(this,i,e)&= &"dependency-mismatch"},startRequest:function(t){this.pending[t.name]||(thi= s.pendingRequest++,this.pending[t.name]=3D!0)},stopRequest:function(e,i){th= is.pendingRequest--,0>this.pendingRequest&&(this.pendingRequest=3D0),delete= this.pending[e.name],i&&0=3D=3D=3Dthis.pendingRequest&&this.formSubmitted&= &this.form()?(t(this.currentForm).submit(),this.formSubmitted=3D!1):!i&&0= =3D=3D=3Dthis.pendingRequest&&this.formSubmitted&&(t(this.currentForm).trig= gerHandler("invalid-form",[this]),this.formSubmitted=3D!1)},previousValue:f= unction(e){return t.data(e,"previousValue")||t.data(e,"previousValue",{old:= null,valid:!0,message:this.defaultMessage(e,"remote")})}},classRuleSettings= :{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateI= SO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcar= d:!0}},addClassRules:function(e,i){e.constructor=3D=3D=3DString?this.classR= uleSettings[e]=3Di:t.extend(this.classRuleSettings,e)},classRules:function(= e){var i=3D{},s=3Dt(e).attr("class");return s&&t.each(s.split(" "),function= (){this in t.validator.classRuleSettings&&t.extend(i,t.validator.classRuleS= ettings[this])}),i},attributeRules:function(e){var i=3D{},s=3Dt(e),r=3Ds[0]= .getAttribute("type");for(var n in t.validator.methods){var a;"required"=3D= =3D=3Dn?(a=3Ds.get(0).getAttribute(n),""=3D=3D=3Da&&(a=3D!0),a=3D!!a):a=3Ds= .attr(n),/min|max/.test(n)&&(null=3D=3D=3Dr||/number|range|text/.test(r))&&= (a=3DNumber(a)),a?i[n]=3Da:r=3D=3D=3Dn&&"range"!=3D=3Dr&&(i[n]=3D!0)}return= i.maxlength&&/-1|2147483647|524288/.test(i.maxlength)&&delete i.maxlength,= i},dataRules:function(e){var i,s,r=3D{},n=3Dt(e);for(i in t.validator.metho= ds)s=3Dn.data("rule-"+i.toLowerCase()),void 0!=3D=3Ds&&(r[i]=3Ds);return r}= ,staticRules:function(e){var i=3D{},s=3Dt.data(e.form,"validator");return s= .settings.rules&&(i=3Dt.validator.normalizeRule(s.settings.rules[e.name])||= {}),i},normalizeRules:function(e,i){return t.each(e,function(s,r){if(r=3D= =3D=3D!1)return delete e[s],void 0;if(r.param||r.depends){var n=3D!0;switch= (typeof r.depends){case"string":n=3D!!t(r.depends,i.form).length;break;case= "function":n=3Dr.depends.call(i,i)}n?e[s]=3Dvoid 0!=3D=3Dr.param?r.param:!0= :delete e[s]}}),t.each(e,function(s,r){e[s]=3Dt.isFunction(r)?r(i):r}),t.ea= ch(["minlength","maxlength"],function(){e[this]&&(e[this]=3DNumber(e[this])= )}),t.each(["rangelength","range"],function(){var i;e[this]&&(t.isArray(e[t= his])?e[this]=3D[Number(e[this][0]),Number(e[this][1])]:"string"=3D=3Dtypeo= f e[this]&&(i=3De[this].split(/[\s,]+/),e[this]=3D[Number(i[0]),Number(i[1]= )]))}),t.validator.autoCreateRanges&&(e.min&&e.max&&(e.range=3D[e.min,e.max= ],delete e.min,delete e.max),e.minlength&&e.maxlength&&(e.rangelength=3D[e.= minlength,e.maxlength],delete e.minlength,delete e.maxlength)),e},normalize= Rule:function(e){if("string"=3D=3Dtypeof e){var i=3D{};t.each(e.split(/\s/)= ,function(){i[this]=3D!0}),e=3Di}return e},addMethod:function(e,i,s){t.vali= dator.methods[e]=3Di,t.validator.messages[e]=3Dvoid 0!=3D=3Ds?s:t.validator= .messages[e],3>i.length&&t.validator.addClassRules(e,t.validator.normalizeR= ule(e))},methods:{required:function(e,i,s){if(!this.depend(s,i))return"depe= ndency-mismatch";if("select"=3D=3D=3Di.nodeName.toLowerCase()){var r=3Dt(i)= .val();return r&&r.length>0}return this.checkable(i)?this.getLength(e,i)>0:= t.trim(e).length>0},email:function(t,e){return this.optional(e)||/^((([a-z]= |\d|[!#\$%&'\*\+\-\/=3D\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFE= F])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=3D\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDC= F\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x0= 1-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF= 900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\u= F900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22= )))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00= A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF90= 0-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]= )))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\= uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\u= FDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.= test(t)},url:function(t,e){return this.optional(e)||/^(https?|s?ftp):\/\/((= (([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2}= )|[!\$&'\(\)\*\+,;=3D]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-= 9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9= ]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-= \uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\= .|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\u= F900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\= uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|= ~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\u= FDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF9= 00-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=3D]|:|@)+(\/(([a-z]= |\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&= '\(\)\*\+,;=3D]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uF= DCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=3D]|:|@)|[\uE000-\uF8FF]|= \/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|= (%[\da-f]{2})|[!\$&'\(\)\*\+,;=3D]|:|@)|\/|\?)*)?$/i.test(t)},date:function= (t,e){return this.optional(e)||!/Invalid|NaN/.test(""+new Date(t))},dateISO= :function(t,e){return this.optional(e)||/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/= .test(t)},number:function(t,e){return this.optional(e)||/^-?(?:\d+|\d{1,3}(= ?:,\d{3})+)?(?:\.\d+)?$/.test(t)},digits:function(t,e){return this.optional= (e)||/^\d+$/.test(t)},creditcard:function(t,e){if(this.optional(e))return"d= ependency-mismatch";if(/[^0-9 \-]+/.test(t))return!1;var i=3D0,s=3D0,r=3D!1= ;t=3Dt.replace(/\D/g,"");for(var n=3Dt.length-1;n>=3D0;n--){var a=3Dt.charA= t(n);s=3DparseInt(a,10),r&&(s*=3D2)>9&&(s-=3D9),i+=3Ds,r=3D!r}return 0=3D= =3D=3Di%10},minlength:function(e,i,s){var r=3Dt.isArray(e)?e.length:this.ge= tLength(t.trim(e),i);return this.optional(i)||r>=3Ds},maxlength:function(e,= i,s){var r=3Dt.isArray(e)?e.length:this.getLength(t.trim(e),i);return this.= optional(i)||s>=3Dr},rangelength:function(e,i,s){var r=3Dt.isArray(e)?e.len= gth:this.getLength(t.trim(e),i);return this.optional(i)||r>=3Ds[0]&&s[1]>= =3Dr},min:function(t,e,i){return this.optional(e)||t>=3Di},max:function(t,e= ,i){return this.optional(e)||i>=3Dt},range:function(t,e,i){return this.opti= onal(e)||t>=3Di[0]&&i[1]>=3Dt},equalTo:function(e,i,s){var r=3Dt(s);return = this.settings.onfocusout&&r.unbind(".validate-equalTo").bind("blur.validate= -equalTo",function(){t(i).valid()}),e=3D=3D=3Dr.val()},remote:function(e,i,= s){if(this.optional(i))return"dependency-mismatch";var r=3Dthis.previousVal= ue(i);if(this.settings.messages[i.name]||(this.settings.messages[i.name]=3D= {}),r.originalMessage=3Dthis.settings.messages[i.name].remote,this.settings= .messages[i.name].remote=3Dr.message,s=3D"string"=3D=3Dtypeof s&&{url:s}||s= ,r.old=3D=3D=3De)return r.valid;r.old=3De;var n=3Dthis;this.startRequest(i)= ;var a=3D{};return a[i.name]=3De,t.ajax(t.extend(!0,{url:s,mode:"abort",por= t:"validate"+i.name,dataType:"json",data:a,success:function(s){n.settings.m= essages[i.name].remote=3Dr.originalMessage;var a=3Ds=3D=3D=3D!0||"true"=3D= =3D=3Ds;if(a){var u=3Dn.formSubmitted;n.prepareElement(i),n.formSubmitted= =3Du,n.successList.push(i),delete n.invalid[i.name],n.showErrors()}else{var= o=3D{},l=3Ds||n.defaultMessage(i,"remote");o[i.name]=3Dr.message=3Dt.isFun= ction(l)?l(e):l,n.invalid[i.name]=3D!0,n.showErrors(o)}r.valid=3Da,n.stopRe= quest(i,a)}},s)),"pending"}}}),t.format=3Dt.validator.format})(jQuery),func= tion(t){var e=3D{};if(t.ajaxPrefilter)t.ajaxPrefilter(function(t,i,s){var r= =3Dt.port;"abort"=3D=3D=3Dt.mode&&(e[r]&&e[r].abort(),e[r]=3Ds)});else{var = i=3Dt.ajax;t.ajax=3Dfunction(s){var r=3D("mode"in s?s:t.ajaxSettings).mode,= n=3D("port"in s?s:t.ajaxSettings).port;return"abort"=3D=3D=3Dr?(e[n]&&e[n].= abort(),e[n]=3Di.apply(this,arguments),e[n]):i.apply(this,arguments)}}}(jQu= ery),function(t){t.extend(t.fn,{validateDelegate:function(e,i,s){return thi= s.bind(i,function(i){var r=3Dt(i.target);return r.is(e)?s.apply(r,arguments= ):void 0})}})}(jQuery); \ No newline at end of file Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-09-10 18:51:49
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/add25b5702b0/ Changeset: add25b5702b0 User: alllee Date: 2013-09-10 20:51:34 Summary: inlining form mixin Affected #: 1 file diff -r e8df2aed57783a7a0d72198d896cda51f8322b07 -r add25b5702b022fbf1211ab44919b49c3df4868f vcweb/core/forms.py --- a/vcweb/core/forms.py +++ b/vcweb/core/forms.py @@ -18,16 +18,13 @@ REQUIRED_EMAIL_ATTRIBUTES = { 'class' : 'required email' } REQUIRED_ATTRIBUTES = { 'class' : 'required' } -class BaseRegistrationMixin(object): +class BaseRegistrationForm(forms.Form): first_name = forms.CharField(widget=widgets.TextInput(attrs=REQUIRED_ATTRIBUTES)) last_name = forms.CharField(widget=widgets.TextInput(attrs=REQUIRED_ATTRIBUTES)) email = forms.EmailField(widget=widgets.TextInput(attrs=REQUIRED_EMAIL_ATTRIBUTES), help_text=_('Please enter a valid email. We will never share your email in any way, shape, or form.')) password = forms.CharField(widget=widgets.PasswordInput(attrs=REQUIRED_ATTRIBUTES)) confirm_password = forms.CharField(widget=widgets.PasswordInput(attrs=REQUIRED_ATTRIBUTES)) institution = forms.CharField(widget=widgets.TextInput(attrs=REQUIRED_ATTRIBUTES), help_text=_('The primary institution, if any, you are affiliated with.')) - - -class BaseRegistrationForm(BaseRegistrationMixin, forms.Form): def clean_email(self): email = self.cleaned_data['email'].lower() try: @@ -67,13 +64,11 @@ class ParticipantAccountForm(forms.ModelForm): - pk = forms.IntegerField(widget=widgets.HiddenInput()) first_name = forms.CharField(widget=widgets.TextInput(attrs=REQUIRED_ATTRIBUTES)) last_name = forms.CharField(widget=widgets.TextInput(attrs=REQUIRED_ATTRIBUTES)) email = forms.EmailField(widget=widgets.TextInput(attrs=REQUIRED_EMAIL_ATTRIBUTES), help_text=_('Please enter a valid email. We will never share your email in any way, shape, or form.')) institution = forms.CharField(widget=widgets.TextInput(attrs=REQUIRED_ATTRIBUTES), help_text=_('The primary institution, if any, you are affiliated with.')) - def __init__(self, *args, **kwargs): instance = kwargs.get('instance') if instance is not None: Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-09-10 18:17:44
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/e8df2aed5778/ Changeset: e8df2aed5778 User: acraze Date: 2013-09-10 20:16:44 Summary: starting to work on user account profile pages, forms, and view Affected #: 4 files diff -r ea1f5577d41480b2fad5f88b25da8c33997bad87 -r e8df2aed57783a7a0d72198d896cda51f8322b07 vcweb/core/forms.py --- a/vcweb/core/forms.py +++ b/vcweb/core/forms.py @@ -5,7 +5,7 @@ from django.forms import widgets, ValidationError from django.utils.translation import ugettext_lazy as _ -from vcweb.core.models import (Experimenter, Institution) +from vcweb.core.models import (Experimenter, Institution, Participant) from django.core.validators import email_re @@ -18,13 +18,16 @@ REQUIRED_EMAIL_ATTRIBUTES = { 'class' : 'required email' } REQUIRED_ATTRIBUTES = { 'class' : 'required' } -class BaseRegistrationForm(forms.Form): +class BaseRegistrationMixin(object): first_name = forms.CharField(widget=widgets.TextInput(attrs=REQUIRED_ATTRIBUTES)) last_name = forms.CharField(widget=widgets.TextInput(attrs=REQUIRED_ATTRIBUTES)) email = forms.EmailField(widget=widgets.TextInput(attrs=REQUIRED_EMAIL_ATTRIBUTES), help_text=_('Please enter a valid email. We will never share your email in any way, shape, or form.')) password = forms.CharField(widget=widgets.PasswordInput(attrs=REQUIRED_ATTRIBUTES)) confirm_password = forms.CharField(widget=widgets.PasswordInput(attrs=REQUIRED_ATTRIBUTES)) institution = forms.CharField(widget=widgets.TextInput(attrs=REQUIRED_ATTRIBUTES), help_text=_('The primary institution, if any, you are affiliated with.')) + + +class BaseRegistrationForm(BaseRegistrationMixin, forms.Form): def clean_email(self): email = self.cleaned_data['email'].lower() try: @@ -62,8 +65,45 @@ raise forms.ValidationError(_("This user has been deactivated. Please contact us if this is in error.")) return self.cleaned_data -class ParticipantAccountForm(BaseRegistrationForm): - pass + +class ParticipantAccountForm(forms.ModelForm): + + pk = forms.IntegerField(widget=widgets.HiddenInput()) + first_name = forms.CharField(widget=widgets.TextInput(attrs=REQUIRED_ATTRIBUTES)) + last_name = forms.CharField(widget=widgets.TextInput(attrs=REQUIRED_ATTRIBUTES)) + email = forms.EmailField(widget=widgets.TextInput(attrs=REQUIRED_EMAIL_ATTRIBUTES), help_text=_('Please enter a valid email. We will never share your email in any way, shape, or form.')) + institution = forms.CharField(widget=widgets.TextInput(attrs=REQUIRED_ATTRIBUTES), help_text=_('The primary institution, if any, you are affiliated with.')) + + def __init__(self, *args, **kwargs): + instance = kwargs.get('instance') + if instance is not None: + logger.debug("IF CONDITION") + super(forms.ModelForm, self).__init__(*args, **kwargs) + for attr in ("pk", "first_name", 'last_name', 'email', 'institution'): + self.fields[attr].initial = getattr(instance, attr) + else: + logger.debug("ELSE") + super(forms.ModelForm, self).__init__(*args, **kwargs) + + class Meta: + model = Participant + fields = ['major', 'classStatus', 'gender', 'can_receive_invitations'] + + def clean(self): + data = super(forms.ModelForm, self).clean() + m = data.get('email') + canBeInvited = data.get('can_receive_invitations') + major = data.get('major') + gender = data.get('gender') + classStatus = data.get('classStatus') + if not m: + raise forms.ValidationError("You have forgotten your Email address") + + if canBeInvited: + if not major or not gender or not classStatus: + raise forms.ValidationError("You need to enter your major, gender and class status if you wan't to receive Invitations") + + return data class ExperimenterAccountForm(forms.ModelForm): class Meta: diff -r ea1f5577d41480b2fad5f88b25da8c33997bad87 -r e8df2aed57783a7a0d72198d896cda51f8322b07 vcweb/core/templates/account/profile.html --- a/vcweb/core/templates/account/profile.html +++ b/vcweb/core/templates/account/profile.html @@ -2,18 +2,30 @@ {% block head %} {{ block.super }} -<script type='text/javascript'> - $(document).ready(function() { - $("#profileForm :input:visible:enabled:first").focus(); - $('#profileForm').validate(); - }); -</script> + {% endblock head %} {% block title %}Your Account{% endblock %} {% block form %} <h3>{{ request.user.get_full_name }}</h3> + {% include "includes/bootstrap-form.html" %} +<button type='button' id="submitprofile">Save</button> {% endblock %} +{% block javascript %} + {{ block.super }} +<script type='text/javascript'> + $(document).ready(function() { + $("#profileForm :input:visible:enabled:first").focus(); + $('#profileForm').validate(); + }); + + $("#submitprofile").click( function () { + var formData = $('#vcweb-form').serialize(); + console.debug("submitting form data: " + formData); + $.post('/accounts/profile/update', formData); + }); +</script> +{% endblock javascript %} \ No newline at end of file diff -r ea1f5577d41480b2fad5f88b25da8c33997bad87 -r e8df2aed57783a7a0d72198d896cda51f8322b07 vcweb/core/urls.py --- a/vcweb/core/urls.py +++ b/vcweb/core/urls.py @@ -18,6 +18,7 @@ url(r'^accounts/logout/$', login_required(LogoutView.as_view()), name='logout'), url(r'^accounts/add/$', RegistrationView.as_view(), name='register'), url(r'^accounts/profile/$', 'account_profile', name='profile'), + url(r'^accounts/profile/update$', 'update_account_profile', name='update_profile'), url(r'^participate/?$', Participate.as_view(), name='participate'), url(r'^participate/survey-completed', completed_survey, name='survey_completed'), url(r'^participate/(?P<pk>\d+)/check-survey-completed', check_survey_completed, name='check_survey_completed'), diff -r ea1f5577d41480b2fad5f88b25da8c33997bad87 -r e8df2aed57783a7a0d72198d896cda51f8322b07 vcweb/core/views.py --- a/vcweb/core/views.py +++ b/vcweb/core/views.py @@ -3,6 +3,7 @@ from django.contrib.auth.decorators import login_required from django.core.urlresolvers import reverse from django.core.exceptions import PermissionDenied +from django.forms.models import inlineformset_factory from django.http import HttpResponse, Http404 from django.shortcuts import render, redirect, get_object_or_404 from django.template.context import RequestContext @@ -248,12 +249,39 @@ class AccountView(FormView): pass +@login_required +def update_account_profile(request): + form = ParticipantAccountForm(request.POST or None) + logger.debug("form is: %s", form) + logger.debug("Can Be Invited: %s", form.cleaned_data.get('can_receive_invitations')) + if form.is_valid(): + pk = form.cleaned_data.get('pk') + + + p = Participant.objects.get(pk = pk) + for attr in ('major', 'classStatus', 'gender', 'can_receive_invitations'): + setattr(p, attr, form.cleaned_data.get(attr)) + + for attr in ('first_name', 'last_name', 'email', 'institution'): + setattr(p.user, attr, form.cleaned_data.get(attr)) + + p.save() + + logger.debug("P: %s, P.User: %s", p, p.user) + + return JsonResponse(dumps({ + 'success': True, + 'message': 'Successful dump.' + })) + logger.debug("Form had errors %s", form) + return JsonResponse(dumps({'success': False})) + @login_required def account_profile(request): user = request.user if is_participant(user): - form = ParticipantAccountForm() + form = ParticipantAccountForm(instance=user.participant) else: form = ExperimenterAccountForm(instance=user.experimenter) return render(request, 'account/profile.html', { 'form': form }) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Shelby M. <iss...@bi...> - 2013-09-09 19:39:51
|
New issue 117: Meeting -DATE OUTPUT FORMAT & CONFIGURATION: 8/16/2013 @ 1:30PM https://bitbucket.org/virtualcommons/vcweb/issue/117/meeting-date-output-format-configuration-8 Shelby Manney: [SM COMMENT 20130908: Still needs to be added to, will complete notes today -] 8/16/2013: @1:16PM VCweb – Data Output meeting Location: CSID main conference area Attendees: Marco: mar...@as... Allen: all...@as... Shelby: sm...@as... Main Topics: Shelby – current deliverables & semester plan All, go through data output from VCweb experiments & come up with some ideas on how & what we want the data output to look like for the experimenters. Summary: Next Steps: Meeting Minutes: Approx: 47 Minutes long Marco: Number of different tasks – 1. Design of Admin/experimenters GUI 2. Running the experiment in Classes (3 classes) 3. Process Data a. Might be multiple ways we decide to process the data b. Figure out workflow Allen/me that will mirror experimenters workflow c. How to move chunks of data from raw output from VCWEB db & provide it in a file format and layout that is most beneficial for experimenter to do statistical analysis. d. Have Marco provide a model or Suggested workflow for how he uses the VCWEB output currently. i. Marco to provide example of past experiment data manipulation workflow. Perhaps Shelby will shadow him when as he goes through data manipulation? ii. Create a step by step list of what he does & how he would like this workflow to change. iii. Where can we most effectively & efficiently implement automated workflow tasks? MARCO –would like to possibly have some way of aggregating or disaggregating data by/into single or seperate variable(s) • Main issue to figure out is WHAT THE VARIABLES/CATEGORIES NEED TO BE?? Recording: Marco: are there any requirements currently for data collection? Allen: yes there are curtain requirements currently Allen: Shelby to look @ DATE formatting – how will we separate the date & correct for how excel reads the dates (changes them into numbers that donot resemble the dates at all) e.g. 08/16/2013 becomes 417002 – not sure what/ how excel comes up with this number? How do we correct for this? Marco: Might be trivial, the input data looks like this __________[INSERT WHAT DATA LOOKS LIKE when you have a chance] And this is what EXCEL is reads the CSV as. SHELBY: Possible ways to reconcile the issue: 1. Create an excel or open office type spreadsheet that the experimenter can download that has already been formatted to take in data and displays it appropriately. a. Requirements: i. Maintenance costs: 1. We might have to update spreadsheet if excel or open office changes 2. We might have to update spreadsheet if data output changes ii. That there is both a CSV or other raw text output & a template excel workbook file iii. Steps for how to best download raw data & put it into the excel template 2. Simply create steps for the experimenter to follow w/ regard to downloading and importing data file into excel and/or other programs a. Maintenance costs – we must keep the workflow steps up to date 3. Automate workflow so that excel (through a script) creates the proper column data type a. High maintenance costs – must maintain the scripts b. Assumes that the experimenter will use excel – or we have to create and maintain multiple scripts for multiple programs 4. Change the way VCWEB exports the dates from a “date” field like (e.g. 01/13/2013 – which makes excel do a mathematical function to another alphanumeric string or numeric stream (e.g. 01132013; or 20130113; or Jan. 01, 2013, etc. ) FOLLOW-UP & SHELBY suggestion – 1. If it is only the date problem – (most likely only in spreadsheet programs like excel) I suggest that we provide steps (there are a few very easy ways to correct for this – both when the user is initially importing the CSV file & also after the file has already been imported) 2. OR the above solution no. 4 would work (if the date output is the only issue). We might also provide a few helpful hints in the admin panel. I still believe adding help (a lookup of topics and a way to start a help ticket might be useful – eventually an undergrad worker or intern could be used for some type of live help). a. Also, as the VCWEB community grows it might be a great idea to have a community ‘blog’ or help center in which we allow the community of users to answer each other’s questions and (like wordpress) develop new experiments, scripts, templates, and other things & share them. \\\ SHELBY - need to finish notes by compiling autofile and written notes \\\\ Responsible: alllee |
From: <com...@bi...> - 2013-09-06 19:39:22
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/ea1f5577d414/ Changeset: ea1f5577d414 User: acraze Date: 2013-09-06 21:38:53 Summary: adding subject pool stub app Affected #: 4 files diff -r 647d15a8872f6c85175bdfe781e65b2dd4b29eba -r ea1f5577d41480b2fad5f88b25da8c33997bad87 vcweb/subject_pool/models.py --- /dev/null +++ b/vcweb/subject_pool/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff -r 647d15a8872f6c85175bdfe781e65b2dd4b29eba -r ea1f5577d41480b2fad5f88b25da8c33997bad87 vcweb/subject_pool/tests.py --- /dev/null +++ b/vcweb/subject_pool/tests.py @@ -0,0 +1,16 @@ +""" +This file demonstrates writing tests using the unittest module. These will pass +when you run "manage.py test". + +Replace this with more appropriate tests for your application. +""" + +from django.test import TestCase + + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.assertEqual(1 + 1, 2) diff -r 647d15a8872f6c85175bdfe781e65b2dd4b29eba -r ea1f5577d41480b2fad5f88b25da8c33997bad87 vcweb/subject_pool/views.py --- /dev/null +++ b/vcweb/subject_pool/views.py @@ -0,0 +1,1 @@ +# Create your views here. Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-09-06 19:03:31
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/647d15a8872f/ Changeset: 647d15a8872f User: acraze Date: 2013-09-06 21:01:38 Summary: adding optional major and class status demographic fields to Participant along with schema migration Affected #: 2 files diff -r 9c825d38ce78f418c9fba54d2f111f8c3bcef21a -r 647d15a8872f6c85175bdfe781e65b2dd4b29eba vcweb/core/migrations/0012_auto__add_field_participant_major__add_field_participant_classStatus.py --- /dev/null +++ b/vcweb/core/migrations/0012_auto__add_field_participant_major__add_field_participant_classStatus.py @@ -0,0 +1,422 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Participant.major' + db.add_column(u'core_participant', 'major', + self.gf('django.db.models.fields.CharField')(default='', max_length=64, blank=True), + keep_default=False) + + # Adding field 'Participant.classStatus' + db.add_column(u'core_participant', 'classStatus', + self.gf('django.db.models.fields.CharField')(default='', max_length=32, blank=True), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'Participant.major' + db.delete_column(u'core_participant', 'major') + + # Deleting field 'Participant.classStatus' + db.delete_column(u'core_participant', 'classStatus') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'core.activitylog': { + 'Meta': {'object_name': 'ActivityLog'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'log_message': ('django.db.models.fields.TextField', [], {}) + }, + u'core.address': { + 'Meta': {'object_name': 'Address'}, + 'city': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'street1': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'street2': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'zipcode': ('django.db.models.fields.CharField', [], {'max_length': '8', 'blank': 'True'}) + }, + u'core.bookmarkedexperimentmetadata': { + 'Meta': {'ordering': "['experimenter', 'experiment_metadata']", 'unique_together': "(('experimenter', 'experiment_metadata'),)", 'object_name': 'BookmarkedExperimentMetadata'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bookmarked_experiment_metadata_set'", 'to': u"orm['core.ExperimentMetadata']"}), + 'experimenter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bookmarked_experiment_metadata_set'", 'to': u"orm['core.Experimenter']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'core.chatmessage': { + 'Meta': {'ordering': "['-date_created']", 'object_name': 'ChatMessage', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}), + 'target_participant': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_participant_chat_message_set'", 'null': 'True', 'to': u"orm['core.ParticipantGroupRelationship']"}) + }, + u'core.comment': { + 'Meta': {'ordering': "['-date_created']", 'object_name': 'Comment', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.experiment': { + 'Meta': {'ordering': "['date_created', 'status']", 'object_name': 'Experiment'}, + 'amqp_exchange_name': ('django.db.models.fields.CharField', [], {'default': "'vcweb.default.exchange'", 'max_length': '64'}), + 'authentication_code': ('django.db.models.fields.CharField', [], {'default': "'vcweb.auth.code'", 'max_length': '32'}), + 'current_repeated_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'current_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'current_round_start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'date_activated': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']"}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']"}), + 'experimenter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'INACTIVE'", 'max_length': '32'}), + 'tick_duration': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}) + }, + u'core.experimentactivitylog': { + 'Meta': {'object_name': 'ExperimentActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Experiment']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.experimentconfiguration': { + 'Meta': {'ordering': "['experiment_metadata', 'creator', 'date_created']", 'object_name': 'ExperimentConfiguration'}, + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'exchange_rate': ('django.db.models.fields.DecimalField', [], {'default': '0.2', 'null': 'True', 'max_digits': '6', 'decimal_places': '2', 'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_configuration_set'", 'to': u"orm['core.ExperimentMetadata']"}), + 'has_daily_rounds': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_subject': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'is_experimenter_driven': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'max_group_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'max_number_of_participants': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'treatment_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}) + }, + u'core.experimenter': { + 'Meta': {'ordering': "['user']", 'object_name': 'Experimenter'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'experimenter'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.experimenterrequest': { + 'Meta': {'object_name': 'ExperimenterRequest'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'}) + }, + u'core.experimentmetadata': { + 'Meta': {'ordering': "['namespace', 'date_created']", 'object_name': 'ExperimentMetadata'}, + 'about_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentConfiguration']", 'null': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'namespace': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'short_name': ('django.db.models.fields.SlugField', [], {'max_length': '32', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'core.experimentparametervalue': { + 'Meta': {'object_name': 'ExperimentParameterValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'parameter_value_set'", 'to': u"orm['core.ExperimentConfiguration']"}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + u'core.experimentsession': { + 'Meta': {'object_name': 'ExperimentSession'}, + 'capacity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '20'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['auth.User']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_session_set'", 'to': u"orm['core.ExperimentMetadata']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'scheduled_date': ('django.db.models.fields.DateTimeField', [], {}), + 'scheduled_end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + u'core.group': { + 'Meta': {'ordering': "['experiment', 'number']", 'object_name': 'Group'}, + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'max_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '5'}), + 'number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'session_id': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '64', 'blank': 'True'}) + }, + u'core.groupactivitylog': { + 'Meta': {'object_name': 'GroupActivityLog', '_ormbases': [u'core.ActivityLog']}, + u'activitylog_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ActivityLog']", 'unique': 'True', 'primary_key': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'activity_log_set'", 'to': u"orm['core.Group']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.groupcluster': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'GroupCluster'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_cluster_set'", 'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'session_id': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '64', 'blank': 'True'}) + }, + u'core.groupclusterdatavalue': { + 'Meta': {'object_name': 'GroupClusterDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'group_cluster': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'data_value_set'", 'to': u"orm['core.GroupCluster']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_cluster_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + u'core.grouprelationship': { + 'Meta': {'ordering': "['date_created']", 'object_name': 'GroupRelationship'}, + 'cluster': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_relationship_set'", 'to': u"orm['core.GroupCluster']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'core.grouprounddatavalue': { + 'Meta': {'ordering': "['round_data', 'group', 'parameter']", 'object_name': 'GroupRoundDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'data_value_set'", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + u'core.institution': { + 'Meta': {'object_name': 'Institution'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) + }, + u'core.invitation': { + 'Meta': {'object_name': 'Invitation'}, + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment_session': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentSession']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Participant']"}), + 'sender': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + u'core.like': { + 'Meta': {'ordering': "['-date_created', 'round_data', 'participant_group_relationship', 'parameter']", 'object_name': 'Like', '_ormbases': [u'core.ParticipantRoundDataValue']}, + u'participantrounddatavalue_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['core.ParticipantRoundDataValue']", 'unique': 'True', 'primary_key': 'True'}) + }, + u'core.parameter': { + 'Meta': {'ordering': "['name']", 'unique_together': "(('name', 'experiment_metadata', 'scope'),)", 'object_name': 'Parameter'}, + 'class_name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Experimenter']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'default_value_string': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), + 'display_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'enum_choices': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'experiment_metadata': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.ExperimentMetadata']", 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_required': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'scope': ('django.db.models.fields.CharField', [], {'default': "'round'", 'max_length': '32'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) + }, + u'core.participant': { + 'Meta': {'ordering': "['user']", 'object_name': 'Participant'}, + 'address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Address']", 'null': 'True', 'blank': 'True'}), + 'authentication_token': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'birthdate': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'can_receive_invitations': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'classStatus': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'experiments': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'participant_set'", 'symmetrical': 'False', 'through': u"orm['core.ParticipantExperimentRelationship']", 'to': u"orm['core.Experiment']"}), + 'failed_password_attempts': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'gender': ('django.db.models.fields.CharField', [], {'max_length': '1', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'participant_set'", 'symmetrical': 'False', 'through': u"orm['core.ParticipantGroupRelationship']", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'institution': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Institution']", 'null': 'True', 'blank': 'True'}), + 'major': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'participant'", 'unique': 'True', 'to': u"orm['auth.User']"}) + }, + u'core.participantexperimentrelationship': { + 'Meta': {'object_name': 'ParticipantExperimentRelationship'}, + 'additional_data': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}), + 'current_location': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_relationship_set'", 'to': u"orm['core.Experiment']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_completed_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'experiment_relationship_set'", 'to': u"orm['core.Participant']"}), + 'participant_identifier': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'sequential_participant_identifier': ('django.db.models.fields.PositiveIntegerField', [], {}) + }, + u'core.participantgrouprelationship': { + 'Meta': {'ordering': "['group', 'participant_number']", 'object_name': 'ParticipantGroupRelationship'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'first_visit': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_group_relationship_set'", 'to': u"orm['core.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'notifications_since': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'null': 'True', 'blank': 'True'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_group_relationship_set'", 'to': u"orm['core.Participant']"}), + 'participant_number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'round_joined': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.RoundConfiguration']"}), + 'survey_completed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + u'core.participantrounddatavalue': { + 'Meta': {'ordering': "['-date_created', 'round_data', 'participant_group_relationship', 'parameter']", 'object_name': 'ParticipantRoundDataValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'participant_group_relationship': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'data_value_set'", 'to': u"orm['core.ParticipantGroupRelationship']"}), + 'round_data': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participant_data_value_set'", 'to': u"orm['core.RoundData']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'submitted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'target_data_value': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'target_data_value_set'", 'null': 'True', 'to': u"orm['core.ParticipantRoundDataValue']"}) + }, + u'core.participantsignup': { + 'Meta': {'object_name': 'ParticipantSignup'}, + 'attendance': ('django.db.models.fields.PositiveIntegerField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'signup_set'", 'to': u"orm['core.Invitation']"}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'signup_set'", 'to': u"orm['core.Participant']"}) + }, + u'core.quizquestion': { + 'Meta': {'object_name': 'QuizQuestion'}, + 'answer': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'default_quiz_question_set'", 'null': 'True', 'to': u"orm['core.Experiment']"}), + 'explanation': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'input_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'label': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'quiz_question_set'", 'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.roundconfiguration': { + 'Meta': {'ordering': "['experiment_configuration', 'sequence_number', 'date_created']", 'object_name': 'RoundConfiguration'}, + 'chat_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'create_group_clusters': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'debriefing': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'display_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'duration': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'experiment_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_configuration_set'", 'to': u"orm['core.ExperimentConfiguration']"}), + 'group_cluster_size': ('django.db.models.fields.PositiveIntegerField', [], {'default': '2', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'initialize_data_values': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'instructions': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'preserve_existing_groups': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'randomize_groups': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'repeat': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'round_type': ('django.db.models.fields.CharField', [], {'default': "'REGULAR'", 'max_length': '32'}), + 'sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'session_id': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '64', 'blank': 'True'}), + 'survey_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'template_filename': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'template_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}) + }, + u'core.rounddata': { + 'Meta': {'ordering': "['round_configuration', 'repeating_round_sequence_number']", 'unique_together': "(('round_configuration', 'repeating_round_sequence_number', 'experiment'),)", 'object_name': 'RoundData'}, + 'elapsed_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'experiment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_data_set'", 'to': u"orm['core.Experiment']"}), + 'experimenter_notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'repeating_round_sequence_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'round_data_set'", 'to': u"orm['core.RoundConfiguration']"}) + }, + u'core.roundparametervalue': { + 'Meta': {'ordering': "['round_configuration', 'parameter', 'date_created']", 'object_name': 'RoundParameterValue'}, + 'boolean_value': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), + 'float_value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'int_value': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'last_modified': ('vcweb.core.models.AutoDateTimeField', [], {'default': 'datetime.datetime.now'}), + 'parameter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['core.Parameter']"}), + 'round_configuration': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'parameter_value_set'", 'to': u"orm['core.RoundConfiguration']"}), + 'string_value': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + u'core.spoolparticipantstatistics': { + 'Meta': {'object_name': 'SpoolParticipantStatistics'}, + 'absences': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'discharges': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invitations': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'participant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'spool_statistics_set'", 'to': u"orm['core.Participant']"}), + 'participations': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + } + } + + complete_apps = ['core'] \ No newline at end of file diff -r 9c825d38ce78f418c9fba54d2f111f8c3bcef21a -r 647d15a8872f6c85175bdfe781e65b2dd4b29eba vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -1843,11 +1843,14 @@ class Participant(CommonsUser): GENDER_CHOICES = (('M', 'Male'), ('F', 'Female'),) + CLASS_CHOICES = Choices('Freshman', 'Sophomore', 'Junior', 'Senior', 'Graduate', 'Other') can_receive_invitations = models.BooleanField(default=False) groups = models.ManyToManyField(Group, through='ParticipantGroupRelationship', related_name='participant_set') experiments = models.ManyToManyField(Experiment, through='ParticipantExperimentRelationship', related_name='participant_set') gender = models.CharField(max_length=1, choices=GENDER_CHOICES, blank=True) birthdate = models.DateField(null=True, blank=True) + major = models.CharField(max_length=64, blank=True) + classStatus = models.CharField(max_length=32, choices=CLASS_CHOICES, blank=True) address = models.ForeignKey(Address, null=True, blank=True) class Meta: Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-09-06 07:25:53
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/9c825d38ce78/ Changeset: 9c825d38ce78 User: alllee Date: 2013-09-06 09:25:47 Summary: adjusting practice round instructions to list different timings Affected #: 1 file diff -r f01a26231127168eb0934265ca131551bd382372 -r 9c825d38ce78f418c9fba54d2f111f8c3bcef21a vcweb/bound/templates/bound/participate.html --- a/vcweb/bound/templates/bound/participate.html +++ b/vcweb/bound/templates/bound/participate.html @@ -360,12 +360,19 @@ </p><h3>Group and Individual Status</h3><p> -You will be able to observe the status of the members of your group each round. Likewise, group members will see your +You will be able to observe the status of the members of your group each round. Likewise, group members will see your status, and those of your group. You will be able to text chat with your group members. </p> -<h3>Harvest Choice</h3> +<h3>Time</h3><p> -Each round you will have a maximum of 1 minute to make a harvest decision. There are two ways to submit a harvest +In each actual experiment round you will have a maximum of 60 seconds to make a harvest decision. In order to help you acquaint +yourself with the experimental environment, the you will have 3 minutes to make a harvest decision in the first practice +round, 2 minutes to make a harvest in the next two practice rounds, and then one minute as usual in the subsequent +practice rounds. +</p> +<h3>Harvest Decision</h3> +<p> +There are two ways to submit a harvest decision: </p><ol> @@ -555,8 +562,7 @@ </script><script src='{% static "js/bootstrap-tour.js" %}'></script><script type="text/javascript"> -// 3. This function creates an <iframe> (and YouTube player) -// after the API code downloads. +// set up youtube player for video intro tutorial var youtubePlayer; function onYouTubeIframeAPIReady() { youtubePlayer = new YT.Player('bound-video-tutorial', { @@ -636,6 +642,7 @@ tour.addStep({ element: "#harvest-decision-td-10", title: "Harvest Decision", placement: "right", content: "Click on the number of trees you'd like to harvest here. For the purposes of this practice round, please select 10 now and click the 'Ok, I'm ready' button."}); + tour.goto(0); tour.start(true); } model.endTour = function() { Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-09-05 23:14:31
|
2 new commits in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/8b6c2a3d6ac1/ Changeset: 8b6c2a3d6ac1 User: alllee Date: 2013-09-04 23:13:14 Summary: version bump to 0.5.1 on bootstrap tour Affected #: 3 files diff -r 46261a37e2217eafce76ba1d151bd2cd9cf7fec0 -r 8b6c2a3d6ac156809d293009adcc5969a8371f30 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -339,7 +339,7 @@ return serializers.serialize(output_format, all_objects, **kwargs) def __unicode__(self): - return self.name + return u"%s (%s)" % (self.name, self.experiment_metadata) class Meta: ordering = ['experiment_metadata', 'creator', 'date_created'] @@ -1176,7 +1176,7 @@ help_text=_('A HTML template ID to use in a single page app, e.g., KO template')) survey_url = models.URLField(null=True, blank=True) """ external survey url for qualtrics integration """ - chat_enabled = models.BooleanField(default=False, help_text=_("Chat enabled")) + chat_enabled = models.BooleanField(default=False, help_text=_("Enable in-round communication")) create_group_clusters = models.BooleanField(default=False, help_text=_("Create relationships (clusters) of groups that can share group cluster data values")) group_cluster_size = models.PositiveIntegerField(null=True, blank=True, default=2, help_text=_("How many groups should form a cluster?")) randomize_groups = models.BooleanField(default=False, help_text=_("Shuffle participants into new groups when the round begins?")) diff -r 46261a37e2217eafce76ba1d151bd2cd9cf7fec0 -r 8b6c2a3d6ac156809d293009adcc5969a8371f30 vcweb/lighterprints/models.py --- a/vcweb/lighterprints/models.py +++ b/vcweb/lighterprints/models.py @@ -26,12 +26,12 @@ EXPERIMENT_METADATA_NAME = intern('lighterprints') @receiver(signals.midnight_tick) -def update_active_experiments(sender, time=None, start=None, send_emails=True, **kwargs): +def update_active_level_based_experiments(sender, time=None, start=None, send_emails=True, **kwargs): # since this happens at midnight we need to look at the previous day if start is None: start = date.today() - timedelta(1); - active_experiments = get_active_experiments() - logger.debug("updating active experiments [%s] for %s", active_experiments, start) + active_experiments = get_active_experiments(has_scheduled_activities=False) + logger.debug("updating active level based experiments [%s] for %s", active_experiments, start) messages = [] for experiment in active_experiments: # calculate total carbon savings and decide if they move on to the next level @@ -287,6 +287,9 @@ return (treatment_type is None) or ('COMPARE_OTHER_GROUP' in treatment_type.string_value) def get_active_experiments(): + ''' + partition these into two tuples - level based and schedule based? + ''' return Experiment.objects.active(experiment_metadata=get_lighterprints_experiment_metadata()) def get_activity_status_dict(participant_group_relationship, activities, group_level=1): diff -r 46261a37e2217eafce76ba1d151bd2cd9cf7fec0 -r 8b6c2a3d6ac156809d293009adcc5969a8371f30 vcweb/static/js/bootstrap-tour.js --- a/vcweb/static/js/bootstrap-tour.js +++ b/vcweb/static/js/bootstrap-tour.js @@ -1,5 +1,5 @@ /* =========================================================== -# bootstrap-tour - v0.5.0 +# bootstrap-tour - v0.6.0 # http://bootstraptour.com # ============================================================== # Copyright 2012-2013 Ulrich Sossou @@ -16,4 +16,4 @@ # See the License for the specific language governing permissions and # limitations under the License. */ -!function(){!function(a,b){var c,d;return d=b.document,c=function(){function c(b){this._options=a.extend({name:"tour",container:"body",keyboard:!0,useLocalStorage:!1,debug:!1,backdrop:!1,redirect:!0,basePath:"",template:"<div class='popover tour'><div class='arrow'></div><h3 class='popover-title'></h3><div class='popover-content'></div><div class='popover-navigation'><button class='btn' data-role='prev'>« Prev</button><span data-role='separator'>|</span><button class='btn' data-role='next'>Next »</button><button class='btn' data-role='end'>End tour</button></div></div>",afterSetState:function(){},afterGetState:function(){},afterRemoveState:function(){},onStart:function(){},onEnd:function(){},onShow:function(){},onShown:function(){},onHide:function(){},onHidden:function(){},onNext:function(){},onPrev:function(){}},b),this._options.useLocalStorage||a.cookie||this._debug("jQuery.cookie is not loaded."),this._steps=[],this.setCurrentStep(),this.backdrop={overlay:null,step:null,background:null}}return c.prototype.setState=function(c,d){return c=""+this._options.name+"_"+c,this._options.useLocalStorage?b.localStorage.setItem(c,d):a.cookie(c,d,{expires:36500,path:"/"}),this._options.afterSetState(c,d)},c.prototype.removeState=function(c){return c=""+this._options.name+"_"+c,this._options.useLocalStorage?b.localStorage.removeItem(c):a.removeCookie(c,{path:"/"}),this._options.afterRemoveState(c)},c.prototype.getState=function(c){var d;return d=this._options.useLocalStorage?b.localStorage.getItem(""+this._options.name+"_"+c):a.cookie(""+this._options.name+"_"+c),(void 0===d||"null"===d)&&(d=null),this._options.afterGetState(c,d),d},c.prototype.addSteps=function(a){var b,c,d,e;for(e=[],c=0,d=a.length;d>c;c++)b=a[c],e.push(this.addStep(b));return e},c.prototype.addStep=function(a){return this._steps.push(a)},c.prototype.getStep=function(b){return null!=this._steps[b]?a.extend({id:"step-"+b,path:"",placement:"right",title:"",content:"<p></p>",next:b===this._steps.length-1?-1:b+1,prev:b-1,animation:!0,container:this._options.container,backdrop:this._options.backdrop,redirect:this._options.redirect,template:this._options.template,onShow:this._options.onShow,onShown:this._options.onShown,onHide:this._options.onHide,onHidden:this._options.onHidden,onNext:this._options.onNext,onPrev:this._options.onPrev},this._steps[b]):void 0},c.prototype.start=function(b){var c,e=this;return null==b&&(b=!1),this.ended()&&!b?this._debug("Tour ended, start prevented."):(a(d).off("click.bootstrap-tour",".popover *[data-role=next]").on("click.bootstrap-tour",".popover *[data-role=next]",function(a){return a.preventDefault(),e.next()}),a(d).off("click.bootstrap-tour",".popover *[data-role=prev]").on("click.bootstrap-tour",".popover *[data-role=prev]",function(a){return a.preventDefault(),e.prev()}),a(d).off("click.bootstrap-tour",".popover *[data-role=end]").on("click.bootstrap-tour",".popover *[data-role=end]",function(a){return a.preventDefault(),e.end()}),this._onresize(function(){return e.showStep(e._current)}),this._setupKeyboardNavigation(),c=this._makePromise(null!=this._options.onStart?this._options.onStart(this):void 0),this._callOnPromiseDone(c,this.showStep,this._current))},c.prototype.next=function(){var a;return a=this.hideStep(this._current),this._callOnPromiseDone(a,this.showNextStep)},c.prototype.prev=function(){var a;return a=this.hideStep(this._current),this._callOnPromiseDone(a,this.showPrevStep)},c.prototype.end=function(){var c,e,f=this;return c=function(){return a(d).off("click.bootstrap-tour"),a(d).off("keyup.bootstrap-tour"),a(b).off("resize.bootstrap-tour"),f.setState("end","yes"),f._hideBackdrop(),null!=f._options.onEnd?f._options.onEnd(f):void 0},e=this.hideStep(this._current),this._callOnPromiseDone(e,c)},c.prototype.ended=function(){return!!this.getState("end")},c.prototype.restart=function(){return this.removeState("current_step"),this.removeState("end"),this.setCurrentStep(0),this.start()},c.prototype.hideStep=function(b){var c,d,e,f=this;return e=this.getStep(b),d=this._makePromise(null!=e.onHide?e.onHide(this):void 0),c=function(){var b;return b=a(e.element).popover("hide"),e.reflex&&b.css("cursor","").off("click.bootstrap-tour"),e.backdrop&&f._hideBackdrop(),null!=e.onHidden?e.onHidden(f):void 0},this._callOnPromiseDone(d,c),d},c.prototype.showStep=function(b){var c,e,f,g=this;return(f=this.getStep(b))?(c=this._makePromise(null!=f.onShow?f.onShow(this):void 0),e=function(){var c,e;return g.setCurrentStep(b),e=a.isFunction(f.path)?f.path.call():g._options.basePath+f.path,c=[d.location.pathname,d.location.hash].join(""),g._isRedirect(e,c)?(g._redirect(f,e),void 0):null!=f.element&&0!==a(f.element).length&&a(f.element).is(":visible")?(f.backdrop&&g._showBackdrop(f.element),g._showPopover(f,b),null!=f.onShown&&f.onShown(g),g._debug("Step "+(g._current+1)+" of "+g._steps.length)):(g._debug("Skip the step "+(g._current+1)+". The element does not exist or is not visible."),g.showNextStep(),void 0)},this._callOnPromiseDone(c,e)):void 0},c.prototype.setCurrentStep=function(a){return null!=a?(this._current=a,this.setState("current_step",a)):(this._current=this.getState("current_step"),this._current=null===this._current?0:parseInt(this._current))},c.prototype.showNextStep=function(){var a,b,c,d=this;return c=this.getStep(this._current),b=function(){return d.showStep(c.next)},a=this._makePromise(null!=c.onNext?c.onNext(this):void 0),this._callOnPromiseDone(a,b)},c.prototype.showPrevStep=function(){var a,b,c,d=this;return c=this.getStep(this._current),b=function(){return d.showStep(c.prev)},a=this._makePromise(null!=c.onPrev?c.onPrev(this):void 0),this._callOnPromiseDone(a,b)},c.prototype._debug=function(a){return this._options.debug?b.console.log("Bootstrap Tour '"+this._options.name+"' | "+a):void 0},c.prototype._isRedirect=function(a,b){return null!=a&&""!==a&&a.replace(/\?.*$/,"").replace(/\/?$/,"")!==b.replace(/\/?$/,"")},c.prototype._redirect=function(b,c){return a.isFunction(b.redirect)?b.redirect.call(this,c):b.redirect===!0?(this._debug("Redirect to "+c),d.location.href=c):void 0},c.prototype._renderNavigation=function(b,c){var d;return d=a.isFunction(b.template)?a(b.template(c,b)):a(b.template),b.prev>=0||d.find(".popover-navigation *[data-role=prev]").remove(),b.next>=0||d.find(".popover-navigation *[data-role=next]").remove(),b.prev>=0&&b.next>=0||d.find(".popover-navigation *[data-role=separator]").remove(),d.clone().wrap("<div>").parent().html()},c.prototype._showPopover=function(b,c){var d,e,f,g,h=this;return f=a.extend({},this._options),b.options&&a.extend(f,b.options),b.reflex&&a(b.element).css("cursor","pointer").on("click.bootstrap-tour",function(){return h.next()}),g=this._renderNavigation(b,c,f),d=a(b.element),d.data("popover")&&d.popover("destroy"),d.popover({placement:b.placement,trigger:"manual",title:b.title,content:b.content,html:!0,animation:b.animation,container:b.container,template:g,selector:b.element}).popover("show"),e=a(b.element).data("popover").tip(),e.attr("id",b.id),this._reposition(e,b),this._scrollIntoView(e)},c.prototype._reposition=function(b,c){var e,f,g,h,i,j,k;if(i=b[0].offsetWidth,h=b[0].offsetHeight,k=b.offset(),g=k.left,j=k.top,e=a(d).outerHeight()-k.top-a(b).outerHeight(),0>e&&(k.top=k.top+e),f=a("html").outerWidth()-k.left-a(b).outerWidth(),0>f&&(k.left=k.left+f),k.top<0&&(k.top=0),k.left<0&&(k.left=0),b.offset(k),"bottom"===c.placement||"top"===c.placement){if(g!==k.left)return this._replaceArrow(b,2*(k.left-g),i,"left")}else if(j!==k.top)return this._replaceArrow(b,2*(k.top-j),h,"top")},c.prototype._replaceArrow=function(a,b,c,d){return a.find(".arrow").css(d,b?50*(1-b/c)+"%":"")},c.prototype._scrollIntoView=function(c){var d;return d=c.get(0).getBoundingClientRect(),d.top>=0&&d.bottom<a(b).height()&&d.left>=0&&d.right<a(b).width()?void 0:c.get(0).scrollIntoView(!0)},c.prototype._onresize=function(c,d){return a(b).on("resize.bootstrap-tour",function(){return clearTimeout(d),d=setTimeout(c,100)})},c.prototype._setupKeyboardNavigation=function(){var b=this;return this._options.keyboard?a(d).on("keyup.bootstrap-tour",function(a){if(a.which)switch(a.which){case 39:return a.preventDefault(),b._current<b._steps.length-1?b.next():b.end();case 37:if(a.preventDefault(),b._current>0)return b.prev();break;case 27:return a.preventDefault(),b.end()}}):void 0},c.prototype._makePromise=function(b){return b&&a.isFunction(b.then)?b:null},c.prototype._callOnPromiseDone=function(a,b,c){var d=this;return a?a.then(function(){return b.call(d,c)}):b.call(this,c)},c.prototype._showBackdrop=function(a){return null===this.backdrop.overlay?(this._showOverlay(),this._showOverlayElement(a)):void 0},c.prototype._hideBackdrop=function(){return null!==this.backdrop.overlay?(this._hideOverlayElement(),this._hideOverlay()):void 0},c.prototype._showOverlay=function(){return this.backdrop=a("<div/>"),this.backdrop.addClass("tour-backdrop"),this.backdrop.height(a(d).innerHeight()),a("body").append(this.backdrop)},c.prototype._hideOverlay=function(){return this.backdrop.remove(),this.backdrop.overlay=null},c.prototype._showOverlayElement=function(b){var c,d,e,f;return f=a(b),e=5,d=f.offset(),d.top=d.top-e,d.left=d.left-e,c=a("<div/>"),c.width(f.innerWidth()+e).height(f.innerHeight()+e).addClass("tour-step-background").offset(d),f.addClass("tour-step-backdrop"),a("body").append(c),this.backdrop.step=f,this.backdrop.background=c},c.prototype._hideOverlayElement=function(){return this.backdrop.step.removeClass("tour-step-backdrop"),this.backdrop.background.remove(),this.backdrop.step=null,this.backdrop.background=null},c}(),b.Tour=c}(jQuery,window)}.call(this); \ No newline at end of file +!function(){!function(a,b){var c,d;return d=b.document,c=function(){function c(c){this._options=a.extend({name:"tour",container:"body",keyboard:!0,storage:b.localStorage,debug:!1,backdrop:!1,redirect:!0,orphan:!1,basePath:"",template:"<div class='popover'><div class='arrow'></div><h3 class='popover-title'></h3><div class='popover-content'></div><nav class='popover-navigation'><div class='btn-group'><button class='btn btn-sm btn-default' data-role='prev'>« Prev</button><button class='btn btn-sm btn-default' data-role='next'>Next »</button></div><button class='btn btn-sm btn-default' data-role='end'>End tour</button></nav></div>",afterSetState:function(){},afterGetState:function(){},afterRemoveState:function(){},onStart:function(){},onEnd:function(){},onShow:function(){},onShown:function(){},onHide:function(){},onHidden:function(){},onNext:function(){},onPrev:function(){}},c),this._steps=[],this.setCurrentStep(),this.backdrop={overlay:null,$element:null,$background:null}}return c.prototype.setState=function(a,b){var c;return c=""+this._options.name+"_"+a,this._options.storage.setItem(c,b),this._options.afterSetState(c,b)},c.prototype.removeState=function(a){var b;return b=""+this._options.name+"_"+a,this._options.storage.removeItem(b),this._options.afterRemoveState(b)},c.prototype.getState=function(a){var b,c;return b=""+this._options.name+"_"+a,c=this._options.storage.getItem(b),(void 0===c||"null"===c)&&(c=null),this._options.afterGetState(a,c),c},c.prototype.addSteps=function(a){var b,c,d,e;for(e=[],c=0,d=a.length;d>c;c++)b=a[c],e.push(this.addStep(b));return e},c.prototype.addStep=function(a){return this._steps.push(a)},c.prototype.getStep=function(b){return null!=this._steps[b]?a.extend({id:"step-"+b,path:"",placement:"right",title:"",content:"<p></p>",next:b===this._steps.length-1?-1:b+1,prev:b-1,animation:!0,container:this._options.container,backdrop:this._options.backdrop,redirect:this._options.redirect,orphan:this._options.orphan,template:this._options.template,onShow:this._options.onShow,onShown:this._options.onShown,onHide:this._options.onHide,onHidden:this._options.onHidden,onNext:this._options.onNext,onPrev:this._options.onPrev},this._steps[b]):void 0},c.prototype.start=function(b){var c,e=this;return null==b&&(b=!1),this.ended()&&!b?this._debug("Tour ended, start prevented."):(a(d).off("click.tour."+this._options.name,".popover *[data-role=next]").on("click.tour."+this._options.name,".popover *[data-role=next]:not(.disabled)",function(a){return a.preventDefault(),e.next()}),a(d).off("click.tour."+this._options.name,".popover *[data-role=prev]").on("click.tour."+this._options.name,".popover *[data-role=prev]:not(.disabled)",function(a){return a.preventDefault(),e.prev()}),a(d).off("click.tour."+this._options.name,".popover *[data-role=end]").on("click.tour."+this._options.name,".popover *[data-role=end]",function(a){return a.preventDefault(),e.end()}),this._onResize(function(){return e.showStep(e._current)}),this._setupKeyboardNavigation(),c=this._makePromise(null!=this._options.onStart?this._options.onStart(this):void 0),this._callOnPromiseDone(c,this.showStep,this._current))},c.prototype.next=function(){var a;return this.ended()?this._debug("Tour ended, next prevented."):(a=this.hideStep(this._current),this._callOnPromiseDone(a,this._showNextStep))},c.prototype.prev=function(){var a;return this.ended()?this._debug("Tour ended, prev prevented."):(a=this.hideStep(this._current),this._callOnPromiseDone(a,this._showPrevStep))},c.prototype.goto=function(a){var b;return this.ended()?this._debug("Tour ended, goto prevented."):(b=this.hideStep(this._current),this._callOnPromiseDone(b,this.showStep,a))},c.prototype.end=function(){var c,e,f=this;return c=function(){return a(d).off("click.tour."+f._options.name),a(d).off("keyup.tour."+f._options.name),a(b).off("resize.tour."+f._options.name),f.setState("end","yes"),null!=f._options.onEnd?f._options.onEnd(f):void 0},e=this.hideStep(this._current),this._callOnPromiseDone(e,c)},c.prototype.ended=function(){return!!this.getState("end")},c.prototype.restart=function(){return this.removeState("current_step"),this.removeState("end"),this.setCurrentStep(0),this.start()},c.prototype.hideStep=function(b){var c,d,e,f=this;return e=this.getStep(b),d=this._makePromise(null!=e.onHide?e.onHide(this,b):void 0),c=function(){var b;return b=f._isOrphan(e)?a("body"):a(e.element),b.popover("destroy"),e.reflex&&b.css("cursor","").off("click.tour."+f._options.name),e.backdrop&&f._hideBackdrop(),null!=e.onHidden?e.onHidden(f):void 0},this._callOnPromiseDone(d,c),d},c.prototype.showStep=function(b){var c,e,f,g,h=this;return(g=this.getStep(b))?(f=b<this._current,c=this._makePromise(null!=g.onShow?g.onShow(this,b):void 0),e=function(){var c,e;if(h.setCurrentStep(b),e=a.isFunction(g.path)?g.path.call():h._options.basePath+g.path,c=[d.location.pathname,d.location.hash].join(""),h._isRedirect(e,c))return h._redirect(g,e),void 0;if(h._isOrphan(g)){if(!g.orphan)return h._debug("Skip the orphan step "+(h._current+1)+". Orphan option is false and the element doesn't exist or is hidden."),f?h._showPrevStep():h._showNextStep(),void 0;h._debug("Show the orphan step "+(h._current+1)+". Orphans option is true.")}return g.backdrop&&h._showBackdrop(h._isOrphan(g)?void 0:g.element),h._showPopover(g,b),null!=g.onShown&&g.onShown(h),h._debug("Step "+(h._current+1)+" of "+h._steps.length)},this._callOnPromiseDone(c,e)):void 0},c.prototype.setCurrentStep=function(a){return null!=a?(this._current=a,this.setState("current_step",a)):(this._current=this.getState("current_step"),this._current=null===this._current?0:parseInt(this._current,10))},c.prototype._showNextStep=function(){var a,b,c,d=this;return c=this.getStep(this._current),b=function(){return d.showStep(c.next)},a=this._makePromise(null!=c.onNext?c.onNext(this):void 0),this._callOnPromiseDone(a,b)},c.prototype._showPrevStep=function(){var a,b,c,d=this;return c=this.getStep(this._current),b=function(){return d.showStep(c.prev)},a=this._makePromise(null!=c.onPrev?c.onPrev(this):void 0),this._callOnPromiseDone(a,b)},c.prototype._debug=function(a){return this._options.debug?b.console.log("Bootstrap Tour '"+this._options.name+"' | "+a):void 0},c.prototype._isRedirect=function(a,b){return null!=a&&""!==a&&a.replace(/\?.*$/,"").replace(/\/?$/,"")!==b.replace(/\/?$/,"")},c.prototype._redirect=function(b,c){return a.isFunction(b.redirect)?b.redirect.call(this,c):b.redirect===!0?(this._debug("Redirect to "+c),d.location.href=c):void 0},c.prototype._isOrphan=function(b){return null==b.element||!a(b.element).length||a(b.element).is(":hidden")},c.prototype._showPopover=function(b,c){var d,e,f,g,h,i,j=this;return i=a.extend({},this._options),f=a.isFunction(b.template)?a(b.template(c,b)):a(b.template),e=f.find(".popover-navigation"),h=this._isOrphan(b),h&&(b.element="body",b.placement="top",f=f.addClass("orphan")),d=a(b.element),f.addClass("tour-"+this._options.name),b.options&&a.extend(i,b.options),b.reflex&&d.css("cursor","pointer").on("click.tour."+this._options.name,function(){return j._current<j._steps.length-1?j.next():j.end()}),b.prev<0&&e.find("*[data-role=prev]").addClass("disabled"),b.next<0&&e.find("*[data-role=next]").addClass("disabled"),b.template=f.clone().wrap("<div>").parent().html(),d.popover({placement:b.placement,trigger:"manual",title:b.title,content:b.content,html:!0,animation:b.animation,container:b.container,template:b.template,selector:b.element}).popover("show"),g=d.data("bs.popover")?d.data("bs.popover").tip():d.data("popover").tip(),g.attr("id",b.id),this._scrollIntoView(g),this._reposition(g,b),h?this._center(g):void 0},c.prototype._reposition=function(b,c){var e,f,g,h,i,j,k;if(h=b[0].offsetWidth,f=b[0].offsetHeight,k=b.offset(),i=k.left,j=k.top,e=a(d).outerHeight()-k.top-b.outerHeight(),0>e&&(k.top=k.top+e),g=a("html").outerWidth()-k.left-b.outerWidth(),0>g&&(k.left=k.left+g),k.top<0&&(k.top=0),k.left<0&&(k.left=0),b.offset(k),"bottom"===c.placement||"top"===c.placement){if(i!==k.left)return this._replaceArrow(b,2*(k.left-i),h,"left")}else if(j!==k.top)return this._replaceArrow(b,2*(k.top-j),f,"top")},c.prototype._center=function(c){return c.css("top",a(b).outerHeight()/2-c.outerHeight()/2)},c.prototype._replaceArrow=function(a,b,c,d){return a.find(".arrow").css(d,b?50*(1-b/c)+"%":"")},c.prototype._scrollIntoView=function(c){return a("html, body").stop().animate({scrollTop:Math.ceil(c.offset().top-a(b).height()/2)})},c.prototype._onResize=function(c,d){return a(b).on("resize.tour."+this._options.name,function(){return clearTimeout(d),d=setTimeout(c,100)})},c.prototype._setupKeyboardNavigation=function(){var b=this;return this._options.keyboard?a(d).on("keyup.tour."+this._options.name,function(a){if(a.which)switch(a.which){case 39:return a.preventDefault(),b._current<b._steps.length-1?b.next():b.end();case 37:if(a.preventDefault(),b._current>0)return b.prev();break;case 27:return a.preventDefault(),b.end()}}):void 0},c.prototype._makePromise=function(b){return b&&a.isFunction(b.then)?b:null},c.prototype._callOnPromiseDone=function(a,b,c){var d=this;return a?a.then(function(){return b.call(d,c)}):b.call(this,c)},c.prototype._showBackdrop=function(a){return null===this.backdrop.overlay?(this._showOverlay(),null!=a?this._showOverlayElement(a):void 0):void 0},c.prototype._hideBackdrop=function(){return null!==this.backdrop.overlay?(this.backdrop.$element&&this._hideOverlayElement(),this._hideOverlay()):void 0},c.prototype._showOverlay=function(){return this.backdrop=a("<div/>"),this.backdrop.addClass("tour-backdrop"),this.backdrop.height(a(d).innerHeight()),a("body").append(this.backdrop)},c.prototype._hideOverlay=function(){return this.backdrop.remove(),this.backdrop.overlay=null},c.prototype._showOverlayElement=function(b){var c,d,e;return d=a(b),c=a("<div/>"),e=d.offset(),e.top=e.top,e.left=e.left,c.width(d.innerWidth()).height(d.innerHeight()).addClass("tour-step-background").offset(e),d.addClass("tour-step-backdrop"),a("body").append(c),this.backdrop.$element=d,this.backdrop.$background=c},c.prototype._hideOverlayElement=function(){return this.backdrop.$element.removeClass("tour-step-backdrop"),this.backdrop.$background.remove(),this.backdrop.$element=null,this.backdrop.$background=null},c}(),b.Tour=c}(jQuery,window)}.call(this); \ No newline at end of file https://bitbucket.org/virtualcommons/vcweb/commits/f01a26231127/ Changeset: f01a26231127 User: alllee Date: 2013-09-06 01:14:25 Summary: cleaning up defunct lighterprints api endpoints Affected #: 2 files diff -r 8b6c2a3d6ac156809d293009adcc5969a8371f30 -r f01a26231127168eb0934265ca131551bd382372 vcweb/lighterprints/urls.py --- a/vcweb/lighterprints/urls.py +++ b/vcweb/lighterprints/urls.py @@ -1,13 +1,11 @@ from django.conf.urls.defaults import url, patterns -from django.views.generic.base import TemplateView from vcweb.lighterprints.views import (post_chat_message, post_comment, perform_activity, participate, - group_activity, like, get_notifications, update_notifications_since, group_score, CsvExportView, checkin, - activity_performed_counts, get_view_model, mobile_participate, mobile_login) + group_activity, like, group_score, CsvExportView, checkin, + get_view_model, mobile_participate, mobile_login) # handles all /lighterprints/* URL requests urlpatterns = patterns('vcweb.lighterprints.views', - url(r'^about$', TemplateView.as_view(template_name='lighterprints/about.html'), name='about'), url(r'^(?P<pk>\d+)/data$', CsvExportView.as_view(), name='export-data'), url(r'^(?P<experiment_id>\d+)/participate/?$', participate, name='participate'), url(r'^api/view-model/(?P<participant_group_id>\d+)?', get_view_model), @@ -17,10 +15,8 @@ url(r'^api/comment', post_comment), url(r'^api/like', like), url(r'^api/group-score/(?P<participant_group_id>\d+)', group_score), - url(r'^api/notifications/clear', update_notifications_since), - url(r'^api/notifications/(?P<participant_group_id>\d+)', get_notifications), url(r'^api/checkin', checkin), - url(r'^api/activity-performed-counts/(?P<participant_group_id>\d+)', activity_performed_counts), + # FIXME: hacky, replace mobile login with core api login instead url(r'^mobile/login?$', mobile_login, name='mobile_login'), url(r'^mobile/?$', mobile_participate, name='mobile_participate'), ) diff -r 8b6c2a3d6ac156809d293009adcc5969a8371f30 -r f01a26231127168eb0934265ca131551bd382372 vcweb/lighterprints/views.py --- a/vcweb/lighterprints/views.py +++ b/vcweb/lighterprints/views.py @@ -10,7 +10,7 @@ from vcweb.core import unicodecsv from vcweb.core.decorators import participant_required -from vcweb.core.forms import (ChatForm, CommentForm, LikeForm, ParticipantGroupIdForm, GeoCheckinForm, LoginForm) +from vcweb.core.forms import (ChatForm, CommentForm, LikeForm, GeoCheckinForm, LoginForm) from vcweb.core.http import JsonResponse from vcweb.core.models import (ChatMessage, Comment, Experiment, ParticipantGroupRelationship, ParticipantRoundDataValue, Like) from vcweb.core.services import foursquare_venue_search @@ -19,7 +19,7 @@ from vcweb.lighterprints.models import (Activity, get_all_activities_tuple, do_activity, get_group_activity, can_view_other_groups, get_lighterprints_experiment_metadata, is_experiment_completed, get_activity_performed_parameter, get_points_to_next_level, get_group_scores, get_group_score, get_footprint_level, - get_foursquare_category_ids, get_activity_performed_counts, get_time_remaining) + get_foursquare_category_ids, get_time_remaining) from collections import defaultdict from operator import itemgetter @@ -102,47 +102,6 @@ return JsonResponse(dumps({'success':False, 'message': 'Invalid authz request'})) @login_required -def update_notifications_since(request): - form = ParticipantGroupIdForm(request.POST or None) - if form.is_valid(): - participant_group_id = form.cleaned_data['participant_group_id'] - participant_group_relationship = get_object_or_404(ParticipantGroupRelationship, pk=participant_group_id) - if request.user.participant == participant_group_relationship.participant: - participant_group_relationship.notifications_since = datetime.now() - participant_group_relationship.save() - return JsonResponse(dumps({'success':True})) - else: - logger.warning("authenticated user %s tried to update notifications since for %s", request.user, participant_group_relationship) - return JsonResponse(dumps({'success':False, 'message': 'Invalid request'})) -''' -[(4, u'adjust-thermostat'), - (2, u'eat-local-lunch'), - (1, u'enable-sleep-on-computer'), - (5, u'recycle-materials'), - (3, u'share-your-ride'), - (10, u'bike-or-walk'), - (7, u'computer-off-night'), - (9, u'no-beef'), - (8, u'recycle-paper'), - (14, u'air-dry-clothes'), - (15, u'cold-water-wash'), - (13, u'eat-green-lunch'), - (11, u'lights-off'), - (12, u'vegan-for-a-day')] - ''' -@login_required -def activity_performed_counts(request, participant_group_id): - _activity_ids = (8, 3, 1, 9, 4, 15, 2, 5, 10, 7, 12, 11, 14, 13) - participant_group_relationship = get_object_or_404(ParticipantGroupRelationship, pk=participant_group_id) - if request.user.participant == participant_group_relationship.participant: - activity_performed_counts = get_activity_performed_counts(participant_group_relationship) - activity_counts_dict = defaultdict(int, [(d['int_value'], d['count']) for d in activity_performed_counts]) - activity_counts = [activity_counts_dict[activity_id] for activity_id in _activity_ids] - logger.debug("activity counts: %s", activity_counts) - return JsonResponse(dumps({'success': True, 'activity_counts': activity_counts})) - return JsonResponse(dumps({'success':False, 'message': 'Invalid request'})) - -@login_required def group_score(request, participant_group_id): participant_group_relationship = get_object_or_404(ParticipantGroupRelationship.objects.select_related('group'), pk=participant_group_id) if request.user.participant == participant_group_relationship.participant: Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-29 06:56:26
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/46261a37e221/ Changeset: 46261a37e221 User: alllee Date: 2013-08-29 08:56:11 Summary: enabling chat in practice rounds Affected #: 2 files diff -r 44c825adb701cdcefd0737e2ea12aff28dfcc4b8 -r 46261a37e2217eafce76ba1d151bd2cd9cf7fec0 vcweb/bound/views.py --- a/vcweb/bound/views.py +++ b/vcweb/bound/views.py @@ -137,7 +137,7 @@ experiment_model_dict['participantsPerGroup'] = ec.max_group_size experiment_model_dict['regrowthRate'] = regrowth_rate experiment_model_dict['initialResourceLevel'] = get_initial_resource_level(current_round) - if current_round.is_regular_round: + if current_round.is_playable_round: experiment_model_dict['chatEnabled'] = current_round.chat_enabled if current_round.is_debriefing_round: diff -r 44c825adb701cdcefd0737e2ea12aff28dfcc4b8 -r 46261a37e2217eafce76ba1d151bd2cd9cf7fec0 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -1141,12 +1141,10 @@ PRACTICE=(_('Practice round'), 'practice.html'), QUIZ=(_('Quiz round'), 'quiz.html')) ROUND_TYPES = (CHAT, DEBRIEFING, GENERAL_INSTRUCTIONS, INSTRUCTIONS, PRACTICE, QUIZ, REGULAR, WELCOME) = sorted(ROUND_TYPES_DICT.keys()) - RoundType = Choices(*[(round_type, ROUND_TYPES_DICT[round_type][0]) for round_type in ROUND_TYPES]) PLAYABLE_ROUND_CONFIGURATIONS = (RoundType.PRACTICE, RoundType.REGULAR) experiment_configuration = models.ForeignKey(ExperimentConfiguration, related_name='round_configuration_set') - sequence_number = models.PositiveIntegerField(help_text='Used internally to determine the ordering of the rounds in an experiment in ascending order, e.g., 1,2,3,4,5') display_number = models.PositiveIntegerField(default=0, help_text='The round number to be displayed with this round. If set to zero, defaults to the internally used sequence_number.') Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-27 21:50:34
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/44c825adb701/ Changeset: 44c825adb701 User: alllee Date: 2013-08-27 23:33:48 Summary: embedding youtube video via iframe API, still having cross origin issues Affected #: 1 file diff -r d2c7f2a6add98a6edd062b4389cbbefe92e4ea07 -r 44c825adb701cdcefd0737e2ea12aff28dfcc4b8 vcweb/bound/templates/bound/participate.html --- a/vcweb/bound/templates/bound/participate.html +++ b/vcweb/bound/templates/bound/participate.html @@ -312,8 +312,11 @@ highest sustainable amount that can be harvested, when the forest is at half its capacity, is 6 trees per individual or 24 trees per group. </p> -<div class='flex-video widescreen' id='bound-video-tutorial'> -<iframe width='640' height='480' src='//www.youtube.com/embed/eQ-N61ISpBc?rel=0&origin=https://vcweb.asu.edu' frameborder='0'></iframe> +<div class='flex-video widescreen'> +<div id='bound-video-tutorial' width='640' height='480'></div> +{% comment %} +<iframe id='bound-video-tutorial' src='//www.youtube.com/embed/eQ-N61ISpBc?rel=0&enablejsapi=1&origin=https://vcweb.asu.edu' frameborder='0' allowfullscreen></iframe> +{% endcomment %} </div><ul class='pager'><li class='previous'> @@ -552,6 +555,28 @@ </script><script src='{% static "js/bootstrap-tour.js" %}'></script><script type="text/javascript"> +// 3. This function creates an <iframe> (and YouTube player) +// after the API code downloads. +var youtubePlayer; +function onYouTubeIframeAPIReady() { + youtubePlayer = new YT.Player('bound-video-tutorial', { + videoId: 'eQ-N61ISpBc', + width: 640, + height: 480, + playerVars: { + rel: 0, + enablejsapi: 1, + origin: 'https://vcweb.asu.edu', + modestbranding: 1, + showinfo: 0 + }, + events: { + 'onReady': function(event) { + console.debug("youtube video tutorial ready"); + } + } + }); +} $(function() { function ExperimentModel(experimentModelJson) { var self = this; @@ -637,6 +662,13 @@ }); // activate instructions click bindings model.activateTemplate = function(name, experimentModel) { + if (name === "GENERAL_INSTRUCTIONS2") { + // XXX: set up youtube video iframe api asynchronously. Kinda ugly hacky. + var tag = document.createElement('script'); + tag.src = "//www.youtube.com/iframe_api"; + var firstScriptTag = document.getElementsByTagName('script')[0]; + firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); + } model.templateName(name); } model.practiceRoundSurveyCompleted = function() { Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-27 06:24:49
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/d2c7f2a6add9/ Changeset: d2c7f2a6add9 User: alllee Date: 2013-08-27 08:24:32 Summary: adding origin to youtube video to get rid of Chrome frame origin warnings Affected #: 1 file diff -r 76fac37933abf4364e60858922a7fe7ed21ea22a -r d2c7f2a6add98a6edd062b4389cbbefe92e4ea07 vcweb/bound/templates/bound/participate.html --- a/vcweb/bound/templates/bound/participate.html +++ b/vcweb/bound/templates/bound/participate.html @@ -282,9 +282,6 @@ could earn as much as <strong data-bind='text: formatCurrency(maxEarnings())'></strong> for the entire experiment. However, the final outcome depends on your choices and those of your group members. </p> -<p> -Instructional video placeholder. -</p><ul class='pager'><li class='next'><a href='javascript: void();' data-bind='click: activateTemplate.bind($data, "GENERAL_INSTRUCTIONS2")'>OK, I understand</a> @@ -315,8 +312,8 @@ highest sustainable amount that can be harvested, when the forest is at half its capacity, is 6 trees per individual or 24 trees per group. </p> -<div class='flex-video widescreen'> -<iframe width='640' height='480' src='//www.youtube.com/embed/eQ-N61ISpBc?rel=0' frameborder='0' allowfullscreen></iframe> +<div class='flex-video widescreen' id='bound-video-tutorial'> +<iframe width='640' height='480' src='//www.youtube.com/embed/eQ-N61ISpBc?rel=0&origin=https://vcweb.asu.edu' frameborder='0'></iframe></div><ul class='pager'><li class='previous'> Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-27 00:23:51
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/76fac37933ab/ Changeset: 76fac37933ab User: alllee Date: 2013-08-27 02:12:52 Summary: fixing typo and data conversion bug on final debriefing session storage and refining session storage display Affected #: 2 files diff -r 4e7b2c11ee46d9b0178a79ff4ecaee18814925cb -r 76fac37933abf4364e60858922a7fe7ed21ea22a vcweb/bound/templates/bound/participate.html --- a/vcweb/bound/templates/bound/participate.html +++ b/vcweb/bound/templates/bound/participate.html @@ -142,13 +142,13 @@ </iframe></div><h2>Payments</h2> - <table class='table'> + <table class='table table-bordered table-condensed'><thead><tr><th>Session 1</th><th>Session 2</th></tr></thead><tbody> - <tr><td><span data-bind='text: sessionOneStorage'></span><br><span data-bind='text: sessionOneEarnings'</span></td> - <td><span data-bind='text: sessionTwoStorage'></span><br><span data-bind='text: sessionTwoEarnings'></span></td> + <tr><td><span class='badge badge-success' data-bind='text: sessionOneStorage'></span><span class='text-success' data-bind='text: sessionOneEarnings'</span></td> + <td><span class='badge badge-success' data-bind='text: sessionTwoStorage'></span><span class='text-success' data-bind='text: sessionTwoEarnings'></span></td></tr></tbody></table> diff -r 4e7b2c11ee46d9b0178a79ff4ecaee18814925cb -r 76fac37933abf4364e60858922a7fe7ed21ea22a vcweb/bound/views.py --- a/vcweb/bound/views.py +++ b/vcweb/bound/views.py @@ -144,8 +144,8 @@ experiment_model_dict['totalHarvest'] = get_total_harvest(participant_group_relationship, current_round.session_id) if experiment.is_last_round: (session_one_storage, session_two_storage) = get_all_session_storages(experiment, participant_group_relationship.participant) - experiment_model_dict['sessionOneStorage'] = session_one_storage - experiment_model_dict['sessonTwoStorage'] = session_two_storage + experiment_model_dict['sessionOneStorage'] = session_one_storage.int_value + experiment_model_dict['sessionTwoStorage'] = session_two_storage.int_value if current_round.is_survey_enabled: query_parameters = urlencode({ Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-26 23:49:14
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/4e7b2c11ee46/ Changeset: 4e7b2c11ee46 User: alllee Date: 2013-08-27 01:49:02 Summary: fixing bug when regrowth parameter existed but was empty (need to access it via .value vs .int_value to get at the default value) fixing two bugs with final round get_all_session_storages - null isn't allowed in session_id anymore so we need to exclude empty session ids, and the query needs to use the participant as the key instead of the participant group relationship because in session 2 we have different randomized groups than session 1. Affected #: 3 files diff -r 1a3fcff9581b7e452097e350b90a756dbf7f57c5 -r 4e7b2c11ee46d9b0178a79ff4ecaee18814925cb vcweb/bound/models.py --- a/vcweb/bound/models.py +++ b/vcweb/bound/models.py @@ -167,16 +167,18 @@ dv = get_storage_dv(participant_group_relationship, round_data, default) return max(default if dv.int_value is None else dv.int_value, 0) -def get_all_session_storages(experiment, participant_group_relationship): +def get_all_session_storages(experiment, participant): + ''' + XXX: we query by participant because the participant group relationships will be different if we've re-randomized + their groups. + ''' debriefing_session_round_data = RoundData.objects.filter(experiment=experiment, - round_configuration__round_type=RoundConfiguration.RoundType.DEBRIEFING, - round_configuration__session_id__isnull=False) + round_configuration__round_type=RoundConfiguration.RoundType.DEBRIEFING).exclude(round_configuration__session_id=u'') return ParticipantRoundDataValue.objects.filter( - participant_group_relationship=participant_group_relationship, + participant_group_relationship__participant=participant, parameter=get_storage_parameter(), round_data__in=debriefing_session_round_data).order_by('date_created') - def _zero_if_none(value): return 0 if value is None else value diff -r 1a3fcff9581b7e452097e350b90a756dbf7f57c5 -r 4e7b2c11ee46d9b0178a79ff4ecaee18814925cb vcweb/bound/templates/bound/participate.html --- a/vcweb/bound/templates/bound/participate.html +++ b/vcweb/bound/templates/bound/participate.html @@ -649,7 +649,7 @@ model.clearCurrentInterval(); $('#content').removeClass('span12').addClass('span8'); $('#sidebar').show(); - model.activateTemplate("PAID_EXPERIMENT_INSTRUCTIONS"); + model.activateTemplate("PAID_EXPERIMENT_INSTRUCTIONS"); }; model.readyParticipantsPercentage = ko.computed(function() { return (model.readyParticipants() / model.participantCount()) * 100; diff -r 1a3fcff9581b7e452097e350b90a756dbf7f57c5 -r 4e7b2c11ee46d9b0178a79ff4ecaee18814925cb vcweb/bound/views.py --- a/vcweb/bound/views.py +++ b/vcweb/bound/views.py @@ -143,7 +143,7 @@ if current_round.is_debriefing_round: experiment_model_dict['totalHarvest'] = get_total_harvest(participant_group_relationship, current_round.session_id) if experiment.is_last_round: - (session_one_storage, session_two_storage) = get_all_session_storages(experiment, participant_group_relationship) + (session_one_storage, session_two_storage) = get_all_session_storages(experiment, participant_group_relationship.participant) experiment_model_dict['sessionOneStorage'] = session_one_storage experiment_model_dict['sessonTwoStorage'] = session_two_storage @@ -176,7 +176,7 @@ experiment_model_dict['playerData'] = player_data experiment_model_dict['averageHarvest'] = get_average_harvest(own_group, previous_round_data) experiment_model_dict['averageStorage'] = get_average_storage(own_group, current_round_data) - experiment_model_dict['regrowth'] = regrowth = get_regrowth_dv(own_group, current_round_data).int_value + regrowth = experiment_model_dict['regrowth'] = get_regrowth_dv(own_group, current_round_data).value c = Counter(map(itemgetter('alive'), experiment_model_dict['playerData'])) experiment_model_dict['numberAlive'] = "%s out of %s" % (c[True], sum(c.values())) # FIXME: refactor duplication between myGroup and otherGroup data loading Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-26 23:09:42
|
2 new commits in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/179889700b7e/ Changeset: 179889700b7e User: alllee Date: 2013-08-26 23:10:27 Summary: scaling images back down to 10x20 Affected #: 2 files diff -r 4eddd6b0a84fa3e6871f999202eef5d9e1fd1743 -r 179889700b7e81819a7dd66787ca71d353ee6f28 vcweb/bound/static/images/bound/tree-resource-new-growth.png Binary file vcweb/bound/static/images/bound/tree-resource-new-growth.png has changed diff -r 4eddd6b0a84fa3e6871f999202eef5d9e1fd1743 -r 179889700b7e81819a7dd66787ca71d353ee6f28 vcweb/bound/static/images/bound/tree-resource-old-growth.png Binary file vcweb/bound/static/images/bound/tree-resource-old-growth.png has changed https://bitbucket.org/virtualcommons/vcweb/commits/1a3fcff9581b/ Changeset: 1a3fcff9581b User: alllee Date: 2013-08-27 01:09:30 Summary: disambiguating original forest and regrowth in resource visualization, caching final sequence number to avoid count query every time we print out a sequence label, and removing defaultdicts from experiment model json as they don't prevent KO binding errors (defaultdicts don't work when serializing to json and then asking the json for a nonexistent value) Affected #: 4 files diff -r 179889700b7e81819a7dd66787ca71d353ee6f28 -r 1a3fcff9581b7e452097e350b90a756dbf7f57c5 vcweb/bound/models.py --- a/vcweb/bound/models.py +++ b/vcweb/bound/models.py @@ -3,11 +3,11 @@ from vcweb.core import signals, simplecache from vcweb.core.models import (DefaultValue, ExperimentMetadata, Parameter, ParticipantRoundDataValue, GroupRelationship, GroupCluster, GroupClusterDataValue, RoundData, RoundConfiguration) -from vcweb.forestry.models import (get_harvest_decision_parameter, get_harvest_decision, get_harvest_decision_dv, get_regrowth_rate_parameter, - get_group_harvest_parameter, get_reset_resource_level_parameter, get_resource_level as get_unshared_resource_level, - get_regrowth_parameter, set_resource_level, get_initial_resource_level_parameter, +from vcweb.forestry.models import (get_harvest_decision_parameter, get_harvest_decision, get_harvest_decision_dv, + get_group_harvest_parameter, get_reset_resource_level_parameter, + get_regrowth_parameter, get_initial_resource_level_parameter, get_resource_level_parameter, get_resource_level_dv as get_unshared_resource_level_dv, - set_group_harvest, get_group_harvest_dv, get_regrowth_dv, set_regrowth, set_harvest_decision) + get_group_harvest_dv, get_regrowth_dv, set_harvest_decision) from collections import defaultdict import logging diff -r 179889700b7e81819a7dd66787ca71d353ee6f28 -r 1a3fcff9581b7e452097e350b90a756dbf7f57c5 vcweb/bound/templates/bound/participate.html --- a/vcweb/bound/templates/bound/participate.html +++ b/vcweb/bound/templates/bound/participate.html @@ -453,20 +453,14 @@ </table></div></div> +{% comment %} resource visualization section {% endcomment %} <div class='row'><div data-bind='css: { span8: ! canObserveOtherGroup() }, template: { name: "resource-visualization-template" }'></div></div> +{% comment %} resource harvest decision section {% endcomment %} <div class='row' data-bind='ifnot: isResourceEmpty'><div class='span8'><h3 class='compact'>Harvest</h3> - {% comment %} - XXX: disabled - <div data-bind='if: submitHarvestDecisionEnabled'> - <div class='alert alert-success'> - <i class='icon-leaf'></i> You have currently <span data-bind='text: submitted ? "submitted" : "selected"'></span> a harvest decision of <span class='badge badge-info' data-bind='text: harvestDecision'></span> trees. Click the 'Ok I'm ready' button to continue. - </div> - </div> - {% endcomment %} <div data-bind='ifnot: alive'><div class='alert alert-error'><b><i class='icon-ambulance'></i></b> You didn't harvest enough trees to meet the cost of living and are now @@ -486,17 +480,20 @@ </script><script type='text/html' id='tree-template'> -<div data-bind="visible: isResourceEmpty"> +<div data-bind="visible: $data.isResourceEmpty"><div class='well'> - <center><img src="{% static 'images/bound/depleted-trees.jpg' %}" class="img-polaroid" width="425" - height="282"></center> + <center><img alt='depleted trees' src="{% static 'images/bound/depleted-trees.jpg' %}" class="img-polaroid" width="425" height="282"></center></div><div class='alert alert-error'><i class='icon-warning-sign'></i> There are no more trees to harvest. Please wait until the next round begins.</div></div><div data-bind='ifnot: isResourceEmpty'> -<div data-bind='style: { width: $root.blockResourceVisualizationImageWidth(resourceLevel), height: $root.blockResourceVisualizationImageHeight(resourceLevel), background: $root.resourceImageBackgroundUrl }'></div> +{% comment %} resource level visualization pre-regrowth {% endcomment %} +<div data-bind='style: { width: $root.blockResourceVisualizationImageWidth(originalResourceLevel), height: $root.blockResourceVisualizationImageHeight(originalResourceLevel), background: $root.resourceImageBackgroundUrl }'></div> {% comment %} FIXME: crummy use of "px" concatenation, use something like inPixels(..) instead? {% endcomment %} -<div data-bind='style: { width: $root.remainderResourceImageWidth(resourceLevel), height: $root.resourceImageHeight() + "px", background: $root.resourceImageBackgroundUrl }'></div> +<div data-bind='style: { width: $root.remainderResourceImageWidth(originalResourceLevel), height: $root.resourceImageHeightPx, background: $root.resourceImageBackgroundUrl }'></div> +{% comment %} regrowth resource visualization {% endcomment %} +<div data-bind='style: { width: $root.regrowthResourceImageWidth(regrowth), height: $root.resourceImageHeightPx, background: $root.regrowthResourceImageBackgroundUrl }'></div> + </div><br><table class='group-status table table-bordered table-condensed table-striped'> @@ -521,11 +518,9 @@ <h3 class='compact'>My Group</h3><div data-bind='template: { name: "tree-template", data: myGroup }'></div></div> -<div data-bind='if: canObserveOtherGroup'> - <div class='span4'> - <h3 class='compact'>Other Group</h3> - <div data-bind='template: {name: "tree-template", data: otherGroup }'></div> - </div> +<div data-bind='if: canObserveOtherGroup, css: { span4: canObserveOtherGroup }'> + <h3 class='compact'>Other Group</h3> + <div data-bind='template: {name: "tree-template", data: otherGroup }'></div></div></script><script type='text/html' id='harvest-decision-multiselect-template'> @@ -681,6 +676,9 @@ }); model.resourceImageWidth = ko.observable(10); model.resourceImageHeight = ko.observable(20); + model.resourceImageHeightPx = ko.computed(function() { + return model.resourceImageHeight() + "px"; + }); model.rowsToDisplay = function(resourceLevel) { return Math.floor(resourceLevel() / model.resourcesPerRow()); }; @@ -694,7 +692,11 @@ return 0; }); model.inactiveResourceImageUrl = ko.observable("{{STATIC_URL}}images/bound/tree-inactive.png"); - model.resourceImageBackgroundUrl = ko.observable("url('{{STATIC_URL}}images/bound/tree-resource.png')"); + model.resourceImageBackgroundUrl = ko.observable("url('{{STATIC_URL}}images/bound/tree-resource-old-growth.png')"); + model.regrowthResourceImageBackgroundUrl = ko.observable("url('{{STATIC_URL}}images/bound/tree-resource-new-growth.png')"); + model.regrowthResourceImageWidth = function(regrowth) { + return (model.regrowth() * model.resourceImageWidth()) + "px"; + } model.blockResourceVisualizationImageWidth = function(resourceLevel) { return (model.resourcesPerRow() * model.resourceImageWidth()) + "px"; }; @@ -866,6 +868,5 @@ } model = initialize($.parseJSON("{{ experimentModelJson|escapejs }}")); }); - var model; </script> {% endblock %} diff -r 179889700b7e81819a7dd66787ca71d353ee6f28 -r 1a3fcff9581b7e452097e350b90a756dbf7f57c5 vcweb/bound/views.py --- a/vcweb/bound/views.py +++ b/vcweb/bound/views.py @@ -8,9 +8,9 @@ from vcweb.core.models import (Experiment, ParticipantGroupRelationship, ChatMessage) from vcweb.bound.forms import SingleIntegerDecisionForm from vcweb.bound.models import (get_experiment_metadata, get_regrowth_rate, get_max_allowed_harvest_decision, - get_cost_of_living, get_resource_level, get_initial_resource_level, get_all_session_storages, + get_cost_of_living, get_resource_level, get_initial_resource_level, get_all_session_storages, get_harvest_decision_dv, set_harvest_decision, can_observe_other_group, get_average_harvest, - get_average_storage, get_total_harvest, get_number_alive, get_player_data) + get_average_storage, get_total_harvest, get_number_alive, get_player_data, get_regrowth_dv) from urllib import urlencode import logging @@ -76,8 +76,24 @@ 'roundDuration': 60, 'chatMessages': [], 'canObserveOtherGroup': False, - 'myGroup': defaultdict(int), - 'otherGroup': defaultdict(int), + 'myGroup': { + 'resourceLevel': 0, + 'regrowth': 0, + 'originalResourceLevel': 0, + 'averageHarvest': 0, + 'averageStorage': 0, + 'numberAlive': 0, + 'isResourceEmpty': 0, + }, + 'otherGroup': { + 'resourceLevel': 0, + 'regrowth': 0, + 'originalResourceLevel': 0, + 'averageHarvest': 0, + 'averageStorage': 0, + 'numberAlive': 0, + 'isResourceEmpty': 0, + }, 'selectedHarvestDecision': False, 'isInstructionsRound': False, 'waitThirtySeconds': False, @@ -91,6 +107,7 @@ 'numberAlive': '4 out of 4', 'isSurveyEnabled': False, 'surveyCompleted': False, + 'regrowth': 0, 'surveyUrl': 'http://survey.qualtrics.com/SE/?SID=SV_0vzmIj5UsOgjoTX', } # FIXME: bloated method with too many special cases, try to refactor @@ -159,10 +176,14 @@ experiment_model_dict['playerData'] = player_data experiment_model_dict['averageHarvest'] = get_average_harvest(own_group, previous_round_data) experiment_model_dict['averageStorage'] = get_average_storage(own_group, current_round_data) + experiment_model_dict['regrowth'] = regrowth = get_regrowth_dv(own_group, current_round_data).int_value c = Counter(map(itemgetter('alive'), experiment_model_dict['playerData'])) experiment_model_dict['numberAlive'] = "%s out of %s" % (c[True], sum(c.values())) +# FIXME: refactor duplication between myGroup and otherGroup data loading experiment_model_dict['myGroup'] = { 'resourceLevel': own_resource_level, + 'regrowth': regrowth, + 'originalResourceLevel': own_resource_level - regrowth, 'averageHarvest': experiment_model_dict['averageHarvest'], 'averageStorage': experiment_model_dict['averageStorage'], 'numberAlive': experiment_model_dict['numberAlive'], @@ -186,8 +207,11 @@ other_group = own_group.get_related_group() number_alive = get_number_alive(other_group, current_round_data) resource_level = get_resource_level(other_group, current_round_data) + regrowth = get_regrowth_dv(other_group, current_round_data).int_value experiment_model_dict['otherGroup'] = { + 'regrowth': regrowth, 'resourceLevel': resource_level, + 'originalResourceLevel': resource_level - regrowth, 'averageHarvest': get_average_harvest(other_group, previous_round_data), 'averageStorage': get_average_storage(other_group, current_round_data), 'numberAlive': "%s out of %s" % (number_alive, other_group.size), diff -r 179889700b7e81819a7dd66787ca71d353ee6f28 -r 1a3fcff9581b7e452097e350b90a756dbf7f57c5 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -279,6 +279,7 @@ Experimenter driven experiments have checkpoints where the experimenter needs to explicitly signal the system to move to the next round or stage. """ + cached_final_sequence_number = 0 @property def is_open(self): @@ -300,8 +301,11 @@ @property def final_sequence_number(self): - # FIXME doesn't work with repeating rounds, also doesn't work well with degenerate data (e.g., manual sequence numbers > count) - return self.round_configuration_set.count() + # FIXME brittle with degenerate round configurations, (e.g., if round configuration sequence numbers are out of sync and > count) + cfsn = self.cached_final_sequence_number + if cfsn == 0: + self.cached_final_sequence_number = cfsn = self.round_configuration_set.count() + return cfsn @property def last_round_sequence_number(self): @@ -461,7 +465,8 @@ def sequence_label(self): cr = self.current_round if cr.is_repeating_round: - return u"Round %s (repeating round %d of %d)" % (self.current_round_sequence_number, + return u"Round %s/%s (repeating round %d of %d)" % (self.current_round_sequence_number, + self.experiment_configuration.final_sequence_number, self.current_repeated_round_sequence_number + 1, cr.repeat) else: return u"Round %s" % cr.sequence_label Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-23 22:01:45
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/4eddd6b0a84f/ Changeset: 4eddd6b0a84f User: alllee Date: 2013-08-24 00:01:34 Summary: fixing round data ordering for repeating rounds Affected #: 1 file diff -r e8b982679135f4e6f429759f19675940409c5f75 -r 4eddd6b0a84fa3e6871f999202eef5d9e1fd1743 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -1798,7 +1798,7 @@ return u"Round data %s" % self.round_configuration.sequence_label class Meta: - ordering = [ 'round_configuration' ] + ordering = [ 'round_configuration', 'repeating_round_sequence_number' ] unique_together = (('round_configuration', 'repeating_round_sequence_number', 'experiment'),) class GroupClusterDataValue(ParameterizedValue): Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-21 07:44:44
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/e8b982679135/ Changeset: e8b982679135 User: alllee Date: 2013-08-21 09:44:33 Summary: fixing observe other group UI and using defaultdicts for my group / other group data initially Affected #: 3 files diff -r aad901a1d430824cae6846f4c0156389bfaa2bb0 -r e8b982679135f4e6f429759f19675940409c5f75 fabfile.py --- a/fabfile.py +++ b/fabfile.py @@ -141,9 +141,6 @@ def server(ip="127.0.0.1", port=8000): local("{python} manage.py runserver {ip}:{port}".format(python=env.python, **locals()), capture=False) -def push(): - local('hg push ssh://hg...@bi.../virtualcommons/vcweb') - def dev(): env.project_path = env.deploy_path + env.project_name env.hosts =['sod51.asu.edu'] @@ -185,7 +182,6 @@ def deploy(): from vcweb import settings as vcweb_settings """ deploys to an already setup environment """ - push() if confirm("Deploy to %(hosts)s ?" % env): with cd(env.project_path): sudo_chain( diff -r aad901a1d430824cae6846f4c0156389bfaa2bb0 -r e8b982679135f4e6f429759f19675940409c5f75 vcweb/bound/templates/bound/participate.html --- a/vcweb/bound/templates/bound/participate.html +++ b/vcweb/bound/templates/bound/participate.html @@ -486,7 +486,6 @@ </script><script type='text/html' id='tree-template'> -<div class='alert alert-message'><strong class='badge badge-success' data-bind='text:resourceLevel'></strong> trees</div><div data-bind="visible: isResourceEmpty"><div class='well'><center><img src="{% static 'images/bound/depleted-trees.jpg' %}" class="img-polaroid" width="425" @@ -502,7 +501,7 @@ <br><table class='group-status table table-bordered table-condensed table-striped'><tbody> - <tr><td>forest</td><td data-bind='text:resourceLevel'></td></tr> + <tr><td>forest</td><td><strong class='badge badge-success' data-bind='text:resourceLevel'></strong> trees</td></tr><tr><td>average harvest</td><td data-bind='text:averageHarvest().toFixed(1)'></td></tr><tr><td>average earnings</td><td data-bind='text:Math.max(0, averageStorage().toFixed(1))'></td></tr><tr><td>number alive</td><td data-bind='text:numberAlive'></td></tr> @@ -521,9 +520,10 @@ <div data-bind='css: { span4: canObserveOtherGroup }'><h3 class='compact'>My Group</h3><div data-bind='template: { name: "tree-template", data: myGroup }'></div> +</div><div data-bind='if: canObserveOtherGroup'><div class='span4'> - <h4>Other Group</h4> + <h3 class='compact'>Other Group</h3><div data-bind='template: {name: "tree-template", data: otherGroup }'></div></div></div> @@ -679,8 +679,8 @@ return 77; } }); - model.resourceImageWidth = ko.observable(11); - model.resourceImageHeight = ko.observable(21); + model.resourceImageWidth = ko.observable(10); + model.resourceImageHeight = ko.observable(20); model.rowsToDisplay = function(resourceLevel) { return Math.floor(resourceLevel() / model.resourcesPerRow()); }; diff -r aad901a1d430824cae6846f4c0156389bfaa2bb0 -r e8b982679135f4e6f429759f19675940409c5f75 vcweb/bound/views.py --- a/vcweb/bound/views.py +++ b/vcweb/bound/views.py @@ -1,4 +1,4 @@ -from collections import Counter +from collections import Counter, defaultdict from operator import itemgetter from django.http import Http404 from django.shortcuts import render, get_object_or_404 @@ -76,8 +76,8 @@ 'roundDuration': 60, 'chatMessages': [], 'canObserveOtherGroup': False, - 'myGroup': {}, - 'otherGroup': {}, + 'myGroup': defaultdict(int), + 'otherGroup': defaultdict(int), 'selectedHarvestDecision': False, 'isInstructionsRound': False, 'waitThirtySeconds': False, Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-21 06:55:47
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/aad901a1d430/ Changeset: aad901a1d430 User: alllee Date: 2013-08-21 08:55:36 Summary: adding isResourceEmpty to group client data model and clearing out round data when restarting an experiment Affected #: 3 files diff -r 160e53d1405633f05fe12371779f3e48a6bb7a55 -r aad901a1d430824cae6846f4c0156389bfaa2bb0 vcweb/bound/templates/bound/participate.html --- a/vcweb/bound/templates/bound/participate.html +++ b/vcweb/bound/templates/bound/participate.html @@ -456,7 +456,7 @@ <div class='row'><div data-bind='css: { span8: ! canObserveOtherGroup() }, template: { name: "resource-visualization-template" }'></div></div> -<div class='row' data-bind='ifnot: isResourceEmpty()'> +<div class='row' data-bind='ifnot: isResourceEmpty'><div class='span8'><h3 class='compact'>Harvest</h3> {% comment %} diff -r 160e53d1405633f05fe12371779f3e48a6bb7a55 -r aad901a1d430824cae6846f4c0156389bfaa2bb0 vcweb/bound/views.py --- a/vcweb/bound/views.py +++ b/vcweb/bound/views.py @@ -165,7 +165,8 @@ 'resourceLevel': own_resource_level, 'averageHarvest': experiment_model_dict['averageHarvest'], 'averageStorage': experiment_model_dict['averageStorage'], - 'numberAlive': experiment_model_dict['numberAlive'] + 'numberAlive': experiment_model_dict['numberAlive'], + 'isResourceEmpty': own_resource_level == 0, } experiment_model_dict['resourceLevel'] = own_resource_level @@ -184,11 +185,13 @@ experiment_model_dict['canObserveOtherGroup'] = True other_group = own_group.get_related_group() number_alive = get_number_alive(other_group, current_round_data) + resource_level = get_resource_level(other_group, current_round_data) experiment_model_dict['otherGroup'] = { - 'resourceLevel': get_resource_level(other_group, current_round_data), + 'resourceLevel': resource_level, 'averageHarvest': get_average_harvest(other_group, previous_round_data), 'averageStorage': get_average_storage(other_group, current_round_data), 'numberAlive': "%s out of %s" % (number_alive, other_group.size), + 'isResourceEmpty': resource_level == 0, } return dumps(experiment_model_dict) diff -r 160e53d1405633f05fe12371779f3e48a6bb7a55 -r aad901a1d430824cae6846f4c0156389bfaa2bb0 vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -1012,8 +1012,9 @@ return self def restart(self): - self.log("Restarting experiment entirely from the first round.") + self.log("Restarting experiment entirely from the first round and clearing out all existing data.") self.deactivate() + self.round_data_set.all().delete() self.current_round_sequence_number = 1 self.activate() self.start_round() Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-20 08:52:04
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/160e53d14056/ Changeset: 160e53d14056 User: alllee Date: 2013-08-20 10:51:50 Summary: templatizing resource visualization, still need to distinguish between regrowth and 'old' growth Affected #: 2 files diff -r cbddb8498f4c74542c8bdb4569ca1e6b891fc50a -r 160e53d1405633f05fe12371779f3e48a6bb7a55 vcweb/bound/templates/bound/participate.html --- a/vcweb/bound/templates/bound/participate.html +++ b/vcweb/bound/templates/bound/participate.html @@ -484,16 +484,8 @@ </div></div></script> -<script type='text/html' id='resource-visualization-template'> -<div data-bind='if: isPracticeRound'> - <div class='alert alert-error alert-block'> - <h4>PRACTICE ROUND</h4> - This is a practice round. The decisions you make in this round will <b>NOT</b> contribute to your earnings. - </div> -</div> -<div data-bind='css: { span4: canObserveOtherGroup }'> -<h3 class='compact'>My Group</h3> +<script type='text/html' id='tree-template'><div class='alert alert-message'><strong class='badge badge-success' data-bind='text:resourceLevel'></strong> trees</div><div data-bind="visible: isResourceEmpty"><div class='well'> @@ -503,9 +495,9 @@ <div class='alert alert-error'><i class='icon-warning-sign'></i> There are no more trees to harvest. Please wait until the next round begins.</div></div><div data-bind='ifnot: isResourceEmpty'> -<div data-bind='style: { width: blockResourceVisualizationImageWidth(resourceLevel), height: blockResourceVisualizationImageHeight(resourceLevel), background: resourceImageBackgroundUrl }'></div> +<div data-bind='style: { width: $root.blockResourceVisualizationImageWidth(resourceLevel), height: $root.blockResourceVisualizationImageHeight(resourceLevel), background: $root.resourceImageBackgroundUrl }'></div> {% comment %} FIXME: crummy use of "px" concatenation, use something like inPixels(..) instead? {% endcomment %} -<div data-bind='style: { width: remainderResourceImageWidth(resourceLevel), height: resourceImageHeight() + "px", background: resourceImageBackgroundUrl }'></div> +<div data-bind='style: { width: $root.remainderResourceImageWidth(resourceLevel), height: $root.resourceImageHeight() + "px", background: $root.resourceImageBackgroundUrl }'></div></div><br><table class='group-status table table-bordered table-condensed table-striped'> @@ -517,31 +509,22 @@ </tbody></table></div> +</script> +<script type='text/html' id='resource-visualization-template'> +<div data-bind='if: isPracticeRound'> + <div class='alert alert-error alert-block'> + <h4>PRACTICE ROUND</h4> + This is a practice round. The decisions you make in this round will <b>NOT</b> contribute to your earnings. + </div> +</div> +<div data-bind='css: { span4: canObserveOtherGroup }'> +<h3 class='compact'>My Group</h3> +<div data-bind='template: { name: "tree-template", data: myGroup }'></div><div data-bind='if: canObserveOtherGroup'><div class='span4'><h4>Other Group</h4> - <div class='alert alert-message'><strong class='badge badge-success' data-bind='text:otherGroupResourceLevel'></strong> trees</div> - <div data-bind="visible: isResourceEmpty"> - <div class='well'> - <center><img alt='deforested' src="{% static 'images/forestry/deforestation.jpg' %}" class="img-polaroid" width="425" height="282"></center> - </div> - <div class='alert alert-error'><i class='icon-warning-sign'></i> There are no more trees to harvest.</div> - </div> - <div data-bind='ifnot: isResourceEmpty'> - <div data-bind='style: { width: blockResourceVisualizationImageWidth(otherGroupResourceLevel), height: blockResourceVisualizationImageHeight(otherGroupResourceLevel), background: resourceImageBackgroundUrl }'></div> - {% comment %} FIXME: crummy use of "px" concatenation, use something like inPixels(..) instead? {% endcomment %} - <div data-bind='style: { width: remainderResourceImageWidth(otherGroupResourceLevel), height: resourceImageHeight() + "px", background: resourceImageBackgroundUrl }'></div> - </div> - <br> - <table class='table table-bordered table-condensed table-striped'> - <tbody> - <tr><td>forest</td><td data-bind='text:otherGroupResourceLevel'></td></tr> - <tr><td>average harvest</td><td data-bind='text:otherGroupAverageHarvest().toFixed(1)'></td></tr> - <tr><td>average earnings</td><td data-bind='text:Math.max(0, otherGroupAverageStorage().toFixed(1))'></td></tr> - <tr><td>number alive</td><td data-bind='text:otherGroupNumberAlive'></td></tr> - </tbody> - </table> + <div data-bind='template: {name: "tree-template", data: otherGroup }'></div></div></div></script> @@ -696,8 +679,8 @@ return 77; } }); - model.resourceImageWidth = ko.observable(10); - model.resourceImageHeight = ko.observable(20); + model.resourceImageWidth = ko.observable(11); + model.resourceImageHeight = ko.observable(21); model.rowsToDisplay = function(resourceLevel) { return Math.floor(resourceLevel() / model.resourcesPerRow()); }; diff -r cbddb8498f4c74542c8bdb4569ca1e6b891fc50a -r 160e53d1405633f05fe12371779f3e48a6bb7a55 vcweb/bound/views.py --- a/vcweb/bound/views.py +++ b/vcweb/bound/views.py @@ -76,10 +76,8 @@ 'roundDuration': 60, 'chatMessages': [], 'canObserveOtherGroup': False, - 'otherGroupResourceLevel': 0, - 'otherGroupAverageHarvest': 0, - 'otherGroupAverageStorage': 0, - 'otherGroupNumberAlive': '4 out of 4', + 'myGroup': {}, + 'otherGroup': {}, 'selectedHarvestDecision': False, 'isInstructionsRound': False, 'waitThirtySeconds': False, @@ -163,7 +161,15 @@ experiment_model_dict['averageStorage'] = get_average_storage(own_group, current_round_data) c = Counter(map(itemgetter('alive'), experiment_model_dict['playerData'])) experiment_model_dict['numberAlive'] = "%s out of %s" % (c[True], sum(c.values())) + experiment_model_dict['myGroup'] = { + 'resourceLevel': own_resource_level, + 'averageHarvest': experiment_model_dict['averageHarvest'], + 'averageStorage': experiment_model_dict['averageStorage'], + 'numberAlive': experiment_model_dict['numberAlive'] + } + experiment_model_dict['resourceLevel'] = own_resource_level + # participant group data parameters are only needed if this round is a data round or the previous round was a data round if previous_round.is_playable_round or current_round.is_playable_round: harvest_decision = get_harvest_decision_dv(participant_group_relationship, current_round_data) @@ -177,10 +183,12 @@ if can_observe_other_group(current_round): experiment_model_dict['canObserveOtherGroup'] = True other_group = own_group.get_related_group() - experiment_model_dict['otherGroupResourceLevel'] = get_resource_level(other_group, current_round_data) - experiment_model_dict['otherGroupAverageHarvest'] = get_average_harvest(other_group, previous_round_data) - experiment_model_dict['otherGroupAverageStorage'] = get_average_storage(other_group, current_round_data) number_alive = get_number_alive(other_group, current_round_data) - experiment_model_dict['otherGroupNumberAlive'] = "%s out of %s" % (number_alive, other_group.size) + experiment_model_dict['otherGroup'] = { + 'resourceLevel': get_resource_level(other_group, current_round_data), + 'averageHarvest': get_average_harvest(other_group, previous_round_data), + 'averageStorage': get_average_storage(other_group, current_round_data), + 'numberAlive': "%s out of %s" % (number_alive, other_group.size), + } return dumps(experiment_model_dict) Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-16 23:02:34
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/cbddb8498f4c/ Changeset: cbddb8498f4c User: alllee Date: 2013-08-17 01:02:25 Summary: improving performance & emitting improved group membership and round data for issue #116 Affected #: 2 files diff -r 64ca47ecc72f84b48efc756c79c8065903aa7964 -r cbddb8498f4c74542c8bdb4569ca1e6b891fc50a vcweb/core/models.py --- a/vcweb/core/models.py +++ b/vcweb/core/models.py @@ -1781,9 +1781,10 @@ @property def round_number(self): - round_number = self.round_configuration.round_number - if self.round_configuration.is_repeating_round: - return "%s.%s" % (round_number, self.repeating_round_sequence_number) + rc = self.round_configuration + round_number = rc.round_number + if rc.is_repeating_round: + return "%s.%s" % (round_number, self.repeating_round_sequence_number + 1) else: return round_number @property @@ -1792,8 +1793,8 @@ def __unicode__(self): if self.round_configuration.is_repeating_round: - return u"Round data for %s (repeat #%d)" % (self.round_configuration, self.repeating_round_sequence_number) - return u"Data for round %s" % self.round_configuration + return u"Repeating round data %s.%s" % (self.round_configuration.sequence_number, self.repeating_round_sequence_number) + return u"Round data %s" % self.round_configuration.sequence_label class Meta: ordering = [ 'round_configuration' ] diff -r 64ca47ecc72f84b48efc756c79c8065903aa7964 -r cbddb8498f4c74542c8bdb4569ca1e6b891fc50a vcweb/core/views.py --- a/vcweb/core/views.py +++ b/vcweb/core/views.py @@ -464,29 +464,30 @@ response = HttpResponse(content_type=content_type) response['Content-Disposition'] = 'attachment; filename=%s' % experiment.data_file_name() writer = UnicodeWriter(response) - writer.writerow(['Group', 'Members']) - for group in experiment.group_set.all(): - writer.writerow(itertools.chain.from_iterable([["%s (PK: %s)" % (group, group.pk)], group.participant_set.all()])) -# write out round parameter value tuples - writer.writerow(['Round', 'Participant ID', 'Participant Number', 'Group', 'Data Parameter', 'Data Parameter Value', 'Created On', 'Last Modified']) - for round_data in experiment.round_data_set.all(): - round_configuration = round_data.round_configuration - # write out participant data values +# emit participant data (pk, email) in each group + writer.writerow(['Group ID', 'Group Number', 'Session ID', 'Participant ID', 'Participant Email']) + for group in experiment.group_set.order_by('pk').all(): + for pgr in group.participant_group_relationship_set.select_related('participant__user').all(): + writer.writerow([group.pk, group.number, group.session_id, pgr.pk, pgr.participant.email]) +# emit participant and group round data value tuples + writer.writerow(['Round', 'Participant ID', 'Participant Number', 'Group ID', 'Data Parameter', 'Data Parameter Value', 'Created On', 'Last Modified']) + for round_data in experiment.round_data_set.select_related('round_configuration').all(): + # emit all participant data values for data_value in round_data.participant_data_value_set.select_related('participant_group_relationship__group').all(): pgr = data_value.participant_group_relationship - writer.writerow([round_configuration, pgr.pk, pgr.participant_number, pgr.group, data_value.parameter.label, + writer.writerow([round_data.round_number, pgr.pk, pgr.participant_number, pgr.group.pk, data_value.parameter.label, data_value.value, data_value.date_created, data_value.last_modified]) - # write out all chat messages as a side bar + # write out all chat messages chat_messages = ChatMessage.objects.filter(round_data=round_data) if chat_messages.count() > 0: for chat_message in chat_messages.order_by('participant_group_relationship__group', 'date_created'): pgr = chat_message.participant_group_relationship - writer.writerow([round_configuration, pgr.pk, pgr.participant_number, pgr.group, "Chat Message", chat_message.string_value, + writer.writerow([round_data.round_number, pgr.pk, pgr.participant_number, pgr.group.pk, "Chat Message", chat_message.string_value, chat_message.date_created, chat_message.last_modified]) # write out group round data logger.debug("writing out group round data") for data_value in round_data.group_data_value_set.select_related('group').all(): - writer.writerow([round_configuration, '', '', data_value.group, data_value.parameter.label, + writer.writerow([round_data.round_number, '', '', data_value.group.pk, data_value.parameter.label, data_value.value, data_value.date_created, data_value.last_modified]) return response Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-16 01:25:49
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/64ca47ecc72f/ Changeset: 64ca47ecc72f User: alllee Date: 2013-08-16 03:25:38 Summary: fixing archived experiments list in experimenter dashboard Affected #: 2 files diff -r 74873718fd7834e2e47a0300f15d550d99b6677a -r 64ca47ecc72f84b48efc756c79c8065903aa7964 vcweb/core/views.py --- a/vcweb/core/views.py +++ b/vcweb/core/views.py @@ -98,7 +98,7 @@ experiment_status_dict[e.status].append(e.to_dict(attrs=('monitor_url', 'status_line', 'controller_url'))) pending_experiments = experiment_status_dict['INACTIVE'] running_experiments = experiment_status_dict['ACTIVE'] + experiment_status_dict['ROUND_IN_PROGRESS'] - archived_experiments = experiment_status_dict['ARCHIVED'] + archived_experiments = experiment_status_dict['COMPLETED'] data = { 'experimentMetadataList': experiment_metadata_list, 'pendingExperiments': pending_experiments, diff -r 74873718fd7834e2e47a0300f15d550d99b6677a -r 64ca47ecc72f84b48efc756c79c8065903aa7964 vcweb/lighterprints/models.py --- a/vcweb/lighterprints/models.py +++ b/vcweb/lighterprints/models.py @@ -199,7 +199,7 @@ return cv def __unicode__(self): - return u'%s' % self.label + return u'%s: %s' % (self.label, self.points) class Meta: ordering = ['level', 'name'] Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-16 01:22:12
|
2 new commits in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/2636f97d97e3/ Changeset: 2636f97d97e3 User: alllee Date: 2013-08-15 22:25:55 Summary: adding new growth / old growth tree resource images (still need to be adjusted to be 10x20 though) Affected #: 2 files diff -r a46df313c42fd93673956bb08a2dd09f2f84ffb3 -r 2636f97d97e3d8476cefc6c97d362380fe061a57 vcweb/bound/static/images/bound/tree-resource-new-growth.png Binary file vcweb/bound/static/images/bound/tree-resource-new-growth.png has changed diff -r a46df313c42fd93673956bb08a2dd09f2f84ffb3 -r 2636f97d97e3d8476cefc6c97d362380fe061a57 vcweb/bound/static/images/bound/tree-resource-old-growth.png Binary file vcweb/bound/static/images/bound/tree-resource-old-growth.png has changed https://bitbucket.org/virtualcommons/vcweb/commits/74873718fd78/ Changeset: 74873718fd78 User: alllee Date: 2013-08-16 03:02:33 Summary: adjusting data download format for issue 116 Affected #: 1 file diff -r 2636f97d97e3d8476cefc6c97d362380fe061a57 -r 74873718fd7834e2e47a0300f15d550d99b6677a vcweb/core/views.py --- a/vcweb/core/views.py +++ b/vcweb/core/views.py @@ -459,28 +459,36 @@ if experiment.experimenter != request.user.experimenter: logger.warning("unauthorized access to %s from %s", experiment, request.user.experimenter) raise PermissionDenied("You don't have access to this experiment") - response = HttpResponse(content_type=mimetypes.types_map['.%s' % file_type]) + content_type = mimetypes.types_map['.%s' % file_type] + logger.debug("Downloading data as %s", content_type) + response = HttpResponse(content_type=content_type) response['Content-Disposition'] = 'attachment; filename=%s' % experiment.data_file_name() writer = UnicodeWriter(response) writer.writerow(['Group', 'Members']) for group in experiment.group_set.all(): - writer.writerow(itertools.chain.from_iterable([[group], group.participant_set.all()])) + writer.writerow(itertools.chain.from_iterable([["%s (PK: %s)" % (group, group.pk)], group.participant_set.all()])) +# write out round parameter value tuples + writer.writerow(['Round', 'Participant ID', 'Participant Number', 'Group', 'Data Parameter', 'Data Parameter Value', 'Created On', 'Last Modified']) for round_data in experiment.round_data_set.all(): round_configuration = round_data.round_configuration - # write out group-wide and participant data values - writer.writerow(['Owner', 'Round', 'Data Parameter', 'Data Parameter Value', 'Created On', 'Last Modified']) - for data_value in itertools.chain(round_data.group_data_value_set.all(), round_data.participant_data_value_set.all()): - writer.writerow([data_value.owner, round_configuration, data_value.parameter.label, + # write out participant data values + for data_value in round_data.participant_data_value_set.select_related('participant_group_relationship__group').all(): + pgr = data_value.participant_group_relationship + writer.writerow([round_configuration, pgr.pk, pgr.participant_number, pgr.group, data_value.parameter.label, data_value.value, data_value.date_created, data_value.last_modified]) # write out all chat messages as a side bar chat_messages = ChatMessage.objects.filter(round_data=round_data) if chat_messages.count() > 0: - # sort by group first, then time - writer.writerow(['Chat Messages']) - writer.writerow(['Group', 'Participant', 'Message', 'Time', 'Round']) for chat_message in chat_messages.order_by('participant_group_relationship__group', 'date_created'): - writer.writerow([chat_message.group, chat_message.participant, chat_message.message, - chat_message.date_created, round_configuration]) + pgr = chat_message.participant_group_relationship + writer.writerow([round_configuration, pgr.pk, pgr.participant_number, pgr.group, "Chat Message", chat_message.string_value, + chat_message.date_created, chat_message.last_modified]) + # write out group round data + logger.debug("writing out group round data") + for data_value in round_data.group_data_value_set.select_related('group').all(): + writer.writerow([round_configuration, '', '', data_value.group, data_value.parameter.label, + data_value.value, data_value.date_created, data_value.last_modified]) + return response @experimenter_required Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: <com...@bi...> - 2013-08-12 23:17:34
|
1 new commit in vcweb: https://bitbucket.org/virtualcommons/vcweb/commits/a46df313c42f/ Changeset: a46df313c42f User: alllee Date: 2013-08-13 01:17:26 Summary: replacing experiment.group_set with experiment.groups to avoid pulling previous session's participant group relationships Affected #: 1 file diff -r 34ee1f421763cde41e10e8de43fb70dd7451ba3d -r a46df313c42fd93673956bb08a2dd09f2f84ffb3 vcweb/vcweb-sockjs.py --- a/vcweb/vcweb-sockjs.py +++ b/vcweb/vcweb-sockjs.py @@ -163,8 +163,7 @@ logger.warning("caught key error %s while trying to remove participant connection %s", connection, k) ''' - Generator function that yields (participant_group_relationship_id, connection) tuples - for the given group + Generator function that yields active (participant_group_relationship_id, connection) tuples for the given group ''' def connections(self, group): experiment = group.experiment @@ -181,7 +180,7 @@ def all_participants(self, experimenter, experiment): experimenter_key = (experimenter.pk, experiment.pk) if experimenter_key in self.experimenter_to_connection: - for group in experiment.group_set.all(): + for group in experiment.groups: for participant_group_relationship_id, connection in self.connections(group): yield (participant_group_relationship_id, connection) else: Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |