Skip to content

Instantly share code, notes, and snippets.

@cyingfan
Last active May 29, 2021 11:13
Show Gist options
  • Save cyingfan/b1e0a2fd44675b94ae2da2fb61fa4f3c to your computer and use it in GitHub Desktop.
Save cyingfan/b1e0a2fd44675b94ae2da2fb61fa4f3c to your computer and use it in GitHub Desktop.
Cure to Golden Ratio OCD on Humble Bundle

Set the humble bundle payment portions to follow golden ratio

TLDR

  1. Copy paste the content from bundlecalculator.min.js into developer console.
  2. Run set_ratio(15). Replace 15 to any figure you wish to pay.

Additional parameters

Disable full allocation to user selected charity

Enabled by default. To disable the behaviour, set second parameter to false, e.g. set_ratio(15, false).

Show debug

Disabled by default. To enable debug message, set third parameter to true set_ratio(15, false, true).

Changing the distribution

The default order from highest to lowest is: Developer/Publisher, Charity, Humble Bundle. If you wish to change it to for example, Charity, Developer/Publisher, Humble Bundle; run set_ratio(15, false, false, 1, 0, 2)

const get_golden_ratio = (target, ...order) => {
const sumFunc = (a, b) => a + b;
const round2 = x => Math.round(100 * x) / 100;
const roundLargestRemainder = (numbers = [], target = 100) => {
let offBy = target - numbers.reduce((acc, x) => acc + round2(x) , 0);
let length = numbers.length;
return numbers
.map((v, i) => ({value: v, index: i}))
.sort((a, b) => (round2(a.value) - a.value) - (round2(b.value) - b.value))
.map((x, i) => {
x.value = round2(x.value) + (offBy > i) - (i >= (length + offBy));
return x;
})
.reduce((acc, x) => {
acc[x.index] = x.value;
return acc;
}, {});
};
const phi = 1.6180339887498948482;
const len = order.length;
const results = new Array(len);
const ratios = order.map((_, i) => Math.pow(phi, len - i));
const ratioSum = ratios.reduce(sumFunc, 0);
const rawValues = ratios.map((v, i) => v * target / ratioSum);
const values = roundLargestRemainder(rawValues, target);
return Object.values(values);
};
const parseValue = v => parseFloat(v.replace(/[^\d\.]/g, ''));
const set_ratio = (target, only_my_charity=true, debug=false, ...order) => {
$('input.js-custom-amount:first').val(target).change();
$('button:contains("Adjust Donation")').click();
$('input[value=custom]').click();
if (order.length === 0) {
order = [0, 1, 2];
}
const portions = get_golden_ratio(target, ...order);
debug && console.log(portions);
const elements = portions.map((v, i) => $(`input.amount-input:nth(${order[i]})`));
debug && console.log(elements);
var run=0;
while (!elements.every(($e, i) => parseValue($e.val()) === portions[i]) && run < 10) {
elements.forEach(($e, i) => {
$e.val(portions[i]).change();
debug && console.log($e.val());
});
run++;
}
if (only_my_charity) {
$('button.subsplits-toggle').click();
const subelements = $('div.subsplits').find('input.amount-input');
subelements.slice(0, subelements.length - 1).each((i, v) => $(v).val(0).change());
subelements.slice(0, subelements.length - 1).each((i, v) => $(v).val(0).change());
}
};
const get_golden_ratio=(e,...a)=>{const t=e=>Math.round(100*e)/100,l=a.length,n=(new Array(l),a.map((e,a)=>Math.pow(1.618033988749895,l-a))),o=n.reduce((e,a)=>e+a,0),u=((e=[],a=100)=>{let l=a-e.reduce((e,a)=>e+t(a),0),n=e.length;return e.map((e,a)=>({value:e,index:a})).sort((e,a)=>t(e.value)-e.value-(t(a.value)-a.value)).map((e,a)=>(e.value=t(e.value)+(l>a)-(a>=n+l),e)).reduce((e,a)=>(e[a.index]=a.value,e),{})})(n.map((a,t)=>a*e/o),e);return Object.values(u)},parseValue=e=>parseFloat(e.replace(/[^\d\.]/g,"")),set_ratio=(e,a=!0,t=!1,...l)=>{$("input.js-custom-amount:first").val(e).change(),$('button:contains("Adjust Donation")').click(),$("input[value=custom]").click(),0===l.length&&(l=[0,1,2]);const n=get_golden_ratio(e,...l);t&&console.log(n);const o=n.map((e,a)=>$(`input.amount-input:nth(${l[a]})`));t&&console.log(o);for(var u=0;!o.every((e,a)=>parseValue(e.val())===n[a])&&u<10;)o.forEach((e,a)=>{e.val(n[a]).change(),t&&console.log(e.val())}),u++;if(a){$("button.subsplits-toggle").click();const e=$("div.subsplits").find("input.amount-input");e.slice(0,e.length-1).each((e,a)=>$(a).val(0).change()),e.slice(0,e.length-1).each((e,a)=>$(a).val(0).change())}};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment