ecclesia
Version:
Framework for political and electoral simulations
146 lines (143 loc) • 4.42 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/actors/house.ts
var house_exports = {};
__export(house_exports, {
District: () => District,
House: () => House
});
module.exports = __toCommonJS(house_exports);
var import_collections = require("@gouvernathor/python/collections");
// src/actors/vote.ts
var Vote = class _Vote {
constructor(votesFor, votesAgainst) {
this.votesFor = votesFor;
this.votesAgainst = votesAgainst;
}
/**
* Returns the reverse of the vote, inverting the for/against ratio.
* Simulates a vote on the opposite motion.
*/
get neg() {
return new _Vote(this.votesAgainst, this.votesFor);
}
get votesCast() {
return this.votesFor + this.votesAgainst;
}
/**
* Returns the ratio of votes for over the total number of votes cast.
* If there are no votes cast, returns an Infinity.
*/
get ratio() {
return this.votesFor / this.votesCast;
}
/**
* Returns the votes in order of decreasing ratio.
* The ties are ordered by decreasing number of positive votes,
* and then by the order they came in.
*/
static order(votes) {
return votes.sort((a, b) => b.ratio - a.ratio || b.votesFor - a.votesFor);
}
};
// src/actors/house.ts
var District = class {
constructor(electionMethod, voters, { identifier, nSeats } = {}) {
this.electionMethod = electionMethod;
this.voters = voters;
this.identifier = identifier;
this.nSeats = nSeats;
}
election(candidates) {
return this.electionMethod(this.voters, candidates);
}
};
var House = class {
constructor(districts, { name, majority = 0.5 } = {}) {
if (!(districts instanceof Map)) {
districts = new Map([...districts].map((d) => [d, new import_collections.Counter()]));
}
this.districts = districts;
this.name = name;
this.majority = majority;
}
/**
* Returns a Counter linking each party to the number of seats it holds,
* regardless of the district.
* For the array (with repetitions) of the individual members, use the
* members.elements() method.
*/
get members() {
const coun = new import_collections.Counter();
for (const dmembers of this.districts.values()) {
coun.update(dmembers);
}
return coun;
}
/**
* If all districts support providing a theoretical number of seats,
* returns the total. Otherwise, returns undefined.
*/
get nSeats() {
let nSeats = 0;
for (const district of this.districts.keys()) {
if (district.nSeats === void 0) {
return void 0;
}
nSeats += district.nSeats;
}
return nSeats;
}
/**
* Triggers an election in each electoral district, returns the members result.
*/
election(candidates) {
const members = new import_collections.Counter();
for (const district of this.districts.keys()) {
const elected = district.election(candidates);
this.districts.set(district, elected);
members.update(elected);
}
return members;
}
/**
* Returns the state of the vote on something having an opinion.
* The object of the vote may be a motion or bill, but also a person to elect
* or to confirm.
*/
vote(target, { disagree }) {
let votesFor = 0;
let votesAgainst = 0;
for (const [party, nSeats] of this.members) {
const disag = disagree(party, target);
if (disag > 0) {
votesFor += nSeats;
} else if (disag < 0) {
votesAgainst += nSeats;
}
}
return new Vote(votesFor, votesAgainst);
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
District,
House
});
//# sourceMappingURL=house.cjs.map