Skip to content

Commit ed8e2b9

Browse files
add web version
1 parent 1d82f41 commit ed8e2b9

File tree

4 files changed

+126
-2
lines changed

4 files changed

+126
-2
lines changed

cpigjs/web.ts

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
'use strict';
2+
import { Info, SetFamily, BoolSetFamily, DagSetFamily, ProdSetFamily } from "./setFamily.js";
3+
import { filterByConstraint, combineInputs, Ostream, CpigInput, outputPath } from "./main.js";
4+
import { Edge, Graph } from "./graph.js";
5+
6+
declare class Param {
7+
constructor(name: string, widget: any, label?: string, description?: string);
8+
}
9+
declare class ParamGroup {
10+
constructor(name: string, paramList: Param[], converter?: any, description?: string);
11+
}
12+
declare var CheckBoxWidget: any;
13+
declare var SelectWidget: any;
14+
declare var SelectOption: any;
15+
declare function createForm(wrapperId: string, paramGroup: ParamGroup,
16+
func: (input: string, stdout: Ostream) => any, clearOutput?: boolean): any;
17+
18+
export async function setup(sfUrl: string, inputUrls: string[]) {
19+
const {sf, input} = await fetchInput(sfUrl, inputUrls);
20+
const params: Param[] = [];
21+
addSfParams(params, sf);
22+
addPredParams(params, input.predicates!);
23+
const paramGroup = new ParamGroup('myForm', params);
24+
createForm('myApp', paramGroup, function (f2fInput, stdout) {
25+
cli(sf, input, f2fInput, stdout);
26+
});
27+
}
28+
29+
export async function fetchInput(sfUrl: string, inputUrls: string[]) {
30+
const pageLoadPromise = new Promise(function(resolve, reject) {
31+
window.addEventListener('DomContentLoaded', resolve);
32+
});
33+
const sfPromise = window.fetch(sfUrl)
34+
.then(response => response.json())
35+
.then(json => SetFamily.fromJson(json));
36+
const inputsPromise = Promise.all(inputUrls.map(
37+
inputUrl => window.fetch(inputUrl).then(response => response.json())));
38+
const sf = await sfPromise;
39+
const input = combineInputs(await inputsPromise);
40+
console.log(sf);
41+
console.log(input);
42+
return {sf: sf, input: input};
43+
}
44+
45+
function addSfParams(output: Param[], setFamily: SetFamily) {
46+
const name = setFamily.info.name;
47+
if(setFamily instanceof BoolSetFamily) {
48+
output.push(new Param(name, new CheckBoxWidget()));
49+
}
50+
else if(setFamily instanceof DagSetFamily) {
51+
output.push(new Param(name, new SelectWidget(setFamily.values.map(
52+
vInfo => new SelectOption(vInfo.name, vInfo.name, vInfo.label || vInfo.name)), setFamily.defVal)));
53+
}
54+
else if(setFamily instanceof ProdSetFamily) {
55+
for(const part of setFamily.parts) {
56+
addSfParams(output, part);
57+
}
58+
}
59+
}
60+
61+
function addPredParams(output: Param[], preds: Info[]) {
62+
for(const pred of preds) {
63+
output.push(new Param('pred.' + pred.name, new CheckBoxWidget(), pred.name));
64+
}
65+
}
66+
67+
function cli(sf: SetFamily, input: CpigInput, f2fInput: any, stdout: Ostream) {
68+
const chosenPreds = [];
69+
for(const pred of input.predicates!) {
70+
if(f2fInput['pred.'+pred.name]) {
71+
chosenPreds.push(pred.name);
72+
}
73+
}
74+
const procInput = filterByConstraint([input], f2fInput, sf);
75+
76+
if(chosenPreds.length === 2) {
77+
const [u, v] = chosenPreds;
78+
outputPath(procInput.impG, u, v, stdout);
79+
outputPath(procInput.impG, v, u, stdout);
80+
}
81+
const {scc, dag} = procInput.impG.trCompression(chosenPreds.length > 0 ? chosenPreds : undefined);
82+
const redDag = dag.trRed();
83+
const s = sccDagToStr(scc, redDag);
84+
stdout.log(s);
85+
}
86+
87+
function componentStr(S: string[], parens: boolean) {
88+
const begDelim = parens ? '( ' : '';
89+
const endDelim = parens ? ' )' : '';
90+
return S.length === 1 ? S[0] : begDelim + S.join(' = ') + endDelim;
91+
}
92+
93+
function sccDagToStr(scc: Map<string, string[]>, dag: Graph<string, Edge<string>>) {
94+
const lines = [];
95+
for(const edge of dag.edges) {
96+
const uS = scc.get(edge.from)!, vS = scc.get(edge.to)!;
97+
lines.push(componentStr(uS, true) + ' ==> ' + componentStr(vS, true));
98+
}
99+
return lines.join('\n');
100+
}

example/cpigjs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../cpigjs

example/index.html

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<meta name="color-scheme" content="dark light" />
7+
<title>Fair Division Implications</title>
8+
<link rel="stylesheet" href="https://sharmaeklavya2.github.io/funcToForm/funcToForm.css" />
9+
<script type="text/javascript" src="https://sharmaeklavya2.github.io/funcToForm/funcToForm.js"></script>
10+
<!--<link rel="stylesheet" href="http://localhost:8080/websites/funcToForm/funcToForm.css" />
11+
<script type="text/javascript" src="http://localhost:8080/websites/funcToForm/funcToForm.js"></script>-->
12+
<script type="module" src="cpigjs/web.js"></script>
13+
<script type="module">
14+
import { setup } from './cpigjs/web.js';
15+
await setup('fd-family.json', ['fdig.json']);
16+
</script>
17+
</head>
18+
19+
<body>
20+
<h1>Fair Division Implications</h1>
21+
<div id="myApp"></div>
22+
</body>
23+
</html>

tsconfig.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"compilerOptions": {
3-
"target": "ES6",
4-
"module": "ES6",
3+
"target": "ES2020",
4+
"module": "ES2020",
55
"rootDir": "cpigjs",
66
"sourceMap": true,
77
"forceConsistentCasingInFileNames": true,

0 commit comments

Comments
 (0)