repertoire-faceting 0.7.2 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/FAQ +3 -2
- data/ext/Makefile +1 -1
- data/ext/bytea/faceting_bytea.control +1 -1
- data/ext/faceting--0.7.2.sql +251 -0
- data/ext/faceting_bytea--0.7.2.sql +207 -0
- data/ext/faceting_varbit--0.7.2.sql +198 -0
- data/ext/signature/faceting.control +1 -1
- data/ext/signature/signature.o +0 -0
- data/ext/signature/signature.so +0 -0
- data/ext/varbit/faceting_varbit.control +1 -1
- data/lib/assets/javascripts/rep.faceting/context.js +0 -22
- data/lib/assets/javascripts/rep.faceting/facet.js +13 -2
- data/lib/assets/javascripts/rep.faceting/facet_widget.js +16 -0
- data/lib/assets/javascripts/rep.faceting/results.js +13 -3
- data/lib/assets/javascripts/rep.widgets/model.js +4 -3
- data/lib/assets/javascripts/rep.widgets/widget.js +16 -14
- data/lib/repertoire-faceting/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f33047f3e67ebe050a869ec98d8f90042c284de
|
4
|
+
data.tar.gz: 66d4aa841d23714ede620a6ea56f2947f107a97c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d86d643b9c881419b6dfe4f3608a56160193775057fc4f645f4b4367f10416cc5968e7f85a0f8059acc9a6c0f5cdc7ebf01a571d1bdc74e6661aa253f6a15e3
|
7
|
+
data.tar.gz: 890a6a07e726450554e058065f0e1fd2471805b8b4e6a751d87d564b5bc3dee58567176b56e8c445fc3df7f12009a9882d7eb2f854966d7facd0c82dce447675
|
data/FAQ
CHANGED
@@ -95,6 +95,7 @@
|
|
95
95
|
|
96
96
|
*A* See the syntax for defining jquery plugins - you can alter the defaults for all widgets by reassigning them in your view code.
|
97
97
|
|
98
|
+
|
98
99
|
*Q* How do I make one-time, minor changes to the behaviour of a widget? For example, I want to add a control.
|
99
100
|
|
100
101
|
*A* Use the inject option, which is part of the base functionality. Your injector function receives a reference to the widget's jquery element and to the widget javascript object. Use jquery to add your control's markup, then register an event handler to add its behaviour. For example, this injector adds a clear-all button in the title:
|
@@ -106,7 +107,7 @@
|
|
106
107
|
handlers: {
|
107
108
|
'click!.clear_control' : function(self) {
|
108
109
|
self.refinements('genre').length = 0;
|
109
|
-
self.
|
110
|
+
self.trigger('changed');
|
110
111
|
return false;
|
111
112
|
}
|
112
113
|
}
|
@@ -127,7 +128,7 @@ In injectors and handlers, you have access to the complete faceting widget API (
|
|
127
128
|
$('#genre').facet({
|
128
129
|
injectors: { ... },
|
129
130
|
handlers: { ... },
|
130
|
-
|
131
|
+
state: function(state) { state.minimum = genre_min; }
|
131
132
|
}
|
132
133
|
|
133
134
|
|
data/ext/Makefile
CHANGED
@@ -0,0 +1,251 @@
|
|
1
|
+
-- ============================================================================
|
2
|
+
-- Faceting API implementing bitmap indices using a custom C datatype and
|
3
|
+
-- associated functions.
|
4
|
+
--
|
5
|
+
-- This API is to be preferred in all situations where it is possible to
|
6
|
+
-- build and install the datatype (requires superuser access to PostgreSQL)
|
7
|
+
--
|
8
|
+
-- Christopher York
|
9
|
+
-- MIT Hyperstudio
|
10
|
+
-- February 2014
|
11
|
+
-- ============================================================================
|
12
|
+
|
13
|
+
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
|
14
|
+
\echo Use "CREATE EXTENSION faceting" to load this the default faceting API.\quit
|
15
|
+
|
16
|
+
-- functions for bitmap indices using datatype written in C
|
17
|
+
|
18
|
+
CREATE TYPE @extschema@.signature;
|
19
|
+
|
20
|
+
-- basic i/o functions for signatures
|
21
|
+
|
22
|
+
CREATE FUNCTION @extschema@.sig_in( cstring )
|
23
|
+
RETURNS signature
|
24
|
+
AS 'signature.so', 'sig_in'
|
25
|
+
LANGUAGE C STRICT;
|
26
|
+
|
27
|
+
CREATE FUNCTION @extschema@.sig_out( signature )
|
28
|
+
RETURNS cstring
|
29
|
+
AS 'signature.so', 'sig_out'
|
30
|
+
LANGUAGE C STRICT;
|
31
|
+
|
32
|
+
-- signature postgresql type
|
33
|
+
|
34
|
+
CREATE TYPE @extschema@.signature (
|
35
|
+
INTERNALLENGTH = VARIABLE,
|
36
|
+
INPUT = sig_in,
|
37
|
+
OUTPUT = sig_out,
|
38
|
+
STORAGE = extended
|
39
|
+
);
|
40
|
+
|
41
|
+
-- functions for signatures
|
42
|
+
|
43
|
+
CREATE FUNCTION @extschema@.sig_resize( signature, INT )
|
44
|
+
RETURNS signature
|
45
|
+
AS 'signature.so', 'sig_resize'
|
46
|
+
LANGUAGE C STRICT IMMUTABLE;
|
47
|
+
|
48
|
+
CREATE FUNCTION @extschema@.sig_set( signature, INT, INT )
|
49
|
+
RETURNS signature
|
50
|
+
AS 'signature.so', 'sig_set'
|
51
|
+
LANGUAGE C STRICT IMMUTABLE;
|
52
|
+
|
53
|
+
CREATE FUNCTION @extschema@.sig_set( signature, INT )
|
54
|
+
RETURNS signature
|
55
|
+
AS 'signature.so', 'sig_set'
|
56
|
+
LANGUAGE C STRICT IMMUTABLE;
|
57
|
+
|
58
|
+
CREATE FUNCTION @extschema@.sig_get( signature, INT )
|
59
|
+
RETURNS INT
|
60
|
+
AS 'signature.so', 'sig_get'
|
61
|
+
LANGUAGE C STRICT IMMUTABLE;
|
62
|
+
|
63
|
+
CREATE FUNCTION @extschema@.sig_length( signature )
|
64
|
+
RETURNS INT
|
65
|
+
AS 'signature.so', 'sig_length'
|
66
|
+
LANGUAGE C STRICT IMMUTABLE;
|
67
|
+
|
68
|
+
CREATE FUNCTION @extschema@.sig_min( signature )
|
69
|
+
RETURNS INT
|
70
|
+
AS 'signature.so', 'sig_min'
|
71
|
+
LANGUAGE C STRICT IMMUTABLE;
|
72
|
+
|
73
|
+
CREATE FUNCTION @extschema@.sig_and( signature, signature )
|
74
|
+
RETURNS signature
|
75
|
+
AS 'signature.so', 'sig_and'
|
76
|
+
LANGUAGE C STRICT IMMUTABLE;
|
77
|
+
|
78
|
+
CREATE FUNCTION @extschema@.sig_or( signature, signature )
|
79
|
+
RETURNS signature
|
80
|
+
AS 'signature.so', 'sig_or'
|
81
|
+
LANGUAGE C STRICT IMMUTABLE;
|
82
|
+
|
83
|
+
CREATE FUNCTION @extschema@.sig_xor( signature )
|
84
|
+
RETURNS signature
|
85
|
+
AS 'signature.so', 'sig_xor'
|
86
|
+
LANGUAGE C STRICT IMMUTABLE;
|
87
|
+
|
88
|
+
CREATE FUNCTION @extschema@.count( signature )
|
89
|
+
RETURNS INT
|
90
|
+
AS 'signature.so', 'count'
|
91
|
+
LANGUAGE C STRICT IMMUTABLE;
|
92
|
+
|
93
|
+
CREATE FUNCTION @extschema@.contains( signature, INT )
|
94
|
+
RETURNS BOOL
|
95
|
+
AS 'signature.so', 'contains'
|
96
|
+
LANGUAGE C STRICT IMMUTABLE;
|
97
|
+
|
98
|
+
CREATE FUNCTION @extschema@.members( signature )
|
99
|
+
RETURNS SETOF INT
|
100
|
+
AS 'signature.so', 'members'
|
101
|
+
LANGUAGE C STRICT IMMUTABLE;
|
102
|
+
|
103
|
+
CREATE FUNCTION @extschema@.sig_cmp( signature, signature )
|
104
|
+
RETURNS INT
|
105
|
+
AS 'signature.so', 'sig_cmp'
|
106
|
+
LANGUAGE C STRICT IMMUTABLE;
|
107
|
+
|
108
|
+
CREATE FUNCTION @extschema@.sig_lt( signature, signature )
|
109
|
+
RETURNS BOOL
|
110
|
+
AS 'signature.so', 'sig_lt'
|
111
|
+
LANGUAGE C STRICT IMMUTABLE;
|
112
|
+
|
113
|
+
CREATE FUNCTION @extschema@.sig_lte( signature, signature )
|
114
|
+
RETURNS BOOL
|
115
|
+
AS 'signature.so', 'sig_lte'
|
116
|
+
LANGUAGE C STRICT IMMUTABLE;
|
117
|
+
|
118
|
+
CREATE FUNCTION @extschema@.sig_eq( signature, signature )
|
119
|
+
RETURNS BOOL
|
120
|
+
AS 'signature.so', 'sig_eq'
|
121
|
+
LANGUAGE C STRICT IMMUTABLE;
|
122
|
+
|
123
|
+
CREATE FUNCTION @extschema@.sig_gt( signature, signature )
|
124
|
+
RETURNS BOOL
|
125
|
+
AS 'signature.so', 'sig_gt'
|
126
|
+
LANGUAGE C STRICT IMMUTABLE;
|
127
|
+
|
128
|
+
CREATE FUNCTION @extschema@.sig_gte( signature, signature )
|
129
|
+
RETURNS BOOL
|
130
|
+
AS 'signature.so', 'sig_gte'
|
131
|
+
LANGUAGE C STRICT IMMUTABLE;
|
132
|
+
|
133
|
+
|
134
|
+
-- operators for signatures
|
135
|
+
|
136
|
+
CREATE OPERATOR @extschema@.& (
|
137
|
+
leftarg = signature,
|
138
|
+
rightarg = signature,
|
139
|
+
procedure = @extschema@.sig_and,
|
140
|
+
commutator = &
|
141
|
+
);
|
142
|
+
|
143
|
+
CREATE OPERATOR @extschema@.| (
|
144
|
+
leftarg = signature,
|
145
|
+
rightarg = signature,
|
146
|
+
procedure = @extschema@.sig_or,
|
147
|
+
commutator = |
|
148
|
+
);
|
149
|
+
|
150
|
+
CREATE OPERATOR @extschema@.+ (
|
151
|
+
leftarg = signature,
|
152
|
+
rightarg = int,
|
153
|
+
procedure = @extschema@.sig_set
|
154
|
+
);
|
155
|
+
|
156
|
+
CREATE OPERATOR @extschema@.< (
|
157
|
+
leftarg = signature, rightarg = signature, procedure = sig_lt,
|
158
|
+
commutator = > , negator = >= ,
|
159
|
+
restrict = scalarltsel, join = scalarltjoinsel
|
160
|
+
);
|
161
|
+
|
162
|
+
CREATE OPERATOR @extschema@.<= (
|
163
|
+
leftarg = signature, rightarg = signature, procedure = sig_lte,
|
164
|
+
commutator = >= , negator = > ,
|
165
|
+
restrict = scalarltsel, join = scalarltjoinsel
|
166
|
+
);
|
167
|
+
|
168
|
+
CREATE OPERATOR @extschema@.= (
|
169
|
+
leftarg = signature, rightarg = signature, procedure = sig_eq,
|
170
|
+
commutator = = , negator = <> ,
|
171
|
+
restrict = eqsel, join = eqjoinsel
|
172
|
+
);
|
173
|
+
|
174
|
+
CREATE OPERATOR >= (
|
175
|
+
leftarg = signature, rightarg = signature, procedure = sig_gte,
|
176
|
+
commutator = <= , negator = < ,
|
177
|
+
restrict = scalargtsel, join = scalargtjoinsel
|
178
|
+
);
|
179
|
+
|
180
|
+
CREATE OPERATOR @extschema@.> (
|
181
|
+
leftarg = signature, rightarg = signature, procedure = sig_gt,
|
182
|
+
commutator = < , negator = <= ,
|
183
|
+
restrict = scalargtsel, join = scalargtjoinsel
|
184
|
+
);
|
185
|
+
|
186
|
+
-- index operator classes for signatures
|
187
|
+
|
188
|
+
CREATE OPERATOR CLASS @extschema@.signature_ops
|
189
|
+
DEFAULT FOR TYPE signature USING btree AS
|
190
|
+
OPERATOR 1 < ,
|
191
|
+
OPERATOR 2 <= ,
|
192
|
+
OPERATOR 3 = ,
|
193
|
+
OPERATOR 4 >= ,
|
194
|
+
OPERATOR 5 > ,
|
195
|
+
FUNCTION 1 sig_cmp(signature, signature);
|
196
|
+
|
197
|
+
|
198
|
+
-- aggregate functions for faceting
|
199
|
+
|
200
|
+
CREATE AGGREGATE @extschema@.collect( signature )
|
201
|
+
(
|
202
|
+
sfunc = @extschema@.sig_or,
|
203
|
+
stype = signature
|
204
|
+
);
|
205
|
+
|
206
|
+
CREATE AGGREGATE @extschema@.filter( signature )
|
207
|
+
(
|
208
|
+
sfunc = @extschema@.sig_and,
|
209
|
+
stype = signature
|
210
|
+
);
|
211
|
+
|
212
|
+
CREATE AGGREGATE @extschema@.signature( INT )
|
213
|
+
(
|
214
|
+
sfunc = @extschema@.sig_set,
|
215
|
+
stype = signature,
|
216
|
+
initcond = '0'
|
217
|
+
);-- ============================================================================
|
218
|
+
-- These functions are common to all bindings of the Repertoire faceting API
|
219
|
+
--
|
220
|
+
-- Christopher York
|
221
|
+
-- MIT Hyperstudio
|
222
|
+
-- February 2014
|
223
|
+
-- ============================================================================
|
224
|
+
|
225
|
+
|
226
|
+
-- Aggregator to measure how many bits from a loosely-packed id column would be wasted, if
|
227
|
+
-- they were all collected into a bitset signature. Returns a float between 0 (no waste)
|
228
|
+
-- and 1.0 (all waste). An example of its use:
|
229
|
+
--
|
230
|
+
-- SELECT wastage(id) FROM nobelists
|
231
|
+
-- =# 0.999999
|
232
|
+
--
|
233
|
+
-- ALTER TABLE nobelists ADD COLUMN _packed_id SERIAL
|
234
|
+
-- SELECT wastage(_packed_id) FROM nobelists
|
235
|
+
-- =# 0.015625
|
236
|
+
--
|
237
|
+
CREATE FUNCTION @extschema@.wastage_proportion( state INT[] ) RETURNS double precision AS $$
|
238
|
+
SELECT (1.0 - (state[1]::double precision / (COALESCE(state[2], 0.0) + 1.0)))
|
239
|
+
$$ LANGUAGE sql;
|
240
|
+
|
241
|
+
CREATE FUNCTION @extschema@.wastage_accum( state INT[], val INT ) RETURNS INT[] AS $$
|
242
|
+
SELECT ARRAY[ state[1]+1, GREATEST(state[2], val) ];
|
243
|
+
$$ LANGUAGE sql;
|
244
|
+
|
245
|
+
CREATE AGGREGATE @extschema@.wastage( INT )
|
246
|
+
(
|
247
|
+
sfunc = @extschema@.wastage_accum,
|
248
|
+
stype = INT[],
|
249
|
+
finalfunc = @extschema@.wastage_proportion,
|
250
|
+
initcond = '{0,0}'
|
251
|
+
);
|
@@ -0,0 +1,207 @@
|
|
1
|
+
-- ============================================================================
|
2
|
+
-- Faceting API implementing bitmap indices using PostgreSQL's built-in BYTEA
|
3
|
+
-- type, processed using plv8 typed arrays.
|
4
|
+
--
|
5
|
+
-- This API is suitable for deployment on Heroku, where plv8 is installed by
|
6
|
+
-- default. Performance is many times better than the VARBIT-based faceting
|
7
|
+
-- API, primarily because of optimisations in memory handling in the count
|
8
|
+
-- function.
|
9
|
+
--
|
10
|
+
-- See https://code.google.com/p/plv8js/wiki/PLV8
|
11
|
+
-- https://postgres.heroku.com/blog/past/2013/6/5/javascript_in_your_postgres/
|
12
|
+
--
|
13
|
+
-- Christopher York
|
14
|
+
-- MIT Hyperstudio
|
15
|
+
-- February 2014
|
16
|
+
-- ============================================================================
|
17
|
+
|
18
|
+
CREATE EXTENSION IF NOT EXISTS plv8;
|
19
|
+
|
20
|
+
SET bytea_output TO hex;
|
21
|
+
|
22
|
+
-- these functions are in pl/pgsql, because they involve appending bytea values,
|
23
|
+
-- which is easier done with direct access to the || operator
|
24
|
+
|
25
|
+
CREATE FUNCTION @extschema@.sig_resize( sig BYTEA, bits INT ) RETURNS BYTEA AS $$
|
26
|
+
DECLARE
|
27
|
+
len INT;
|
28
|
+
bytes INT;
|
29
|
+
BEGIN
|
30
|
+
bytes := ceil(bits / 8.0)::INT;
|
31
|
+
len := length(sig);
|
32
|
+
IF bytes > len THEN
|
33
|
+
-- RAISE NOTICE 'Extending signature from % to % bytes', len, bytes;
|
34
|
+
RETURN sig || ('\x' || repeat('00', bytes - len))::BYTEA;
|
35
|
+
ELSIF bits < len THEN
|
36
|
+
-- no provision in PostgreSQL for truncating a BYTEA
|
37
|
+
RETURN sig;
|
38
|
+
END IF;
|
39
|
+
RETURN sig;
|
40
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
41
|
+
|
42
|
+
CREATE FUNCTION @extschema@.sig_set( sig BYTEA, pos INT, val INT ) RETURNS BYTEA AS $$
|
43
|
+
BEGIN
|
44
|
+
RETURN set_bit(@extschema@.sig_resize(sig, pos+1), pos, val);
|
45
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
46
|
+
|
47
|
+
CREATE FUNCTION @extschema@.sig_set( sig BYTEA, pos INT ) RETURNS BYTEA AS $$
|
48
|
+
BEGIN
|
49
|
+
RETURN @extschema@.sig_set(sig, pos, 1);
|
50
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
51
|
+
|
52
|
+
-- these functions are in javascript, because (1) pl/pgsql is close
|
53
|
+
-- to the worst language in the world; (2) plv8's typed arrays make
|
54
|
+
-- the count function much faster
|
55
|
+
|
56
|
+
CREATE FUNCTION @extschema@.sig_get( sig BYTEA, pos INT ) RETURNS INT AS $$
|
57
|
+
if (pos <= sig.length * 8) {
|
58
|
+
return sig[ Math.floor(pos / 8) ] >> (pos % 8) & 1;
|
59
|
+
} else {
|
60
|
+
return 0;
|
61
|
+
}
|
62
|
+
$$ LANGUAGE plv8 STRICT IMMUTABLE;
|
63
|
+
|
64
|
+
CREATE FUNCTION @extschema@.sig_length( sig BYTEA ) RETURNS INT AS $$
|
65
|
+
return sig.length;
|
66
|
+
$$ LANGUAGE plv8 STRICT IMMUTABLE;
|
67
|
+
|
68
|
+
CREATE FUNCTION @extschema@.sig_and(sig1 BYTEA, sig2 BYTEA) RETURNS BYTEA AS $$
|
69
|
+
if (sig2.length < sig1.length) {
|
70
|
+
var tmp = sig1;
|
71
|
+
sig1 = sig2;
|
72
|
+
sig2 = tmp;
|
73
|
+
}
|
74
|
+
for (var i = 0; i < sig1.length; i++) {
|
75
|
+
sig1[i] = sig1[i] & sig2[i];
|
76
|
+
}
|
77
|
+
return sig1;
|
78
|
+
$$ LANGUAGE plv8 STRICT IMMUTABLE;
|
79
|
+
|
80
|
+
CREATE FUNCTION @extschema@.sig_or(sig1 BYTEA, sig2 BYTEA) RETURNS BYTEA AS $$
|
81
|
+
if (sig2.length > sig1.length) {
|
82
|
+
var tmp = sig1;
|
83
|
+
sig1 = sig2;
|
84
|
+
sig2 = tmp;
|
85
|
+
}
|
86
|
+
for (var i = 0; i < sig2.length; i++) {
|
87
|
+
sig1[i] = sig1[i] | sig2[i];
|
88
|
+
}
|
89
|
+
return sig1;
|
90
|
+
$$ LANGUAGE plv8 STRICT IMMUTABLE;
|
91
|
+
|
92
|
+
CREATE FUNCTION @extschema@.count( sig BYTEA ) RETURNS int4 AS $$
|
93
|
+
var count_table = [
|
94
|
+
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
|
95
|
+
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
96
|
+
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
97
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
98
|
+
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
99
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
100
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
101
|
+
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
102
|
+
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
103
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
104
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
105
|
+
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
106
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
107
|
+
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
108
|
+
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
109
|
+
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
|
110
|
+
];
|
111
|
+
var count = 0;
|
112
|
+
for (var i = 0; i < sig.length; i++) { count += count_table[ sig[i] ]; }
|
113
|
+
return count;
|
114
|
+
$$ LANGUAGE plv8 STRICT IMMUTABLE;
|
115
|
+
|
116
|
+
CREATE FUNCTION @extschema@.contains( sig BYTEA, pos INT ) RETURNS BOOL AS $$
|
117
|
+
return (pos <= sig.length * 8) && (sig[ Math.floor(pos / 8) ] >> (pos % 8) & 1);
|
118
|
+
$$ LANGUAGE plv8 STRICT IMMUTABLE;
|
119
|
+
|
120
|
+
CREATE FUNCTION @extschema@.members( sig BYTEA ) RETURNS SETOF INT AS $$
|
121
|
+
for (var i = 0; i < sig.length; i++) {
|
122
|
+
for (var j = 0; j < 8; j++) {
|
123
|
+
if (sig[i] >> j & 1) {
|
124
|
+
plv8.return_next(i * 8 + j);
|
125
|
+
}
|
126
|
+
}
|
127
|
+
}
|
128
|
+
$$ LANGUAGE plv8 STRICT IMMUTABLE;
|
129
|
+
|
130
|
+
|
131
|
+
-- operators for faceting
|
132
|
+
|
133
|
+
CREATE OPERATOR @extschema@.& (
|
134
|
+
leftarg = BYTEA,
|
135
|
+
rightarg = BYTEA,
|
136
|
+
procedure = @extschema@.sig_and,
|
137
|
+
commutator = &
|
138
|
+
);
|
139
|
+
|
140
|
+
CREATE OPERATOR @extschema@.| (
|
141
|
+
leftarg = BYTEA,
|
142
|
+
rightarg = BYTEA,
|
143
|
+
procedure = @extschema@.sig_or,
|
144
|
+
commutator = |
|
145
|
+
);
|
146
|
+
|
147
|
+
CREATE OPERATOR @extschema@.+ (
|
148
|
+
leftarg = BYTEA,
|
149
|
+
rightarg = int,
|
150
|
+
procedure = @extschema@.sig_set
|
151
|
+
);
|
152
|
+
|
153
|
+
|
154
|
+
-- aggregate functions for faceting
|
155
|
+
|
156
|
+
CREATE AGGREGATE @extschema@.collect( BYTEA )
|
157
|
+
(
|
158
|
+
sfunc = @extschema@.sig_or,
|
159
|
+
stype = BYTEA
|
160
|
+
);
|
161
|
+
|
162
|
+
CREATE AGGREGATE @extschema@.filter( BYTEA )
|
163
|
+
(
|
164
|
+
sfunc = @extschema@.sig_and,
|
165
|
+
stype = BYTEA
|
166
|
+
);
|
167
|
+
|
168
|
+
CREATE AGGREGATE @extschema@.signature( INT )
|
169
|
+
(
|
170
|
+
sfunc = @extschema@.sig_set,
|
171
|
+
stype = BYTEA,
|
172
|
+
initcond = ''
|
173
|
+
);-- ============================================================================
|
174
|
+
-- These functions are common to all bindings of the Repertoire faceting API
|
175
|
+
--
|
176
|
+
-- Christopher York
|
177
|
+
-- MIT Hyperstudio
|
178
|
+
-- February 2014
|
179
|
+
-- ============================================================================
|
180
|
+
|
181
|
+
|
182
|
+
-- Aggregator to measure how many bits from a loosely-packed id column would be wasted, if
|
183
|
+
-- they were all collected into a bitset signature. Returns a float between 0 (no waste)
|
184
|
+
-- and 1.0 (all waste). An example of its use:
|
185
|
+
--
|
186
|
+
-- SELECT wastage(id) FROM nobelists
|
187
|
+
-- =# 0.999999
|
188
|
+
--
|
189
|
+
-- ALTER TABLE nobelists ADD COLUMN _packed_id SERIAL
|
190
|
+
-- SELECT wastage(_packed_id) FROM nobelists
|
191
|
+
-- =# 0.015625
|
192
|
+
--
|
193
|
+
CREATE FUNCTION @extschema@.wastage_proportion( state INT[] ) RETURNS double precision AS $$
|
194
|
+
SELECT (1.0 - (state[1]::double precision / (COALESCE(state[2], 0.0) + 1.0)))
|
195
|
+
$$ LANGUAGE sql;
|
196
|
+
|
197
|
+
CREATE FUNCTION @extschema@.wastage_accum( state INT[], val INT ) RETURNS INT[] AS $$
|
198
|
+
SELECT ARRAY[ state[1]+1, GREATEST(state[2], val) ];
|
199
|
+
$$ LANGUAGE sql;
|
200
|
+
|
201
|
+
CREATE AGGREGATE @extschema@.wastage( INT )
|
202
|
+
(
|
203
|
+
sfunc = @extschema@.wastage_accum,
|
204
|
+
stype = INT[],
|
205
|
+
finalfunc = @extschema@.wastage_proportion,
|
206
|
+
initcond = '{0,0}'
|
207
|
+
);
|
@@ -0,0 +1,198 @@
|
|
1
|
+
-- ============================================================================
|
2
|
+
-- Faceting API implementing bitmap indices using PostgreSQL's built-in VARBIT
|
3
|
+
-- type, processed using the built-in language pl/pgsql.
|
4
|
+
--
|
5
|
+
-- This API is suitable for deployment on any host, since it requires no
|
6
|
+
-- PostgreSQL extensions outside the default install.
|
7
|
+
--
|
8
|
+
-- However, performance is limited to around 30,000 items in practice (in part
|
9
|
+
-- because of unnecessary duplication of varbit values when pl/pgsql evaluates
|
10
|
+
-- the count function.)
|
11
|
+
--
|
12
|
+
-- The 'signature' C-based faceting API is preferable for any install where
|
13
|
+
-- you have superuser access to the database.
|
14
|
+
--
|
15
|
+
-- Christopher York
|
16
|
+
-- MIT Hyperstudio
|
17
|
+
-- February 2014
|
18
|
+
-- ============================================================================
|
19
|
+
|
20
|
+
CREATE FUNCTION @extschema@.sig_resize( sig VARBIT, bits INT ) RETURNS VARBIT AS $$
|
21
|
+
DECLARE
|
22
|
+
len INT;
|
23
|
+
BEGIN
|
24
|
+
len := length(sig);
|
25
|
+
IF bits > len THEN
|
26
|
+
RETURN sig || repeat('0', bits - len)::VARBIT;
|
27
|
+
ELSIF bits < len THEN
|
28
|
+
RETURN substring(sig FROM 1 FOR bits);
|
29
|
+
END IF;
|
30
|
+
RETURN sig;
|
31
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
32
|
+
|
33
|
+
CREATE FUNCTION @extschema@.sig_set( sig VARBIT, pos INT, val INT ) RETURNS VARBIT AS $$
|
34
|
+
DECLARE
|
35
|
+
len INT;
|
36
|
+
BEGIN
|
37
|
+
len := length(sig);
|
38
|
+
IF pos >= len THEN
|
39
|
+
IF val > 0 THEN
|
40
|
+
RETURN set_bit(@extschema@.sig_resize(sig, pos+1), pos, 1);
|
41
|
+
ELSE
|
42
|
+
RETURN sig;
|
43
|
+
END IF;
|
44
|
+
ELSE
|
45
|
+
RETURN set_bit(sig, pos, val);
|
46
|
+
END IF;
|
47
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
48
|
+
|
49
|
+
CREATE FUNCTION @extschema@.sig_set( sig VARBIT, pos INT ) RETURNS VARBIT AS $$
|
50
|
+
BEGIN
|
51
|
+
RETURN @extschema@.sig_set(sig, pos, 1);
|
52
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
53
|
+
|
54
|
+
CREATE FUNCTION @extschema@.sig_get( sig VARBIT, pos INT ) RETURNS INT AS $$
|
55
|
+
DECLARE
|
56
|
+
len INT;
|
57
|
+
BEGIN
|
58
|
+
len := length(sig);
|
59
|
+
IF pos >= len THEN
|
60
|
+
RETURN 0;
|
61
|
+
ELSE
|
62
|
+
RETURN get_bit(sig, pos);
|
63
|
+
END IF;
|
64
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
65
|
+
|
66
|
+
CREATE FUNCTION @extschema@.sig_length( sig VARBIT ) RETURNS INT AS $$
|
67
|
+
BEGIN
|
68
|
+
RETURN length(sig);
|
69
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
70
|
+
|
71
|
+
CREATE FUNCTION @extschema@.sig_min( sig VARBIT ) RETURNS INT AS $$
|
72
|
+
BEGIN
|
73
|
+
RETURN position('1' in sig) - 1;
|
74
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
75
|
+
|
76
|
+
CREATE FUNCTION @extschema@.sig_and( sig1 VARBIT, sig2 VARBIT ) RETURNS VARBIT AS $$
|
77
|
+
DECLARE
|
78
|
+
len INT;
|
79
|
+
BEGIN
|
80
|
+
len := GREATEST(length(sig1), length(sig2));
|
81
|
+
RETURN bitand(@extschema@.sig_resize(sig1, len), @extschema@.sig_resize(sig2, len)) ;
|
82
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
83
|
+
|
84
|
+
CREATE FUNCTION @extschema@.sig_or( sig1 VARBIT, sig2 VARBIT ) RETURNS VARBIT AS $$
|
85
|
+
DECLARE
|
86
|
+
len INT;
|
87
|
+
BEGIN
|
88
|
+
len := GREATEST(length(sig1), length(sig2));
|
89
|
+
RETURN bitor(@extschema@.sig_resize(sig1, len), @extschema@.sig_resize(sig2, len)) ;
|
90
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
91
|
+
|
92
|
+
CREATE FUNCTION @extschema@.sig_xor( sig1 VARBIT, sig2 VARBIT ) RETURNS VARBIT AS $$
|
93
|
+
DECLARE
|
94
|
+
len INT;
|
95
|
+
BEGIN
|
96
|
+
len := GREATEST(length(sig1), length(sig2));
|
97
|
+
RETURN bitxor(@extschema@.sig_resize(sig1, len), @extschema@.sig_resize(sig2, len)) ;
|
98
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
99
|
+
|
100
|
+
CREATE FUNCTION @extschema@.count( sig VARBIT ) RETURNS INT AS $$
|
101
|
+
BEGIN
|
102
|
+
-- This is, by any measure, horrific. However, it appears to be the only
|
103
|
+
-- way to use PostgreSQL built in functions to count bits in a bit string.
|
104
|
+
RETURN length(replace(sig::TEXT, '0', ''));
|
105
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
106
|
+
|
107
|
+
CREATE FUNCTION @extschema@.contains( sig VARBIT, pos INT ) RETURNS BOOL AS $$
|
108
|
+
BEGIN
|
109
|
+
RETURN @extschema@.sig_get(sig, pos) = 1;
|
110
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
111
|
+
|
112
|
+
CREATE FUNCTION @extschema@.members( sig VARBIT ) RETURNS SETOF INT AS $$
|
113
|
+
BEGIN
|
114
|
+
FOR i IN 0 .. length(sig) - 1 LOOP
|
115
|
+
IF @extschema@.contains(sig, i) THEN
|
116
|
+
RETURN NEXT i;
|
117
|
+
END IF;
|
118
|
+
END LOOP;
|
119
|
+
END $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
120
|
+
|
121
|
+
|
122
|
+
-- operators for faceting
|
123
|
+
|
124
|
+
CREATE OPERATOR @extschema@.& (
|
125
|
+
leftarg = VARBIT,
|
126
|
+
rightarg = VARBIT,
|
127
|
+
procedure = @extschema@.sig_and,
|
128
|
+
commutator = &
|
129
|
+
);
|
130
|
+
|
131
|
+
CREATE OPERATOR @extschema@.| (
|
132
|
+
leftarg = VARBIT,
|
133
|
+
rightarg = VARBIT,
|
134
|
+
procedure = @extschema@.sig_or,
|
135
|
+
commutator = |
|
136
|
+
);
|
137
|
+
|
138
|
+
CREATE OPERATOR @extschema@.+ (
|
139
|
+
leftarg = VARBIT,
|
140
|
+
rightarg = int,
|
141
|
+
procedure = @extschema@.sig_set
|
142
|
+
);
|
143
|
+
|
144
|
+
|
145
|
+
-- aggregate functions for faceting
|
146
|
+
|
147
|
+
CREATE AGGREGATE @extschema@.collect( VARBIT )
|
148
|
+
(
|
149
|
+
sfunc = @extschema@.sig_or,
|
150
|
+
stype = VARBIT
|
151
|
+
);
|
152
|
+
|
153
|
+
CREATE AGGREGATE @extschema@.filter( VARBIT )
|
154
|
+
(
|
155
|
+
sfunc = @extschema@.sig_and,
|
156
|
+
stype = VARBIT
|
157
|
+
);
|
158
|
+
|
159
|
+
CREATE AGGREGATE @extschema@.signature( INT )
|
160
|
+
(
|
161
|
+
sfunc = @extschema@.sig_set,
|
162
|
+
stype = VARBIT,
|
163
|
+
initcond = '0'
|
164
|
+
);-- ============================================================================
|
165
|
+
-- These functions are common to all bindings of the Repertoire faceting API
|
166
|
+
--
|
167
|
+
-- Christopher York
|
168
|
+
-- MIT Hyperstudio
|
169
|
+
-- February 2014
|
170
|
+
-- ============================================================================
|
171
|
+
|
172
|
+
|
173
|
+
-- Aggregator to measure how many bits from a loosely-packed id column would be wasted, if
|
174
|
+
-- they were all collected into a bitset signature. Returns a float between 0 (no waste)
|
175
|
+
-- and 1.0 (all waste). An example of its use:
|
176
|
+
--
|
177
|
+
-- SELECT wastage(id) FROM nobelists
|
178
|
+
-- =# 0.999999
|
179
|
+
--
|
180
|
+
-- ALTER TABLE nobelists ADD COLUMN _packed_id SERIAL
|
181
|
+
-- SELECT wastage(_packed_id) FROM nobelists
|
182
|
+
-- =# 0.015625
|
183
|
+
--
|
184
|
+
CREATE FUNCTION @extschema@.wastage_proportion( state INT[] ) RETURNS double precision AS $$
|
185
|
+
SELECT (1.0 - (state[1]::double precision / (COALESCE(state[2], 0.0) + 1.0)))
|
186
|
+
$$ LANGUAGE sql;
|
187
|
+
|
188
|
+
CREATE FUNCTION @extschema@.wastage_accum( state INT[], val INT ) RETURNS INT[] AS $$
|
189
|
+
SELECT ARRAY[ state[1]+1, GREATEST(state[2], val) ];
|
190
|
+
$$ LANGUAGE sql;
|
191
|
+
|
192
|
+
CREATE AGGREGATE @extschema@.wastage( INT )
|
193
|
+
(
|
194
|
+
sfunc = @extschema@.wastage_accum,
|
195
|
+
stype = INT[],
|
196
|
+
finalfunc = @extschema@.wastage_proportion,
|
197
|
+
initcond = '{0,0}'
|
198
|
+
);
|
Binary file
|
Binary file
|
@@ -74,28 +74,6 @@ repertoire.facet_context = function(context_name, state_fn, options) {
|
|
74
74
|
filter[facet] = filter[facet] || [];
|
75
75
|
}
|
76
76
|
|
77
|
-
//
|
78
|
-
// Calculate facet value counts from webservice
|
79
|
-
//
|
80
|
-
// By default, the url is '/<context>/counts/<facet>'
|
81
|
-
//
|
82
|
-
self.counts = function(facet_name, callback, $elem) {
|
83
|
-
var url = self.facet_url('counts', facet_name);
|
84
|
-
// package up the faceting state and send back to results rendering service
|
85
|
-
self.fetch(self.params(), url, 'json', callback, $elem);
|
86
|
-
};
|
87
|
-
|
88
|
-
//
|
89
|
-
// Update query results from webservice
|
90
|
-
//
|
91
|
-
// By default, the url is '/<context>/counts/<facet>'
|
92
|
-
//
|
93
|
-
self.results = function(type, callback, $elem) {
|
94
|
-
var url = self.facet_url('results');
|
95
|
-
// package up the faceting state and send back to results rendering service
|
96
|
-
self.fetch(self.params(), url, type, callback, $elem);
|
97
|
-
};
|
98
|
-
|
99
77
|
//
|
100
78
|
// Convenience function for constructing faceting urls
|
101
79
|
//
|
@@ -46,13 +46,24 @@ repertoire.facet = function($facet, options) {
|
|
46
46
|
// do not bubble event
|
47
47
|
return false;
|
48
48
|
});
|
49
|
+
|
50
|
+
//
|
51
|
+
// Calculate facet value counts from webservice
|
52
|
+
//
|
53
|
+
// By default, the url is '/<context>/counts/<facet>'
|
54
|
+
//
|
55
|
+
self.fetch = function(facet_name, callback, $elem) {
|
56
|
+
var context = self.context();
|
57
|
+
var url = context.facet_url('counts', facet_name);
|
58
|
+
// package up the faceting state and send back to results rendering service
|
59
|
+
context.fetch(self.params(), url, 'json', callback, $elem);
|
60
|
+
};
|
49
61
|
|
50
62
|
//
|
51
63
|
// Ajax callback for facet value counts
|
52
64
|
//
|
53
65
|
self.reload = function(callback) {
|
54
|
-
|
55
|
-
context.counts(self.facet_name(), callback, $facet);
|
66
|
+
self.fetch(self.facet_name(), callback, $facet);
|
56
67
|
}
|
57
68
|
|
58
69
|
//
|
@@ -58,6 +58,22 @@ repertoire.facet_widget = function($widget, options) {
|
|
58
58
|
return options.context || self.context().name();
|
59
59
|
};
|
60
60
|
|
61
|
+
self.state = function() {
|
62
|
+
if (options.state)
|
63
|
+
return options.state();
|
64
|
+
else return {};
|
65
|
+
}
|
66
|
+
|
67
|
+
//
|
68
|
+
// Return any extra params to send to the web-server.
|
69
|
+
//
|
70
|
+
// By default, params encompass all context state, plus any widget state.
|
71
|
+
//
|
72
|
+
self.params = function() {
|
73
|
+
var context = self.context();
|
74
|
+
return $.extend({}, context.params(), self.state());
|
75
|
+
};
|
76
|
+
|
61
77
|
//
|
62
78
|
// Capitalize and return a string
|
63
79
|
//
|
@@ -25,14 +25,24 @@
|
|
25
25
|
repertoire.results = function($results, options) {
|
26
26
|
// inherit basic facet widget behaviour
|
27
27
|
var self = repertoire.facet_widget($results, options);
|
28
|
-
|
28
|
+
|
29
|
+
//
|
30
|
+
// Update query results from webservice
|
31
|
+
//
|
32
|
+
// By default, the url is '/<context>/counts/<facet>'
|
33
|
+
//
|
34
|
+
self.fetch = function(type, callback, $elem) {
|
35
|
+
var context = self.context();
|
36
|
+
var url = context.facet_url('results');
|
37
|
+
// package up the faceting state and send back to results rendering service
|
38
|
+
context.fetch(self.params(), url, type, callback, $elem);
|
39
|
+
};
|
29
40
|
|
30
41
|
//
|
31
42
|
// Ajax callback for results
|
32
43
|
//
|
33
44
|
self.reload = function(callback) {
|
34
|
-
|
35
|
-
context.results(options.type, callback, $results);
|
45
|
+
self.fetch(options.type, callback, $results);
|
36
46
|
}
|
37
47
|
|
38
48
|
//
|
@@ -70,7 +70,7 @@ repertoire.model = function(options) {
|
|
70
70
|
if ($elem)
|
71
71
|
$elem.addClass(spinnerClass);
|
72
72
|
|
73
|
-
$.ajax({
|
73
|
+
return $.ajax({
|
74
74
|
async: async,
|
75
75
|
url: url,
|
76
76
|
data: self.to_query_string(params),
|
@@ -80,8 +80,9 @@ repertoire.model = function(options) {
|
|
80
80
|
/* beforeSend: function(xhr) { xhr.setRequestHeader("Accept", "application/json") } */
|
81
81
|
success: callback,
|
82
82
|
error: function(request, textStatus, errorThrown) {
|
83
|
-
|
84
|
-
|
83
|
+
if ($elem) {
|
84
|
+
$elem.html(options.error || 'Could not load');
|
85
|
+
};
|
85
86
|
},
|
86
87
|
complete: function () {
|
87
88
|
if ($elem)
|
@@ -24,7 +24,7 @@
|
|
24
24
|
// error - text to display if ajax load fails
|
25
25
|
// injectors - additional jquery markup to inject into widget (see FAQ)
|
26
26
|
// handlers - additional jquery event handlers to add to widget (see FAQ)
|
27
|
-
// state
|
27
|
+
// state - additional pre-processing for params sent to webservice (see FAQ)
|
28
28
|
//
|
29
29
|
// Sub-classes are required to over-ride one method: self.render(). If you wish to
|
30
30
|
// use a data model, store a subclass of rep.wigets/model in your widget.
|
@@ -32,11 +32,11 @@
|
|
32
32
|
repertoire.widget = function(selector, options) {
|
33
33
|
// this object is an abstract class
|
34
34
|
var self = {};
|
35
|
-
|
35
|
+
|
36
36
|
// private variables
|
37
37
|
var $widget = $(selector);
|
38
38
|
options = options || {};
|
39
|
-
|
39
|
+
|
40
40
|
// mix in event handling functionality
|
41
41
|
repertoire.events(self, $widget);
|
42
42
|
|
@@ -47,7 +47,9 @@ repertoire.widget = function(selector, options) {
|
|
47
47
|
register_handlers(options.handlers);
|
48
48
|
|
49
49
|
// load once at beginning
|
50
|
-
|
50
|
+
if (! options.delay_loading) {
|
51
|
+
self.refresh();
|
52
|
+
};
|
51
53
|
}
|
52
54
|
|
53
55
|
//
|
@@ -64,21 +66,21 @@ repertoire.widget = function(selector, options) {
|
|
64
66
|
self.refresh = function() {
|
65
67
|
var callback,
|
66
68
|
callbackStamp;
|
67
|
-
|
69
|
+
|
68
70
|
// pass to custom state processor
|
69
71
|
if (options.state !== undefined)
|
70
72
|
options.state(self);
|
71
73
|
|
72
74
|
// adjust timestamp to most recent ajax call
|
73
75
|
ajaxStamp = callbackStamp = Date.now();
|
74
|
-
|
76
|
+
|
75
77
|
callback = function() {
|
76
78
|
// reject if this is an old ajax request
|
77
79
|
if (callbackStamp < ajaxStamp) return;
|
78
80
|
|
79
81
|
// render the widget
|
80
82
|
var markup = self.render.apply(self, arguments);
|
81
|
-
|
83
|
+
|
82
84
|
// inject any custom markup
|
83
85
|
if (options.injectors !== undefined)
|
84
86
|
// TODO. figure out how to send all args to injectors
|
@@ -105,7 +107,7 @@ repertoire.widget = function(selector, options) {
|
|
105
107
|
// };
|
106
108
|
//
|
107
109
|
// (2) If you just want to tweak the superclass' view:
|
108
|
-
//
|
110
|
+
//
|
109
111
|
// var template_fn = self.render; // idiom to access super.render()
|
110
112
|
// self.render = function() {
|
111
113
|
// var markup = template_fn();
|
@@ -118,8 +120,8 @@ repertoire.widget = function(selector, options) {
|
|
118
120
|
self.render = function() {
|
119
121
|
return $('<div class="rep"/>'); // namespace for all other widget css is 'rep'
|
120
122
|
};
|
121
|
-
|
122
|
-
|
123
|
+
|
124
|
+
|
123
125
|
//
|
124
126
|
// A hook for use when your widget must render the results of an ajax callback. Put
|
125
127
|
// the ajax call in self.reload(). Its results will be passed to self.render().
|
@@ -155,7 +157,7 @@ repertoire.widget = function(selector, options) {
|
|
155
157
|
event_selector = parse_event_selector(event_selector);
|
156
158
|
var event = event_selector[0],
|
157
159
|
selector = event_selector[1]; // why doesn't JS support array decomposition?!?
|
158
|
-
|
160
|
+
|
159
161
|
// bind new handler
|
160
162
|
$widget.bind(event, function (e) {
|
161
163
|
var $el = $(e.target);
|
@@ -172,9 +174,9 @@ repertoire.widget = function(selector, options) {
|
|
172
174
|
}
|
173
175
|
});
|
174
176
|
}
|
175
|
-
|
177
|
+
|
176
178
|
// PRIVATE
|
177
|
-
|
179
|
+
|
178
180
|
// register a collection of event handlers
|
179
181
|
function register_handlers(handlers) {
|
180
182
|
$.each(handlers, function(selector, handler) {
|
@@ -198,7 +200,7 @@ repertoire.widget = function(selector, options) {
|
|
198
200
|
}
|
199
201
|
});
|
200
202
|
}
|
201
|
-
|
203
|
+
|
202
204
|
// parse an event name and selector spec
|
203
205
|
function parse_event_selector(event_selector) {
|
204
206
|
var s = event_selector.split('!');
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: repertoire-faceting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christopher York
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -83,8 +83,13 @@ files:
|
|
83
83
|
- ext/bytea/faceting_bytea.control
|
84
84
|
- ext/common/util.sql
|
85
85
|
- ext/extconf.rb
|
86
|
+
- ext/faceting--0.7.2.sql
|
87
|
+
- ext/faceting_bytea--0.7.2.sql
|
88
|
+
- ext/faceting_varbit--0.7.2.sql
|
86
89
|
- ext/signature/faceting.control
|
87
90
|
- ext/signature/signature.c
|
91
|
+
- ext/signature/signature.o
|
92
|
+
- ext/signature/signature.so
|
88
93
|
- ext/signature/signature.sql
|
89
94
|
- ext/varbit/faceting_varbit.control
|
90
95
|
- ext/varbit/varbit.sql
|