add viz 2 post
This commit is contained in:
parent
886684ec4c
commit
5ed62d23b4
@ -42,7 +42,7 @@ layout: default
|
||||
{% endfor %}
|
||||
{% if prev or next %}
|
||||
<p class="light"><em>
|
||||
This post is part of a series<br/>
|
||||
This post is part of a series:<br/>
|
||||
{% if prev %}
|
||||
Previously: <a href="{{ prev.url | relative_url }}">{{ prev.title }}</a></br>
|
||||
{% endif %}
|
||||
@ -67,7 +67,7 @@ layout: default
|
||||
|
||||
{% if prev or next %}
|
||||
<p class="light"><em>
|
||||
This post is part of a series<br/>
|
||||
If you liked this post, consider checking out other posts in the series:<br/>
|
||||
{% if prev %}
|
||||
Previously: <a href="{{ prev.url | relative_url }}">{{ prev.title }}</a></br>
|
||||
{% endif %}
|
||||
|
42
_posts/2018-11-12-viz-2.md
Normal file
42
_posts/2018-11-12-viz-2.md
Normal file
@ -0,0 +1,42 @@
|
||||
---
|
||||
title: >-
|
||||
Visualization 2
|
||||
description: >-
|
||||
Now in glorious technicolor!
|
||||
series: viz
|
||||
git_repo: https://github.com/mediocregopher/viz.git
|
||||
git_commit: 76caf80afc94655f2a21661714248676ed018328
|
||||
---
|
||||
|
||||
|
||||
<script src="/assets/viz/2/goog/base.js"></script>
|
||||
<script src="/assets/viz/2/cljs_deps.js"></script>
|
||||
<script>goog.require("viz.core");</script>
|
||||
<p align="center"><canvas id="viz"></canvas></p>
|
||||
|
||||
This visualization builds on the previous. Structurally the cortesian grid has
|
||||
been turned into an isometric one, but this is more of an environmental change
|
||||
than a behavioral one.
|
||||
|
||||
Behavioral changes which were made:
|
||||
|
||||
* When a live point is deciding its next spawn points, it first sorts the set of
|
||||
empty adjacent points from closest-to-the-center to farthest. Then it randomly
|
||||
chooses a number `n` between `0` to `N` (where `N` is the size of that sorted
|
||||
set) and spawns new points in the first `n` points of the sorted set.
|
||||
|
||||
* Each point is spawned with an attached color, where the color chosen is a
|
||||
slightly different hue than its parent. The change is deterministic, so all
|
||||
child points of the same generation have the same color.
|
||||
|
||||
The second change is purely cosmetic, but does create a mesmerizing effect. The
|
||||
first change alters the behavior dramatically.
|
||||
|
||||
In the previous visualization the points moved around in groups aimlessly. Now
|
||||
the groups are all competing for the same thing, the center, and as a result
|
||||
congregate and are able to be viewed as a larger whole.
|
||||
|
||||
The constant churn of the whole takes many forms, from a spiral in the center,
|
||||
to waves crashing against each other, to outright chaos, to random purges of
|
||||
nearly all points. Each form lasts for only a few seconds before giving way to
|
||||
another.
|
10762
assets/viz/2/cljs/core.cljs
Normal file
10762
assets/viz/2/cljs/core.cljs
Normal file
File diff suppressed because it is too large
Load Diff
35801
assets/viz/2/cljs/core.js
Normal file
35801
assets/viz/2/cljs/core.js
Normal file
File diff suppressed because it is too large
Load Diff
1
assets/viz/2/cljs/core.js.map
Normal file
1
assets/viz/2/cljs/core.js.map
Normal file
File diff suppressed because one or more lines are too long
368
assets/viz/2/cljs/core/constants.js
Normal file
368
assets/viz/2/cljs/core/constants.js
Normal file
@ -0,0 +1,368 @@
|
||||
goog.provide('cljs.core.constants');
|
||||
goog.require('cljs.core');
|
||||
cljs.core.cst$kw$y = new cljs.core.Keyword(null,"y","y",-1757859776);
|
||||
cljs.core.cst$sym$form = new cljs.core.Symbol(null,"form","form",16469056,null);
|
||||
cljs.core.cst$kw$key_DASH_code = new cljs.core.Keyword(null,"key-code","key-code",-1732114304);
|
||||
cljs.core.cst$sym$tag = new cljs.core.Symbol(null,"tag","tag",350170304,null);
|
||||
cljs.core.cst$sym$_AMPERSAND_ = new cljs.core.Symbol(null,"&","&",-2144855648,null);
|
||||
cljs.core.cst$sym$stepper = new cljs.core.Symbol(null,"stepper","stepper",1159163296,null);
|
||||
cljs.core.cst$kw$grid_DASH_def = new cljs.core.Keyword(null,"grid-def","grid-def",-392588768);
|
||||
cljs.core.cst$sym$uuid = new cljs.core.Symbol(null,"uuid","uuid",-504564192,null);
|
||||
cljs.core.cst$kw$shift = new cljs.core.Keyword(null,"shift","shift",997140064);
|
||||
cljs.core.cst$kw$features = new cljs.core.Keyword(null,"features","features",-1146962336);
|
||||
cljs.core.cst$sym$$endDraw = new cljs.core.Symbol(null,".endDraw",".endDraw",795589408,null);
|
||||
cljs.core.cst$kw$open = new cljs.core.Keyword(null,"open","open",-1763596448);
|
||||
cljs.core.cst$kw$baseline = new cljs.core.Keyword(null,"baseline","baseline",1151033280);
|
||||
cljs.core.cst$sym$end = new cljs.core.Symbol(null,"end","end",1372345569,null);
|
||||
cljs.core.cst$kw$disable_DASH_stroke_DASH_perspective = new cljs.core.Keyword(null,"disable-stroke-perspective","disable-stroke-perspective",479198433);
|
||||
cljs.core.cst$kw$active_DASH_node_DASH_ids = new cljs.core.Keyword(null,"active-node-ids","active-node-ids",-398210751);
|
||||
cljs.core.cst$sym$defrecord_STAR_ = new cljs.core.Symbol(null,"defrecord*","defrecord*",-1936366207,null);
|
||||
cljs.core.cst$sym$base = new cljs.core.Symbol(null,"base","base",1825810849,null);
|
||||
cljs.core.cst$sym$obj = new cljs.core.Symbol(null,"obj","obj",-1672671807,null);
|
||||
cljs.core.cst$kw$hsb = new cljs.core.Keyword(null,"hsb","hsb",-753472031);
|
||||
cljs.core.cst$kw$quads = new cljs.core.Keyword(null,"quads","quads",1347497505);
|
||||
cljs.core.cst$sym$fqn = new cljs.core.Symbol(null,"fqn","fqn",-1749334463,null);
|
||||
cljs.core.cst$kw$arrow = new cljs.core.Keyword(null,"arrow","arrow",1071351425);
|
||||
cljs.core.cst$kw$dilate = new cljs.core.Keyword(null,"dilate","dilate",1504745153);
|
||||
cljs.core.cst$sym$first = new cljs.core.Symbol(null,"first","first",996428481,null);
|
||||
cljs.core.cst$sym$quil$core_SLASH_current_DASH_fill = new cljs.core.Symbol("quil.core","current-fill","quil.core/current-fill",269663137,null);
|
||||
cljs.core.cst$sym$try = new cljs.core.Symbol(null,"try","try",-1273693247,null);
|
||||
cljs.core.cst$sym$has_DASH_nil_QMARK_ = new cljs.core.Symbol(null,"has-nil?","has-nil?",825886722,null);
|
||||
cljs.core.cst$kw$min = new cljs.core.Keyword(null,"min","min",444991522);
|
||||
cljs.core.cst$sym$quil$core_SLASH__STAR_graphics_STAR_ = new cljs.core.Symbol("quil.core","*graphics*","quil.core/*graphics*",-1088142302,null);
|
||||
cljs.core.cst$kw$quad_DASH_strip = new cljs.core.Keyword(null,"quad-strip","quad-strip",-1297270686);
|
||||
cljs.core.cst$kw$down = new cljs.core.Keyword(null,"down","down",1565245570);
|
||||
cljs.core.cst$kw$grid_DASH_width = new cljs.core.Keyword(null,"grid-width","grid-width",837583106);
|
||||
cljs.core.cst$kw$disable_DASH_depth_DASH_mask = new cljs.core.Keyword(null,"disable-depth-mask","disable-depth-mask",3298562);
|
||||
cljs.core.cst$kw$pixels_DASH_in_DASH_360 = new cljs.core.Keyword(null,"pixels-in-360","pixels-in-360",1789567298);
|
||||
cljs.core.cst$kw$frame_DASH_rate = new cljs.core.Keyword(null,"frame-rate","frame-rate",-994918942);
|
||||
cljs.core.cst$kw$p_DASH_y = new cljs.core.Keyword(null,"p-y","p-y",-530704830);
|
||||
cljs.core.cst$kw$step_DASH_size = new cljs.core.Keyword(null,"step-size","step-size",1545609922);
|
||||
cljs.core.cst$kw$zoom = new cljs.core.Keyword(null,"zoom","zoom",-1827487038);
|
||||
cljs.core.cst$sym$rear = new cljs.core.Symbol(null,"rear","rear",-900164830,null);
|
||||
cljs.core.cst$sym$hierarchy = new cljs.core.Symbol(null,"hierarchy","hierarchy",587061186,null);
|
||||
cljs.core.cst$sym$iter = new cljs.core.Symbol(null,"iter","iter",-1346195486,null);
|
||||
cljs.core.cst$sym$cljs$core_SLASH_binding = new cljs.core.Symbol("cljs.core","binding","cljs.core/binding",2050379843,null);
|
||||
cljs.core.cst$kw$burn = new cljs.core.Keyword(null,"burn","burn",-458179293);
|
||||
cljs.core.cst$sym$step = new cljs.core.Symbol(null,"step","step",-1365547645,null);
|
||||
cljs.core.cst$sym$tr__10249__auto__ = new cljs.core.Symbol(null,"tr__10249__auto__","tr__10249__auto__",-739839485,null);
|
||||
cljs.core.cst$sym$boolean = new cljs.core.Symbol(null,"boolean","boolean",-278886877,null);
|
||||
cljs.core.cst$kw$key_DASH_typed = new cljs.core.Keyword(null,"key-typed","key-typed",-876037597);
|
||||
cljs.core.cst$sym$update_DASH_count = new cljs.core.Symbol(null,"update-count","update-count",-411982269,null);
|
||||
cljs.core.cst$kw$mouse_DASH_clicked = new cljs.core.Keyword(null,"mouse-clicked","mouse-clicked",-199339421);
|
||||
cljs.core.cst$sym$method_DASH_table = new cljs.core.Symbol(null,"method-table","method-table",-1878263165,null);
|
||||
cljs.core.cst$kw$mouse_DASH_released = new cljs.core.Keyword(null,"mouse-released","mouse-released",-664480061);
|
||||
cljs.core.cst$kw$posterize = new cljs.core.Keyword(null,"posterize","posterize",-148251901);
|
||||
cljs.core.cst$sym$chunk = new cljs.core.Symbol(null,"chunk","chunk",449371907,null);
|
||||
cljs.core.cst$kw$fn = new cljs.core.Keyword(null,"fn","fn",-1175266204);
|
||||
cljs.core.cst$sym$quil$sketch_SLASH_with_DASH_sketch = new cljs.core.Symbol("quil.sketch","with-sketch","quil.sketch/with-sketch",-634067708,null);
|
||||
cljs.core.cst$sym$i = new cljs.core.Symbol(null,"i","i",253690212,null);
|
||||
cljs.core.cst$kw$f8 = new cljs.core.Keyword(null,"f8","f8",-2141475484);
|
||||
cljs.core.cst$sym$rest = new cljs.core.Symbol(null,"rest","rest",398835108,null);
|
||||
cljs.core.cst$kw$meta = new cljs.core.Keyword(null,"meta","meta",1499536964);
|
||||
cljs.core.cst$sym$quil$core_SLASH_translate = new cljs.core.Symbol("quil.core","translate","quil.core/translate",150889028,null);
|
||||
cljs.core.cst$sym$old_DASH_fill__10239__auto__ = new cljs.core.Symbol(null,"old-fill__10239__auto__","old-fill__10239__auto__",-4319548,null);
|
||||
cljs.core.cst$kw$screen = new cljs.core.Keyword(null,"screen","screen",1990059748);
|
||||
cljs.core.cst$kw$enable_DASH_depth_DASH_test = new cljs.core.Keyword(null,"enable-depth-test","enable-depth-test",1519326084);
|
||||
cljs.core.cst$kw$mouse_DASH_exited = new cljs.core.Keyword(null,"mouse-exited","mouse-exited",-483205244);
|
||||
cljs.core.cst$kw$gray = new cljs.core.Keyword(null,"gray","gray",1013268388);
|
||||
cljs.core.cst$kw$frame = new cljs.core.Keyword(null,"frame","frame",-1711082588);
|
||||
cljs.core.cst$kw$enable_DASH_depth_DASH_sort = new cljs.core.Keyword(null,"enable-depth-sort","enable-depth-sort",-383089627);
|
||||
cljs.core.cst$kw$f1 = new cljs.core.Keyword(null,"f1","f1",1714532389);
|
||||
cljs.core.cst$kw$dup = new cljs.core.Keyword(null,"dup","dup",556298533);
|
||||
cljs.core.cst$kw$java2d = new cljs.core.Keyword(null,"java2d","java2d",166099237);
|
||||
cljs.core.cst$kw$corner = new cljs.core.Keyword(null,"corner","corner",1296717125);
|
||||
cljs.core.cst$kw$disable_DASH_texture_DASH_mipmaps = new cljs.core.Keyword(null,"disable-texture-mipmaps","disable-texture-mipmaps",1697917541);
|
||||
cljs.core.cst$kw$key = new cljs.core.Keyword(null,"key","key",-1516042587);
|
||||
cljs.core.cst$sym$comp = new cljs.core.Symbol(null,"comp","comp",-1462482139,null);
|
||||
cljs.core.cst$sym$dispatch_DASH_fn = new cljs.core.Symbol(null,"dispatch-fn","dispatch-fn",-1401088155,null);
|
||||
cljs.core.cst$kw$darkest = new cljs.core.Keyword(null,"darkest","darkest",68197253);
|
||||
cljs.core.cst$kw$f10 = new cljs.core.Keyword(null,"f10","f10",627525541);
|
||||
cljs.core.cst$kw$dodge = new cljs.core.Keyword(null,"dodge","dodge",-1556666427);
|
||||
cljs.core.cst$kw$bottom = new cljs.core.Keyword(null,"bottom","bottom",-1550509018);
|
||||
cljs.core.cst$kw$bevel = new cljs.core.Keyword(null,"bevel","bevel",2090515654);
|
||||
cljs.core.cst$kw$else = new cljs.core.Keyword(null,"else","else",-1508377146);
|
||||
cljs.core.cst$kw$on_DASH_close = new cljs.core.Keyword(null,"on-close","on-close",-761178394);
|
||||
cljs.core.cst$kw$disable_DASH_stroke_DASH_pure = new cljs.core.Keyword(null,"disable-stroke-pure","disable-stroke-pure",735493926);
|
||||
cljs.core.cst$kw$replace = new cljs.core.Keyword(null,"replace","replace",-786587770);
|
||||
cljs.core.cst$kw$next_DASH_id = new cljs.core.Keyword(null,"next-id","next-id",-224240762);
|
||||
cljs.core.cst$kw$alt = new cljs.core.Keyword(null,"alt","alt",-3214426);
|
||||
cljs.core.cst$sym$left = new cljs.core.Symbol(null,"left","left",1241415590,null);
|
||||
cljs.core.cst$sym$ns_STAR_ = new cljs.core.Symbol(null,"ns*","ns*",1840949383,null);
|
||||
cljs.core.cst$kw$cljs$core_SLASH_none = new cljs.core.Keyword("cljs.core","none","cljs.core/none",926646439);
|
||||
cljs.core.cst$sym$shift = new cljs.core.Symbol(null,"shift","shift",-1657295705,null);
|
||||
cljs.core.cst$sym$iters = new cljs.core.Symbol(null,"iters","iters",719353031,null);
|
||||
cljs.core.cst$kw$button = new cljs.core.Keyword(null,"button","button",1456579943);
|
||||
cljs.core.cst$kw$top = new cljs.core.Keyword(null,"top","top",-1856271961);
|
||||
cljs.core.cst$kw$mouse_DASH_wheel = new cljs.core.Keyword(null,"mouse-wheel","mouse-wheel",1811662439);
|
||||
cljs.core.cst$sym$cljs$core_SLASH_apply = new cljs.core.Symbol("cljs.core","apply","cljs.core/apply",1757277831,null);
|
||||
cljs.core.cst$sym$xform = new cljs.core.Symbol(null,"xform","xform",-85179481,null);
|
||||
cljs.core.cst$kw$validator = new cljs.core.Keyword(null,"validator","validator",-1966190681);
|
||||
cljs.core.cst$kw$disable_DASH_depth_DASH_test = new cljs.core.Keyword(null,"disable-depth-test","disable-depth-test",284606407);
|
||||
cljs.core.cst$sym$finally = new cljs.core.Symbol(null,"finally","finally",-1065347064,null);
|
||||
cljs.core.cst$kw$keyPressed = new cljs.core.Keyword(null,"keyPressed","keyPressed",1791025256);
|
||||
cljs.core.cst$kw$default = new cljs.core.Keyword(null,"default","default",-1987822328);
|
||||
cljs.core.cst$sym$prefer_DASH_table = new cljs.core.Symbol(null,"prefer-table","prefer-table",462168584,null);
|
||||
cljs.core.cst$kw$bar = new cljs.core.Keyword(null,"bar","bar",-1386246584);
|
||||
cljs.core.cst$sym$loop_STAR_ = new cljs.core.Symbol(null,"loop*","loop*",615029416,null);
|
||||
cljs.core.cst$sym$watches = new cljs.core.Symbol(null,"watches","watches",1367433992,null);
|
||||
cljs.core.cst$kw$ns = new cljs.core.Keyword(null,"ns","ns",441598760);
|
||||
cljs.core.cst$kw$grid = new cljs.core.Keyword(null,"grid","grid",402978600);
|
||||
cljs.core.cst$kw$pie = new cljs.core.Keyword(null,"pie","pie",1530441672);
|
||||
cljs.core.cst$sym$quil$core_SLASH_pop_DASH_matrix = new cljs.core.Symbol("quil.core","pop-matrix","quil.core/pop-matrix",310892617,null);
|
||||
cljs.core.cst$kw$decor = new cljs.core.Keyword(null,"decor","decor",-1730969431);
|
||||
cljs.core.cst$kw$w = new cljs.core.Keyword(null,"w","w",354169001);
|
||||
cljs.core.cst$sym$bitmap = new cljs.core.Symbol(null,"bitmap","bitmap",501334601,null);
|
||||
cljs.core.cst$kw$enable_DASH_stroke_DASH_perspective = new cljs.core.Keyword(null,"enable-stroke-perspective","enable-stroke-perspective",-259923319);
|
||||
cljs.core.cst$sym$_seq = new cljs.core.Symbol(null,"_seq","_seq",-449557847,null);
|
||||
cljs.core.cst$sym$nil_DASH_val = new cljs.core.Symbol(null,"nil-val","nil-val",-513933559,null);
|
||||
cljs.core.cst$kw$opengl = new cljs.core.Keyword(null,"opengl","opengl",-614998103);
|
||||
cljs.core.cst$kw$exit_DASH_wait_DASH_frames = new cljs.core.Keyword(null,"exit-wait-frames","exit-wait-frames",1417213098);
|
||||
cljs.core.cst$kw$mouse_DASH_moved = new cljs.core.Keyword(null,"mouse-moved","mouse-moved",-1918152310);
|
||||
cljs.core.cst$kw$parent_DASH_pos = new cljs.core.Keyword(null,"parent-pos","parent-pos",-282368566);
|
||||
cljs.core.cst$sym$v = new cljs.core.Symbol(null,"v","v",1661996586,null);
|
||||
cljs.core.cst$kw$safe_DASH_draw_DASH_fn = new cljs.core.Keyword(null,"safe-draw-fn","safe-draw-fn",1454900202);
|
||||
cljs.core.cst$kw$chord = new cljs.core.Keyword(null,"chord","chord",-696248342);
|
||||
cljs.core.cst$sym$riter = new cljs.core.Symbol(null,"riter","riter",-237834262,null);
|
||||
cljs.core.cst$sym$__hash = new cljs.core.Symbol(null,"__hash","__hash",-1328796629,null);
|
||||
cljs.core.cst$kw$rgb = new cljs.core.Keyword(null,"rgb","rgb",1432123467);
|
||||
cljs.core.cst$sym$meta = new cljs.core.Symbol(null,"meta","meta",-1154898805,null);
|
||||
cljs.core.cst$sym$_meta = new cljs.core.Symbol(null,"_meta","_meta",-1716892533,null);
|
||||
cljs.core.cst$sym$$dispose = new cljs.core.Symbol(null,".dispose",".dispose",-1697594101,null);
|
||||
cljs.core.cst$kw$lines = new cljs.core.Keyword(null,"lines","lines",-700165781);
|
||||
cljs.core.cst$sym$afn = new cljs.core.Symbol(null,"afn","afn",216963467,null);
|
||||
cljs.core.cst$kw$argb = new cljs.core.Keyword(null,"argb","argb",633844107);
|
||||
cljs.core.cst$kw$mouseOut = new cljs.core.Keyword(null,"mouseOut","mouseOut",-386669045);
|
||||
cljs.core.cst$kw$move = new cljs.core.Keyword(null,"move","move",-2110884309);
|
||||
cljs.core.cst$sym$tree = new cljs.core.Symbol(null,"tree","tree",1444219499,null);
|
||||
cljs.core.cst$sym$fn = new cljs.core.Symbol(null,"fn","fn",465265323,null);
|
||||
cljs.core.cst$kw$f5 = new cljs.core.Keyword(null,"f5","f5",1587057387);
|
||||
cljs.core.cst$kw$settings = new cljs.core.Keyword(null,"settings","settings",1556144875);
|
||||
cljs.core.cst$sym$front = new cljs.core.Symbol(null,"front","front",117022539,null);
|
||||
cljs.core.cst$sym$buf = new cljs.core.Symbol(null,"buf","buf",1426618187,null);
|
||||
cljs.core.cst$kw$pos = new cljs.core.Keyword(null,"pos","pos",-864607220);
|
||||
cljs.core.cst$kw$gif_DASH_seconds = new cljs.core.Keyword(null,"gif-seconds","gif-seconds",1861397548);
|
||||
cljs.core.cst$kw$command = new cljs.core.Keyword(null,"command","command",-894540724);
|
||||
cljs.core.cst$kw$mouseScrolled = new cljs.core.Keyword(null,"mouseScrolled","mouseScrolled",31878252);
|
||||
cljs.core.cst$sym$next_DASH_entry = new cljs.core.Symbol(null,"next-entry","next-entry",1091342476,null);
|
||||
cljs.core.cst$kw$val = new cljs.core.Keyword(null,"val","val",128701612);
|
||||
cljs.core.cst$sym$key = new cljs.core.Symbol(null,"key","key",124488940,null);
|
||||
cljs.core.cst$sym$_next = new cljs.core.Symbol(null,"_next","_next",101877036,null);
|
||||
cljs.core.cst$sym$quil$core_SLASH_stroke = new cljs.core.Symbol("quil.core","stroke","quil.core/stroke",577473004,null);
|
||||
cljs.core.cst$kw$update = new cljs.core.Keyword(null,"update","update",1045576396);
|
||||
cljs.core.cst$sym$root_DASH_iter = new cljs.core.Symbol(null,"root-iter","root-iter",1974672108,null);
|
||||
cljs.core.cst$sym$do = new cljs.core.Symbol(null,"do","do",1686842252,null);
|
||||
cljs.core.cst$sym$vec = new cljs.core.Symbol(null,"vec","vec",982683596,null);
|
||||
cljs.core.cst$sym$js_SLASH_Processing$prototype$PConstants = new cljs.core.Symbol("js","Processing.prototype.PConstants","js/Processing.prototype.PConstants",2034048972,null);
|
||||
cljs.core.cst$kw$miter = new cljs.core.Keyword(null,"miter","miter",327727052);
|
||||
cljs.core.cst$kw$points = new cljs.core.Keyword(null,"points","points",-1486596883);
|
||||
cljs.core.cst$kw$fallback_DASH_impl = new cljs.core.Keyword(null,"fallback-impl","fallback-impl",-1501286995);
|
||||
cljs.core.cst$kw$hand = new cljs.core.Keyword(null,"hand","hand",791601933);
|
||||
cljs.core.cst$kw$flush_DASH_on_DASH_newline = new cljs.core.Keyword(null,"flush-on-newline","flush-on-newline",-151457939);
|
||||
cljs.core.cst$kw$mouseDragged = new cljs.core.Keyword(null,"mouseDragged","mouseDragged",129975181);
|
||||
cljs.core.cst$sym$default_DASH_dispatch_DASH_val = new cljs.core.Symbol(null,"default-dispatch-val","default-dispatch-val",-1231201266,null);
|
||||
cljs.core.cst$kw$no_DASH_test = new cljs.core.Keyword(null,"no-test","no-test",-1679482642);
|
||||
cljs.core.cst$kw$close = new cljs.core.Keyword(null,"close","close",1835149582);
|
||||
cljs.core.cst$kw$roots = new cljs.core.Keyword(null,"roots","roots",-1088919250);
|
||||
cljs.core.cst$sym$validator = new cljs.core.Symbol(null,"validator","validator",-325659154,null);
|
||||
cljs.core.cst$kw$radius = new cljs.core.Keyword(null,"radius","radius",-2073122258);
|
||||
cljs.core.cst$kw$normal = new cljs.core.Keyword(null,"normal","normal",-1519123858);
|
||||
cljs.core.cst$sym$letfn_STAR_ = new cljs.core.Symbol(null,"letfn*","letfn*",-110097810,null);
|
||||
cljs.core.cst$sym$if = new cljs.core.Symbol(null,"if","if",1181717262,null);
|
||||
cljs.core.cst$kw$s = new cljs.core.Keyword(null,"s","s",1705939918);
|
||||
cljs.core.cst$sym$arr = new cljs.core.Symbol(null,"arr","arr",2115492975,null);
|
||||
cljs.core.cst$kw$threshold = new cljs.core.Keyword(null,"threshold","threshold",204221583);
|
||||
cljs.core.cst$sym$new = new cljs.core.Symbol(null,"new","new",-444906321,null);
|
||||
cljs.core.cst$kw$rotate_DASH_on = new cljs.core.Keyword(null,"rotate-on","rotate-on",-1282225937);
|
||||
cljs.core.cst$kw$up = new cljs.core.Keyword(null,"up","up",-269712113);
|
||||
cljs.core.cst$kw$descendants = new cljs.core.Keyword(null,"descendants","descendants",1824886031);
|
||||
cljs.core.cst$kw$renderer = new cljs.core.Keyword(null,"renderer","renderer",336841071);
|
||||
cljs.core.cst$sym$ns = new cljs.core.Symbol(null,"ns","ns",2082130287,null);
|
||||
cljs.core.cst$kw$size = new cljs.core.Keyword(null,"size","size",1098693007);
|
||||
cljs.core.cst$kw$title = new cljs.core.Keyword(null,"title","title",636505583);
|
||||
cljs.core.cst$kw$tail_DASH_length = new cljs.core.Keyword(null,"tail-length","tail-length",-2007115089);
|
||||
cljs.core.cst$kw$center = new cljs.core.Keyword(null,"center","center",-748944368);
|
||||
cljs.core.cst$kw$setup = new cljs.core.Keyword(null,"setup","setup",1987730512);
|
||||
cljs.core.cst$kw$mouse_DASH_pressed = new cljs.core.Keyword(null,"mouse-pressed","mouse-pressed",736955536);
|
||||
cljs.core.cst$kw$ancestors = new cljs.core.Keyword(null,"ancestors","ancestors",-776045424);
|
||||
cljs.core.cst$kw$middleware = new cljs.core.Keyword(null,"middleware","middleware",1462115504);
|
||||
cljs.core.cst$kw$round = new cljs.core.Keyword(null,"round","round",2009433328);
|
||||
cljs.core.cst$kw$disable_DASH_optimized_DASH_stroke = new cljs.core.Keyword(null,"disable-optimized-stroke","disable-optimized-stroke",74038544);
|
||||
cljs.core.cst$sym$meta8588 = new cljs.core.Symbol(null,"meta8588","meta8588",1105839504,null);
|
||||
cljs.core.cst$sym$value = new cljs.core.Symbol(null,"value","value",1946509744,null);
|
||||
cljs.core.cst$kw$focus_DASH_gained = new cljs.core.Keyword(null,"focus-gained","focus-gained",-857086384);
|
||||
cljs.core.cst$sym$name = new cljs.core.Symbol(null,"name","name",-810760592,null);
|
||||
cljs.core.cst$sym$gr__10259__auto__ = new cljs.core.Symbol(null,"gr__10259__auto__","gr__10259__auto__",-992087344,null);
|
||||
cljs.core.cst$kw$readably = new cljs.core.Keyword(null,"readably","readably",1129599760);
|
||||
cljs.core.cst$kw$global_DASH_key_DASH_events = new cljs.core.Keyword(null,"global-key-events","global-key-events",335064944);
|
||||
cljs.core.cst$kw$more_DASH_marker = new cljs.core.Keyword(null,"more-marker","more-marker",-14717935);
|
||||
cljs.core.cst$sym$cljs$core_SLASH_let = new cljs.core.Symbol("cljs.core","let","cljs.core/let",-308701135,null);
|
||||
cljs.core.cst$sym$fields = new cljs.core.Symbol(null,"fields","fields",-291534703,null);
|
||||
cljs.core.cst$kw$corners = new cljs.core.Keyword(null,"corners","corners",-137817903);
|
||||
cljs.core.cst$sym$method_DASH_cache = new cljs.core.Symbol(null,"method-cache","method-cache",1230193905,null);
|
||||
cljs.core.cst$kw$z = new cljs.core.Keyword(null,"z","z",-789527183);
|
||||
cljs.core.cst$sym$nexts = new cljs.core.Symbol(null,"nexts","nexts",-1683579407,null);
|
||||
cljs.core.cst$kw$f11 = new cljs.core.Keyword(null,"f11","f11",-1417398799);
|
||||
cljs.core.cst$kw$host = new cljs.core.Keyword(null,"host","host",-1558485167);
|
||||
cljs.core.cst$sym$edit = new cljs.core.Symbol(null,"edit","edit",-1302639,null);
|
||||
cljs.core.cst$sym$editable_QMARK_ = new cljs.core.Symbol(null,"editable?","editable?",-164945806,null);
|
||||
cljs.core.cst$kw$opaque = new cljs.core.Keyword(null,"opaque","opaque",-1243552654);
|
||||
cljs.core.cst$kw$straight = new cljs.core.Keyword(null,"straight","straight",-1252567854);
|
||||
cljs.core.cst$sym$base_DASH_count = new cljs.core.Symbol(null,"base-count","base-count",-1180647182,null);
|
||||
cljs.core.cst$kw$overlay = new cljs.core.Keyword(null,"overlay","overlay",-139131598);
|
||||
cljs.core.cst$kw$mouse_DASH_entered = new cljs.core.Keyword(null,"mouse-entered","mouse-entered",811350322);
|
||||
cljs.core.cst$sym$collision_DASH_hash = new cljs.core.Symbol(null,"collision-hash","collision-hash",-35831342,null);
|
||||
cljs.core.cst$kw$forest = new cljs.core.Keyword(null,"forest","forest",278860306);
|
||||
cljs.core.cst$sym$deftype_STAR_ = new cljs.core.Symbol(null,"deftype*","deftype*",962659890,null);
|
||||
cljs.core.cst$sym$let_STAR_ = new cljs.core.Symbol(null,"let*","let*",1920721458,null);
|
||||
cljs.core.cst$kw$enable_DASH_opengl_DASH_errors = new cljs.core.Keyword(null,"enable-opengl-errors","enable-opengl-errors",89998962);
|
||||
cljs.core.cst$kw$leaves = new cljs.core.Keyword(null,"leaves","leaves",-2143630574);
|
||||
cljs.core.cst$sym$start = new cljs.core.Symbol(null,"start","start",1285322546,null);
|
||||
cljs.core.cst$sym$coll = new cljs.core.Symbol(null,"coll","coll",-1006698606,null);
|
||||
cljs.core.cst$sym$not_DASH_native = new cljs.core.Symbol(null,"not-native","not-native",-236392494,null);
|
||||
cljs.core.cst$sym$js_STAR_ = new cljs.core.Symbol(null,"js*","js*",-1134233646,null);
|
||||
cljs.core.cst$kw$enable_DASH_stroke_DASH_pure = new cljs.core.Keyword(null,"enable-stroke-pure","enable-stroke-pure",881345587);
|
||||
cljs.core.cst$sym$strobj = new cljs.core.Symbol(null,"strobj","strobj",1088091283,null);
|
||||
cljs.core.cst$kw$nodes = new cljs.core.Keyword(null,"nodes","nodes",-2099585805);
|
||||
cljs.core.cst$kw$no_DASH_safe_DASH_draw = new cljs.core.Keyword(null,"no-safe-draw","no-safe-draw",-1157778157);
|
||||
cljs.core.cst$kw$blur = new cljs.core.Keyword(null,"blur","blur",-453500461);
|
||||
cljs.core.cst$sym$_rest = new cljs.core.Symbol(null,"_rest","_rest",-2100466189,null);
|
||||
cljs.core.cst$kw$project = new cljs.core.Keyword(null,"project","project",1124394579);
|
||||
cljs.core.cst$kw$triangle_DASH_fan = new cljs.core.Keyword(null,"triangle-fan","triangle-fan",1743150739);
|
||||
cljs.core.cst$kw$focus_DASH_lost = new cljs.core.Keyword(null,"focus-lost","focus-lost",-554849613);
|
||||
cljs.core.cst$sym$fn_STAR_ = new cljs.core.Symbol(null,"fn*","fn*",-752876845,null);
|
||||
cljs.core.cst$kw$f3 = new cljs.core.Keyword(null,"f3","f3",1954829043);
|
||||
cljs.core.cst$sym$val = new cljs.core.Symbol(null,"val","val",1769233139,null);
|
||||
cljs.core.cst$sym$ascending_QMARK_ = new cljs.core.Symbol(null,"ascending?","ascending?",-1938452653,null);
|
||||
cljs.core.cst$sym$recur = new cljs.core.Symbol(null,"recur","recur",1202958259,null);
|
||||
cljs.core.cst$sym$ci = new cljs.core.Symbol(null,"ci","ci",2049808339,null);
|
||||
cljs.core.cst$kw$enable_DASH_depth_DASH_mask = new cljs.core.Keyword(null,"enable-depth-mask","enable-depth-mask",872785875);
|
||||
cljs.core.cst$kw$key_DASH_pressed = new cljs.core.Keyword(null,"key-pressed","key-pressed",-757100364);
|
||||
cljs.core.cst$kw$key_DASH_released = new cljs.core.Keyword(null,"key-released","key-released",215919828);
|
||||
cljs.core.cst$kw$print_DASH_length = new cljs.core.Keyword(null,"print-length","print-length",1931866356);
|
||||
cljs.core.cst$kw$max = new cljs.core.Keyword(null,"max","max",61366548);
|
||||
cljs.core.cst$kw$foo = new cljs.core.Keyword(null,"foo","foo",1268894036);
|
||||
cljs.core.cst$kw$f2 = new cljs.core.Keyword(null,"f2","f2",396168596);
|
||||
cljs.core.cst$kw$keyReleased = new cljs.core.Keyword(null,"keyReleased","keyReleased",541714964);
|
||||
cljs.core.cst$kw$id = new cljs.core.Keyword(null,"id","id",-1388402092);
|
||||
cljs.core.cst$sym$state = new cljs.core.Symbol(null,"state","state",-348086572,null);
|
||||
cljs.core.cst$kw$control = new cljs.core.Keyword(null,"control","control",1892578036);
|
||||
cljs.core.cst$kw$ok = new cljs.core.Keyword(null,"ok","ok",967785236);
|
||||
cljs.core.cst$kw$difference = new cljs.core.Keyword(null,"difference","difference",1916101396);
|
||||
cljs.core.cst$sym$quil$core_SLASH_push_DASH_matrix = new cljs.core.Symbol("quil.core","push-matrix","quil.core/push-matrix",1356326676,null);
|
||||
cljs.core.cst$kw$cljs$core_SLASH_halt = new cljs.core.Keyword("cljs.core","halt","cljs.core/halt",-1049036715);
|
||||
cljs.core.cst$kw$mouseClicked = new cljs.core.Keyword(null,"mouseClicked","mouseClicked",1764302965);
|
||||
cljs.core.cst$kw$square = new cljs.core.Keyword(null,"square","square",812434677);
|
||||
cljs.core.cst$sym$cached_DASH_hierarchy = new cljs.core.Symbol(null,"cached-hierarchy","cached-hierarchy",-1085460203,null);
|
||||
cljs.core.cst$kw$enable_DASH_optimized_DASH_stroke = new cljs.core.Keyword(null,"enable-optimized-stroke","enable-optimized-stroke",1537575253);
|
||||
cljs.core.cst$kw$parent_DASH_id = new cljs.core.Keyword(null,"parent-id","parent-id",-1400729131);
|
||||
cljs.core.cst$sym$s = new cljs.core.Symbol(null,"s","s",-948495851,null);
|
||||
cljs.core.cst$kw$parents = new cljs.core.Keyword(null,"parents","parents",-2027538891);
|
||||
cljs.core.cst$sym$cnt = new cljs.core.Symbol(null,"cnt","cnt",1924510325,null);
|
||||
cljs.core.cst$kw$p_DASH_x = new cljs.core.Keyword(null,"p-x","p-x",-1721211211);
|
||||
cljs.core.cst$kw$p2d = new cljs.core.Keyword(null,"p2d","p2d",-2106175755);
|
||||
cljs.core.cst$kw$keep_DASH_on_DASH_top = new cljs.core.Keyword(null,"keep-on-top","keep-on-top",-970284267);
|
||||
cljs.core.cst$kw$navigation_DASH_3d = new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301);
|
||||
cljs.core.cst$sym$node = new cljs.core.Symbol(null,"node","node",-2073234571,null);
|
||||
cljs.core.cst$kw$mouseReleased = new cljs.core.Keyword(null,"mouseReleased","mouseReleased",1116234838);
|
||||
cljs.core.cst$kw$mousePressed = new cljs.core.Keyword(null,"mousePressed","mousePressed",1776186454);
|
||||
cljs.core.cst$kw$shape = new cljs.core.Keyword(null,"shape","shape",1190694006);
|
||||
cljs.core.cst$sym$sym = new cljs.core.Symbol(null,"sym","sym",195671222,null);
|
||||
cljs.core.cst$kw$mouseMoved = new cljs.core.Keyword(null,"mouseMoved","mouseMoved",-1936954058);
|
||||
cljs.core.cst$kw$f12 = new cljs.core.Keyword(null,"f12","f12",853352790);
|
||||
cljs.core.cst$sym$sb = new cljs.core.Symbol(null,"sb","sb",-1249746442,null);
|
||||
cljs.core.cst$kw$mouseOver = new cljs.core.Keyword(null,"mouseOver","mouseOver",-1334461930);
|
||||
cljs.core.cst$kw$exclusion = new cljs.core.Keyword(null,"exclusion","exclusion",531897910);
|
||||
cljs.core.cst$sym$quil$core_SLASH_fill = new cljs.core.Symbol("quil.core","fill","quil.core/fill",814613078,null);
|
||||
cljs.core.cst$sym$meta8585 = new cljs.core.Symbol(null,"meta8585","meta8585",663620534,null);
|
||||
cljs.core.cst$sym$old_DASH_stroke__10244__auto__ = new cljs.core.Symbol(null,"old-stroke__10244__auto__","old-stroke__10244__auto__",1374294039,null);
|
||||
cljs.core.cst$kw$disable_DASH_opengl_DASH_errors = new cljs.core.Keyword(null,"disable-opengl-errors","disable-opengl-errors",506822839);
|
||||
cljs.core.cst$kw$unknown_DASH_key = new cljs.core.Keyword(null,"unknown-key","unknown-key",255305911);
|
||||
cljs.core.cst$kw$alpha = new cljs.core.Keyword(null,"alpha","alpha",-1574982441);
|
||||
cljs.core.cst$kw$wait = new cljs.core.Keyword(null,"wait","wait",-260664777);
|
||||
cljs.core.cst$kw$right = new cljs.core.Keyword(null,"right","right",-452581833);
|
||||
cljs.core.cst$kw$random = new cljs.core.Keyword(null,"random","random",-557811113);
|
||||
cljs.core.cst$sym$quil$core_SLASH_current_DASH_stroke = new cljs.core.Symbol("quil.core","current-stroke","quil.core/current-stroke",-1148124489,null);
|
||||
cljs.core.cst$kw$host_DASH_id = new cljs.core.Keyword(null,"host-id","host-id",742376279);
|
||||
cljs.core.cst$kw$repeat = new cljs.core.Keyword(null,"repeat","repeat",832692087);
|
||||
cljs.core.cst$kw$hard_DASH_light = new cljs.core.Keyword(null,"hard-light","hard-light",-37591145);
|
||||
cljs.core.cst$sym$quil$sketch$macros_SLASH_defsketch = new cljs.core.Symbol("quil.sketch$macros","defsketch","quil.sketch$macros/defsketch",2065609719,null);
|
||||
cljs.core.cst$kw$keyTyped = new cljs.core.Keyword(null,"keyTyped","keyTyped",1437329399);
|
||||
cljs.core.cst$kw$position = new cljs.core.Keyword(null,"position","position",-2011731912);
|
||||
cljs.core.cst$kw$no_DASH_start = new cljs.core.Keyword(null,"no-start","no-start",1381488856);
|
||||
cljs.core.cst$sym$_hash = new cljs.core.Symbol(null,"_hash","_hash",-2130838312,null);
|
||||
cljs.core.cst$kw$image = new cljs.core.Keyword(null,"image","image",-58725096);
|
||||
cljs.core.cst$kw$d = new cljs.core.Keyword(null,"d","d",1972142424);
|
||||
cljs.core.cst$kw$dial = new cljs.core.Keyword(null,"dial","dial",1238392184);
|
||||
cljs.core.cst$kw$multiply = new cljs.core.Keyword(null,"multiply","multiply",-1036907048);
|
||||
cljs.core.cst$kw$lightest = new cljs.core.Keyword(null,"lightest","lightest",-2043115912);
|
||||
cljs.core.cst$sym$quil$core_SLASH_rotate = new cljs.core.Symbol("quil.core","rotate","quil.core/rotate",-1944995048,null);
|
||||
cljs.core.cst$kw$f7 = new cljs.core.Keyword(null,"f7","f7",356150168);
|
||||
cljs.core.cst$kw$ghost = new cljs.core.Keyword(null,"ghost","ghost",-1531157576);
|
||||
cljs.core.cst$sym$keys = new cljs.core.Symbol(null,"keys","keys",-1586012071,null);
|
||||
cljs.core.cst$kw$x = new cljs.core.Keyword(null,"x","x",2099068185);
|
||||
cljs.core.cst$kw$blend = new cljs.core.Keyword(null,"blend","blend",249565561);
|
||||
cljs.core.cst$sym$set_BANG_ = new cljs.core.Symbol(null,"set!","set!",250714521,null);
|
||||
cljs.core.cst$kw$disable_DASH_depth_DASH_sort = new cljs.core.Keyword(null,"disable-depth-sort","disable-depth-sort",-1568352839);
|
||||
cljs.core.cst$kw$tag = new cljs.core.Keyword(null,"tag","tag",-1290361223);
|
||||
cljs.core.cst$sym$tree_DASH_map = new cljs.core.Symbol(null,"tree-map","tree-map",1373073049,null);
|
||||
cljs.core.cst$kw$raw_DASH_key = new cljs.core.Keyword(null,"raw-key","raw-key",-162482279);
|
||||
cljs.core.cst$kw$target = new cljs.core.Keyword(null,"target","target",253001721);
|
||||
cljs.core.cst$sym$_DOT_ = new cljs.core.Symbol(null,".",".",1975675962,null);
|
||||
cljs.core.cst$sym$var = new cljs.core.Symbol(null,"var","var",870848730,null);
|
||||
cljs.core.cst$kw$mutable = new cljs.core.Keyword(null,"mutable","mutable",875778266);
|
||||
cljs.core.cst$sym$quote = new cljs.core.Symbol(null,"quote","quote",1377916282,null);
|
||||
cljs.core.cst$kw$f9 = new cljs.core.Keyword(null,"f9","f9",704633338);
|
||||
cljs.core.cst$sym$root = new cljs.core.Symbol(null,"root","root",1191874074,null);
|
||||
cljs.core.cst$sym$str = new cljs.core.Symbol(null,"str","str",-1564826950,null);
|
||||
cljs.core.cst$kw$draw = new cljs.core.Keyword(null,"draw","draw",1358331674);
|
||||
cljs.core.cst$sym$nodes = new cljs.core.Symbol(null,"nodes","nodes",-459054278,null);
|
||||
cljs.core.cst$sym$seen = new cljs.core.Symbol(null,"seen","seen",1121531738,null);
|
||||
cljs.core.cst$sym$hash_DASH_map = new cljs.core.Symbol(null,"hash-map","hash-map",-439030950,null);
|
||||
cljs.core.cst$kw$erode = new cljs.core.Keyword(null,"erode","erode",1539530618);
|
||||
cljs.core.cst$kw$centered = new cljs.core.Keyword(null,"centered","centered",-515171141);
|
||||
cljs.core.cst$kw$add = new cljs.core.Keyword(null,"add","add",235287739);
|
||||
cljs.core.cst$sym$catch = new cljs.core.Symbol(null,"catch","catch",-1616370245,null);
|
||||
cljs.core.cst$kw$soft_DASH_light = new cljs.core.Keyword(null,"soft-light","soft-light",513207899);
|
||||
cljs.core.cst$kw$child_DASH_ids = new cljs.core.Keyword(null,"child-ids","child-ids",-604525861);
|
||||
cljs.core.cst$kw$alt_DASH_impl = new cljs.core.Keyword(null,"alt-impl","alt-impl",670969595);
|
||||
cljs.core.cst$sym$ext_DASH_map_DASH_iter = new cljs.core.Symbol(null,"ext-map-iter","ext-map-iter",-1215982757,null);
|
||||
cljs.core.cst$sym$tail = new cljs.core.Symbol(null,"tail","tail",494507963,null);
|
||||
cljs.core.cst$sym$quil$core_SLASH_with_DASH_graphics = new cljs.core.Symbol("quil.core","with-graphics","quil.core/with-graphics",481277883,null);
|
||||
cljs.core.cst$kw$subtract = new cljs.core.Keyword(null,"subtract","subtract",2136988635);
|
||||
cljs.core.cst$kw$clamp = new cljs.core.Keyword(null,"clamp","clamp",1803814940);
|
||||
cljs.core.cst$sym$record = new cljs.core.Symbol(null,"record","record",861424668,null);
|
||||
cljs.core.cst$sym$mseq = new cljs.core.Symbol(null,"mseq","mseq",1602647196,null);
|
||||
cljs.core.cst$sym$count = new cljs.core.Symbol(null,"count","count",-514511684,null);
|
||||
cljs.core.cst$kw$f6 = new cljs.core.Keyword(null,"f6","f6",2103080604);
|
||||
cljs.core.cst$kw$keywordize_DASH_keys = new cljs.core.Keyword(null,"keywordize-keys","keywordize-keys",1310784252);
|
||||
cljs.core.cst$sym$off = new cljs.core.Symbol(null,"off","off",-2047994980,null);
|
||||
cljs.core.cst$kw$clj = new cljs.core.Keyword(null,"clj","clj",-660495428);
|
||||
cljs.core.cst$kw$f4 = new cljs.core.Keyword(null,"f4","f4",990968764);
|
||||
cljs.core.cst$kw$triangle_DASH_strip = new cljs.core.Keyword(null,"triangle-strip","triangle-strip",221845500);
|
||||
cljs.core.cst$kw$navigation_DASH_2d = new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611);
|
||||
cljs.core.cst$sym$stack = new cljs.core.Symbol(null,"stack","stack",847125597,null);
|
||||
cljs.core.cst$sym$transient_DASH_map = new cljs.core.Symbol(null,"transient-map","transient-map",351764893,null);
|
||||
cljs.core.cst$sym$len = new cljs.core.Symbol(null,"len","len",-1230778691,null);
|
||||
cljs.core.cst$kw$cross = new cljs.core.Keyword(null,"cross","cross",194557789);
|
||||
cljs.core.cst$sym$right = new cljs.core.Symbol(null,"right","right",1187949694,null);
|
||||
cljs.core.cst$sym$throw = new cljs.core.Symbol(null,"throw","throw",595905694,null);
|
||||
cljs.core.cst$kw$p3d = new cljs.core.Keyword(null,"p3d","p3d",-850380194);
|
||||
cljs.core.cst$sym$fseq = new cljs.core.Symbol(null,"fseq","fseq",-1466412450,null);
|
||||
cljs.core.cst$kw$a = new cljs.core.Keyword(null,"a","a",-2123407586);
|
||||
cljs.core.cst$kw$triangles = new cljs.core.Keyword(null,"triangles","triangles",-1525417058);
|
||||
cljs.core.cst$sym$$beginDraw = new cljs.core.Symbol(null,".beginDraw",".beginDraw",1110767550,null);
|
||||
cljs.core.cst$kw$mouse_DASH_dragged = new cljs.core.Keyword(null,"mouse-dragged","mouse-dragged",-1220073441);
|
||||
cljs.core.cst$sym$cljs$core_SLASH_aget = new cljs.core.Symbol("cljs.core","aget","cljs.core/aget",6345791,null);
|
||||
cljs.core.cst$sym$tr__10254__auto__ = new cljs.core.Symbol(null,"tr__10254__auto__","tr__10254__auto__",1519210815,null);
|
||||
cljs.core.cst$kw$left = new cljs.core.Keyword(null,"left","left",-399115937);
|
||||
cljs.core.cst$kw$cljs$core_SLASH_not_DASH_found = new cljs.core.Keyword("cljs.core","not-found","cljs.core/not-found",-1572889185);
|
||||
cljs.core.cst$sym$more = new cljs.core.Symbol(null,"more","more",-418290273,null);
|
||||
cljs.core.cst$sym$def = new cljs.core.Symbol(null,"def","def",597100991,null);
|
||||
cljs.core.cst$kw$invert = new cljs.core.Keyword(null,"invert","invert",1553577503);
|
||||
cljs.core.cst$kw$text = new cljs.core.Keyword(null,"text","text",-1790561697);
|
||||
cljs.core.cst$kw$enable_DASH_texture_DASH_mipmaps = new cljs.core.Keyword(null,"enable-texture-mipmaps","enable-texture-mipmaps",1241892671);
|
||||
cljs.core.cst$kw$model = new cljs.core.Keyword(null,"model","model",331153215);
|
||||
cljs.core.cst$sym$f = new cljs.core.Symbol(null,"f","f",43394975,null);
|
||||
cljs.core.cst$sym$next_DASH_iter = new cljs.core.Symbol(null,"next-iter","next-iter",1526626239,null);
|
||||
cljs.core.cst$sym$gr__10066__auto__ = new cljs.core.Symbol(null,"gr__10066__auto__","gr__10066__auto__",-614350849,null);
|
18
assets/viz/2/cljs_deps.js
Normal file
18
assets/viz/2/cljs_deps.js
Normal file
@ -0,0 +1,18 @@
|
||||
goog.addDependency("base.js", ['goog'], []);
|
||||
goog.addDependency("../cljs/core.js", ['cljs.core'], ['goog.string', 'goog.object', 'goog.math.Integer', 'goog.string.StringBuffer', 'goog.array', 'goog.math.Long']);
|
||||
goog.addDependency("../viz/grid.js", ['viz.grid'], ['cljs.core']);
|
||||
goog.addDependency("../viz/forest.js", ['viz.forest'], ['cljs.core', 'viz.grid']);
|
||||
goog.addDependency("../processing.js", ['org.processingjs.Processing'], []);
|
||||
goog.addDependency("../quil/middlewares/deprecated_options.js", ['quil.middlewares.deprecated_options'], ['cljs.core']);
|
||||
goog.addDependency("../clojure/string.js", ['clojure.string'], ['goog.string', 'cljs.core', 'goog.string.StringBuffer']);
|
||||
goog.addDependency("../quil/util.js", ['quil.util'], ['cljs.core', 'clojure.string']);
|
||||
goog.addDependency("../quil/sketch.js", ['quil.sketch'], ['goog.dom', 'cljs.core', 'quil.middlewares.deprecated_options', 'goog.events.EventType', 'goog.events', 'quil.util']);
|
||||
goog.addDependency("../quil/core.js", ['quil.core'], ['org.processingjs.Processing', 'quil.sketch', 'cljs.core', 'clojure.string', 'quil.util']);
|
||||
goog.addDependency("../quil/middlewares/navigation_3d.js", ['quil.middlewares.navigation_3d'], ['cljs.core', 'quil.core']);
|
||||
goog.addDependency("../quil/middlewares/navigation_2d.js", ['quil.middlewares.navigation_2d'], ['cljs.core', 'quil.core']);
|
||||
goog.addDependency("../quil/middlewares/fun_mode.js", ['quil.middlewares.fun_mode'], ['cljs.core', 'quil.core']);
|
||||
goog.addDependency("../quil/middleware.js", ['quil.middleware'], ['cljs.core', 'quil.middlewares.navigation_3d', 'quil.middlewares.navigation_2d', 'quil.middlewares.fun_mode']);
|
||||
goog.addDependency("../clojure/set.js", ['clojure.set'], ['cljs.core']);
|
||||
goog.addDependency("../viz/ghost.js", ['viz.ghost'], ['cljs.core', 'viz.forest', 'clojure.set', 'viz.grid']);
|
||||
goog.addDependency("../viz/dial.js", ['viz.dial'], ['cljs.core', 'quil.core']);
|
||||
goog.addDependency("../viz/core.js", ['viz.core'], ['goog.string', 'cljs.core', 'viz.forest', 'quil.core', 'quil.middleware', 'goog.string.format', 'viz.ghost', 'viz.grid', 'viz.dial']);
|
161
assets/viz/2/clojure/set.cljs
Normal file
161
assets/viz/2/clojure/set.cljs
Normal file
@ -0,0 +1,161 @@
|
||||
; Copyright (c) Rich Hickey. All rights reserved.
|
||||
; The use and distribution terms for this software are covered by the
|
||||
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
|
||||
; which can be found in the file epl-v10.html at the root of this distribution.
|
||||
; By using this software in any fashion, you are agreeing to be bound by
|
||||
; the terms of this license.
|
||||
; You must not remove this notice, or any other, from this software.
|
||||
|
||||
(ns ^{:doc "Set operations such as union/intersection."
|
||||
:author "Rich Hickey"}
|
||||
clojure.set)
|
||||
|
||||
(defn- bubble-max-key [k coll]
|
||||
"Move a maximal element of coll according to fn k (which returns a number)
|
||||
to the front of coll."
|
||||
(let [max (apply max-key k coll)]
|
||||
(cons max (remove #(identical? max %) coll))))
|
||||
|
||||
(defn union
|
||||
"Return a set that is the union of the input sets"
|
||||
([] #{})
|
||||
([s1] s1)
|
||||
([s1 s2]
|
||||
(if (< (count s1) (count s2))
|
||||
(reduce conj s2 s1)
|
||||
(reduce conj s1 s2)))
|
||||
([s1 s2 & sets]
|
||||
(let [bubbled-sets (bubble-max-key count (conj sets s2 s1))]
|
||||
(reduce into (first bubbled-sets) (rest bubbled-sets)))))
|
||||
|
||||
(defn intersection
|
||||
"Return a set that is the intersection of the input sets"
|
||||
([s1] s1)
|
||||
([s1 s2]
|
||||
(if (< (count s2) (count s1))
|
||||
(recur s2 s1)
|
||||
(reduce (fn [result item]
|
||||
(if (contains? s2 item)
|
||||
result
|
||||
(disj result item)))
|
||||
s1 s1)))
|
||||
([s1 s2 & sets]
|
||||
(let [bubbled-sets (bubble-max-key #(- (count %)) (conj sets s2 s1))]
|
||||
(reduce intersection (first bubbled-sets) (rest bubbled-sets)))))
|
||||
|
||||
(defn difference
|
||||
"Return a set that is the first set without elements of the remaining sets"
|
||||
([s1] s1)
|
||||
([s1 s2]
|
||||
(if (< (count s1) (count s2))
|
||||
(reduce (fn [result item]
|
||||
(if (contains? s2 item)
|
||||
(disj result item)
|
||||
result))
|
||||
s1 s1)
|
||||
(reduce disj s1 s2)))
|
||||
([s1 s2 & sets]
|
||||
(reduce difference s1 (conj sets s2))))
|
||||
|
||||
|
||||
(defn select
|
||||
"Returns a set of the elements for which pred is true"
|
||||
[pred xset]
|
||||
(reduce (fn [s k] (if (pred k) s (disj s k)))
|
||||
xset xset))
|
||||
|
||||
(defn project
|
||||
"Returns a rel of the elements of xrel with only the keys in ks"
|
||||
[xrel ks]
|
||||
(set (map #(select-keys % ks) xrel)))
|
||||
|
||||
(defn rename-keys
|
||||
"Returns the map with the keys in kmap renamed to the vals in kmap"
|
||||
[map kmap]
|
||||
(reduce
|
||||
(fn [m [old new]]
|
||||
(if (contains? map old)
|
||||
(assoc m new (get map old))
|
||||
m))
|
||||
(apply dissoc map (keys kmap)) kmap))
|
||||
|
||||
(defn rename
|
||||
"Returns a rel of the maps in xrel with the keys in kmap renamed to the vals in kmap"
|
||||
[xrel kmap]
|
||||
(set (map #(rename-keys % kmap) xrel)))
|
||||
|
||||
(defn index
|
||||
"Returns a map of the distinct values of ks in the xrel mapped to a
|
||||
set of the maps in xrel with the corresponding values of ks."
|
||||
[xrel ks]
|
||||
(reduce
|
||||
(fn [m x]
|
||||
(let [ik (select-keys x ks)]
|
||||
(assoc m ik (conj (get m ik #{}) x))))
|
||||
{} xrel))
|
||||
|
||||
(defn map-invert
|
||||
"Returns the map with the vals mapped to the keys."
|
||||
[m] (reduce (fn [m [k v]] (assoc m v k)) {} m))
|
||||
|
||||
(defn join
|
||||
"When passed 2 rels, returns the rel corresponding to the natural
|
||||
join. When passed an additional keymap, joins on the corresponding
|
||||
keys."
|
||||
([xrel yrel] ;natural join
|
||||
(if (and (seq xrel) (seq yrel))
|
||||
(let [ks (intersection (set (keys (first xrel))) (set (keys (first yrel))))
|
||||
[r s] (if (<= (count xrel) (count yrel))
|
||||
[xrel yrel]
|
||||
[yrel xrel])
|
||||
idx (index r ks)]
|
||||
(reduce (fn [ret x]
|
||||
(let [found (idx (select-keys x ks))]
|
||||
(if found
|
||||
(reduce #(conj %1 (merge %2 x)) ret found)
|
||||
ret)))
|
||||
#{} s))
|
||||
#{}))
|
||||
([xrel yrel km] ;arbitrary key mapping
|
||||
(let [[r s k] (if (<= (count xrel) (count yrel))
|
||||
[xrel yrel (map-invert km)]
|
||||
[yrel xrel km])
|
||||
idx (index r (vals k))]
|
||||
(reduce (fn [ret x]
|
||||
(let [found (idx (rename-keys (select-keys x (keys k)) k))]
|
||||
(if found
|
||||
(reduce #(conj %1 (merge %2 x)) ret found)
|
||||
ret)))
|
||||
#{} s))))
|
||||
|
||||
(defn subset?
|
||||
"Is set1 a subset of set2?"
|
||||
[set1 set2]
|
||||
(and (<= (count set1) (count set2))
|
||||
(every? #(contains? set2 %) set1)))
|
||||
|
||||
(defn superset?
|
||||
"Is set1 a superset of set2?"
|
||||
[set1 set2]
|
||||
(and (>= (count set1) (count set2))
|
||||
(every? #(contains? set1 %) set2)))
|
||||
|
||||
(comment
|
||||
(refer 'set)
|
||||
(def xs #{{:a 11 :b 1 :c 1 :d 4}
|
||||
{:a 2 :b 12 :c 2 :d 6}
|
||||
{:a 3 :b 3 :c 3 :d 8 :f 42}})
|
||||
|
||||
(def ys #{{:a 11 :b 11 :c 11 :e 5}
|
||||
{:a 12 :b 11 :c 12 :e 3}
|
||||
{:a 3 :b 3 :c 3 :e 7 }})
|
||||
|
||||
(join xs ys)
|
||||
(join xs (rename ys {:b :yb :c :yc}) {:a :a})
|
||||
|
||||
(union #{:a :b :c} #{:c :d :e })
|
||||
(difference #{:a :b :c} #{:c :d :e})
|
||||
(intersection #{:a :b :c} #{:c :d :e})
|
||||
|
||||
(index ys [:b]))
|
||||
|
1
assets/viz/2/clojure/set.cljs.cache.edn
Normal file
1
assets/viz/2/clojure/set.cljs.cache.edn
Normal file
File diff suppressed because one or more lines are too long
400
assets/viz/2/clojure/set.js
Normal file
400
assets/viz/2/clojure/set.js
Normal file
@ -0,0 +1,400 @@
|
||||
// Compiled by ClojureScript 1.9.473 {}
|
||||
goog.provide('clojure.set');
|
||||
goog.require('cljs.core');
|
||||
clojure.set.bubble_max_key = (function clojure$set$bubble_max_key(k,coll){
|
||||
|
||||
var max = cljs.core.apply.call(null,cljs.core.max_key,k,coll);
|
||||
return cljs.core.cons.call(null,max,cljs.core.remove.call(null,((function (max){
|
||||
return (function (p1__9452_SHARP_){
|
||||
return (max === p1__9452_SHARP_);
|
||||
});})(max))
|
||||
,coll));
|
||||
});
|
||||
/**
|
||||
* Return a set that is the union of the input sets
|
||||
*/
|
||||
clojure.set.union = (function clojure$set$union(var_args){
|
||||
var args9453 = [];
|
||||
var len__7927__auto___9459 = arguments.length;
|
||||
var i__7928__auto___9460 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___9460 < len__7927__auto___9459)){
|
||||
args9453.push((arguments[i__7928__auto___9460]));
|
||||
|
||||
var G__9461 = (i__7928__auto___9460 + (1));
|
||||
i__7928__auto___9460 = G__9461;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var G__9458 = args9453.length;
|
||||
switch (G__9458) {
|
||||
case 0:
|
||||
return clojure.set.union.cljs$core$IFn$_invoke$arity$0();
|
||||
|
||||
break;
|
||||
case 1:
|
||||
return clojure.set.union.cljs$core$IFn$_invoke$arity$1((arguments[(0)]));
|
||||
|
||||
break;
|
||||
case 2:
|
||||
return clojure.set.union.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
|
||||
|
||||
break;
|
||||
default:
|
||||
var argseq__7946__auto__ = (new cljs.core.IndexedSeq(args9453.slice((2)),(0),null));
|
||||
return clojure.set.union.cljs$core$IFn$_invoke$arity$variadic((arguments[(0)]),(arguments[(1)]),argseq__7946__auto__);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
clojure.set.union.cljs$core$IFn$_invoke$arity$0 = (function (){
|
||||
return cljs.core.PersistentHashSet.EMPTY;
|
||||
});
|
||||
|
||||
clojure.set.union.cljs$core$IFn$_invoke$arity$1 = (function (s1){
|
||||
return s1;
|
||||
});
|
||||
|
||||
clojure.set.union.cljs$core$IFn$_invoke$arity$2 = (function (s1,s2){
|
||||
if((cljs.core.count.call(null,s1) < cljs.core.count.call(null,s2))){
|
||||
return cljs.core.reduce.call(null,cljs.core.conj,s2,s1);
|
||||
} else {
|
||||
return cljs.core.reduce.call(null,cljs.core.conj,s1,s2);
|
||||
}
|
||||
});
|
||||
|
||||
clojure.set.union.cljs$core$IFn$_invoke$arity$variadic = (function (s1,s2,sets){
|
||||
var bubbled_sets = clojure.set.bubble_max_key.call(null,cljs.core.count,cljs.core.conj.call(null,sets,s2,s1));
|
||||
return cljs.core.reduce.call(null,cljs.core.into,cljs.core.first.call(null,bubbled_sets),cljs.core.rest.call(null,bubbled_sets));
|
||||
});
|
||||
|
||||
clojure.set.union.cljs$lang$applyTo = (function (seq9454){
|
||||
var G__9455 = cljs.core.first.call(null,seq9454);
|
||||
var seq9454__$1 = cljs.core.next.call(null,seq9454);
|
||||
var G__9456 = cljs.core.first.call(null,seq9454__$1);
|
||||
var seq9454__$2 = cljs.core.next.call(null,seq9454__$1);
|
||||
return clojure.set.union.cljs$core$IFn$_invoke$arity$variadic(G__9455,G__9456,seq9454__$2);
|
||||
});
|
||||
|
||||
clojure.set.union.cljs$lang$maxFixedArity = (2);
|
||||
|
||||
/**
|
||||
* Return a set that is the intersection of the input sets
|
||||
*/
|
||||
clojure.set.intersection = (function clojure$set$intersection(var_args){
|
||||
var args9464 = [];
|
||||
var len__7927__auto___9470 = arguments.length;
|
||||
var i__7928__auto___9471 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___9471 < len__7927__auto___9470)){
|
||||
args9464.push((arguments[i__7928__auto___9471]));
|
||||
|
||||
var G__9472 = (i__7928__auto___9471 + (1));
|
||||
i__7928__auto___9471 = G__9472;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var G__9469 = args9464.length;
|
||||
switch (G__9469) {
|
||||
case 1:
|
||||
return clojure.set.intersection.cljs$core$IFn$_invoke$arity$1((arguments[(0)]));
|
||||
|
||||
break;
|
||||
case 2:
|
||||
return clojure.set.intersection.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
|
||||
|
||||
break;
|
||||
default:
|
||||
var argseq__7946__auto__ = (new cljs.core.IndexedSeq(args9464.slice((2)),(0),null));
|
||||
return clojure.set.intersection.cljs$core$IFn$_invoke$arity$variadic((arguments[(0)]),(arguments[(1)]),argseq__7946__auto__);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
clojure.set.intersection.cljs$core$IFn$_invoke$arity$1 = (function (s1){
|
||||
return s1;
|
||||
});
|
||||
|
||||
clojure.set.intersection.cljs$core$IFn$_invoke$arity$2 = (function (s1,s2){
|
||||
while(true){
|
||||
if((cljs.core.count.call(null,s2) < cljs.core.count.call(null,s1))){
|
||||
var G__9474 = s2;
|
||||
var G__9475 = s1;
|
||||
s1 = G__9474;
|
||||
s2 = G__9475;
|
||||
continue;
|
||||
} else {
|
||||
return cljs.core.reduce.call(null,((function (s1,s2){
|
||||
return (function (result,item){
|
||||
if(cljs.core.contains_QMARK_.call(null,s2,item)){
|
||||
return result;
|
||||
} else {
|
||||
return cljs.core.disj.call(null,result,item);
|
||||
}
|
||||
});})(s1,s2))
|
||||
,s1,s1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
clojure.set.intersection.cljs$core$IFn$_invoke$arity$variadic = (function (s1,s2,sets){
|
||||
var bubbled_sets = clojure.set.bubble_max_key.call(null,(function (p1__9463_SHARP_){
|
||||
return (- cljs.core.count.call(null,p1__9463_SHARP_));
|
||||
}),cljs.core.conj.call(null,sets,s2,s1));
|
||||
return cljs.core.reduce.call(null,clojure.set.intersection,cljs.core.first.call(null,bubbled_sets),cljs.core.rest.call(null,bubbled_sets));
|
||||
});
|
||||
|
||||
clojure.set.intersection.cljs$lang$applyTo = (function (seq9465){
|
||||
var G__9466 = cljs.core.first.call(null,seq9465);
|
||||
var seq9465__$1 = cljs.core.next.call(null,seq9465);
|
||||
var G__9467 = cljs.core.first.call(null,seq9465__$1);
|
||||
var seq9465__$2 = cljs.core.next.call(null,seq9465__$1);
|
||||
return clojure.set.intersection.cljs$core$IFn$_invoke$arity$variadic(G__9466,G__9467,seq9465__$2);
|
||||
});
|
||||
|
||||
clojure.set.intersection.cljs$lang$maxFixedArity = (2);
|
||||
|
||||
/**
|
||||
* Return a set that is the first set without elements of the remaining sets
|
||||
*/
|
||||
clojure.set.difference = (function clojure$set$difference(var_args){
|
||||
var args9476 = [];
|
||||
var len__7927__auto___9482 = arguments.length;
|
||||
var i__7928__auto___9483 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___9483 < len__7927__auto___9482)){
|
||||
args9476.push((arguments[i__7928__auto___9483]));
|
||||
|
||||
var G__9484 = (i__7928__auto___9483 + (1));
|
||||
i__7928__auto___9483 = G__9484;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var G__9481 = args9476.length;
|
||||
switch (G__9481) {
|
||||
case 1:
|
||||
return clojure.set.difference.cljs$core$IFn$_invoke$arity$1((arguments[(0)]));
|
||||
|
||||
break;
|
||||
case 2:
|
||||
return clojure.set.difference.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
|
||||
|
||||
break;
|
||||
default:
|
||||
var argseq__7946__auto__ = (new cljs.core.IndexedSeq(args9476.slice((2)),(0),null));
|
||||
return clojure.set.difference.cljs$core$IFn$_invoke$arity$variadic((arguments[(0)]),(arguments[(1)]),argseq__7946__auto__);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
clojure.set.difference.cljs$core$IFn$_invoke$arity$1 = (function (s1){
|
||||
return s1;
|
||||
});
|
||||
|
||||
clojure.set.difference.cljs$core$IFn$_invoke$arity$2 = (function (s1,s2){
|
||||
if((cljs.core.count.call(null,s1) < cljs.core.count.call(null,s2))){
|
||||
return cljs.core.reduce.call(null,(function (result,item){
|
||||
if(cljs.core.contains_QMARK_.call(null,s2,item)){
|
||||
return cljs.core.disj.call(null,result,item);
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}),s1,s1);
|
||||
} else {
|
||||
return cljs.core.reduce.call(null,cljs.core.disj,s1,s2);
|
||||
}
|
||||
});
|
||||
|
||||
clojure.set.difference.cljs$core$IFn$_invoke$arity$variadic = (function (s1,s2,sets){
|
||||
return cljs.core.reduce.call(null,clojure.set.difference,s1,cljs.core.conj.call(null,sets,s2));
|
||||
});
|
||||
|
||||
clojure.set.difference.cljs$lang$applyTo = (function (seq9477){
|
||||
var G__9478 = cljs.core.first.call(null,seq9477);
|
||||
var seq9477__$1 = cljs.core.next.call(null,seq9477);
|
||||
var G__9479 = cljs.core.first.call(null,seq9477__$1);
|
||||
var seq9477__$2 = cljs.core.next.call(null,seq9477__$1);
|
||||
return clojure.set.difference.cljs$core$IFn$_invoke$arity$variadic(G__9478,G__9479,seq9477__$2);
|
||||
});
|
||||
|
||||
clojure.set.difference.cljs$lang$maxFixedArity = (2);
|
||||
|
||||
/**
|
||||
* Returns a set of the elements for which pred is true
|
||||
*/
|
||||
clojure.set.select = (function clojure$set$select(pred,xset){
|
||||
return cljs.core.reduce.call(null,(function (s,k){
|
||||
if(cljs.core.truth_(pred.call(null,k))){
|
||||
return s;
|
||||
} else {
|
||||
return cljs.core.disj.call(null,s,k);
|
||||
}
|
||||
}),xset,xset);
|
||||
});
|
||||
/**
|
||||
* Returns a rel of the elements of xrel with only the keys in ks
|
||||
*/
|
||||
clojure.set.project = (function clojure$set$project(xrel,ks){
|
||||
return cljs.core.set.call(null,cljs.core.map.call(null,(function (p1__9486_SHARP_){
|
||||
return cljs.core.select_keys.call(null,p1__9486_SHARP_,ks);
|
||||
}),xrel));
|
||||
});
|
||||
/**
|
||||
* Returns the map with the keys in kmap renamed to the vals in kmap
|
||||
*/
|
||||
clojure.set.rename_keys = (function clojure$set$rename_keys(map,kmap){
|
||||
return cljs.core.reduce.call(null,(function (m,p__9491){
|
||||
var vec__9492 = p__9491;
|
||||
var old = cljs.core.nth.call(null,vec__9492,(0),null);
|
||||
var new$ = cljs.core.nth.call(null,vec__9492,(1),null);
|
||||
if(cljs.core.contains_QMARK_.call(null,map,old)){
|
||||
return cljs.core.assoc.call(null,m,new$,cljs.core.get.call(null,map,old));
|
||||
} else {
|
||||
return m;
|
||||
}
|
||||
}),cljs.core.apply.call(null,cljs.core.dissoc,map,cljs.core.keys.call(null,kmap)),kmap);
|
||||
});
|
||||
/**
|
||||
* Returns a rel of the maps in xrel with the keys in kmap renamed to the vals in kmap
|
||||
*/
|
||||
clojure.set.rename = (function clojure$set$rename(xrel,kmap){
|
||||
return cljs.core.set.call(null,cljs.core.map.call(null,(function (p1__9495_SHARP_){
|
||||
return clojure.set.rename_keys.call(null,p1__9495_SHARP_,kmap);
|
||||
}),xrel));
|
||||
});
|
||||
/**
|
||||
* Returns a map of the distinct values of ks in the xrel mapped to a
|
||||
* set of the maps in xrel with the corresponding values of ks.
|
||||
*/
|
||||
clojure.set.index = (function clojure$set$index(xrel,ks){
|
||||
return cljs.core.reduce.call(null,(function (m,x){
|
||||
var ik = cljs.core.select_keys.call(null,x,ks);
|
||||
return cljs.core.assoc.call(null,m,ik,cljs.core.conj.call(null,cljs.core.get.call(null,m,ik,cljs.core.PersistentHashSet.EMPTY),x));
|
||||
}),cljs.core.PersistentArrayMap.EMPTY,xrel);
|
||||
});
|
||||
/**
|
||||
* Returns the map with the vals mapped to the keys.
|
||||
*/
|
||||
clojure.set.map_invert = (function clojure$set$map_invert(m){
|
||||
return cljs.core.reduce.call(null,(function (m__$1,p__9500){
|
||||
var vec__9501 = p__9500;
|
||||
var k = cljs.core.nth.call(null,vec__9501,(0),null);
|
||||
var v = cljs.core.nth.call(null,vec__9501,(1),null);
|
||||
return cljs.core.assoc.call(null,m__$1,v,k);
|
||||
}),cljs.core.PersistentArrayMap.EMPTY,m);
|
||||
});
|
||||
/**
|
||||
* When passed 2 rels, returns the rel corresponding to the natural
|
||||
* join. When passed an additional keymap, joins on the corresponding
|
||||
* keys.
|
||||
*/
|
||||
clojure.set.join = (function clojure$set$join(var_args){
|
||||
var args9508 = [];
|
||||
var len__7927__auto___9517 = arguments.length;
|
||||
var i__7928__auto___9518 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___9518 < len__7927__auto___9517)){
|
||||
args9508.push((arguments[i__7928__auto___9518]));
|
||||
|
||||
var G__9519 = (i__7928__auto___9518 + (1));
|
||||
i__7928__auto___9518 = G__9519;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var G__9510 = args9508.length;
|
||||
switch (G__9510) {
|
||||
case 2:
|
||||
return clojure.set.join.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
|
||||
|
||||
break;
|
||||
case 3:
|
||||
return clojure.set.join.cljs$core$IFn$_invoke$arity$3((arguments[(0)]),(arguments[(1)]),(arguments[(2)]));
|
||||
|
||||
break;
|
||||
default:
|
||||
throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid arity: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(args9508.length)].join('')));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
clojure.set.join.cljs$core$IFn$_invoke$arity$2 = (function (xrel,yrel){
|
||||
if((cljs.core.seq.call(null,xrel)) && (cljs.core.seq.call(null,yrel))){
|
||||
var ks = clojure.set.intersection.call(null,cljs.core.set.call(null,cljs.core.keys.call(null,cljs.core.first.call(null,xrel))),cljs.core.set.call(null,cljs.core.keys.call(null,cljs.core.first.call(null,yrel))));
|
||||
var vec__9511 = (((cljs.core.count.call(null,xrel) <= cljs.core.count.call(null,yrel)))?new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [xrel,yrel], null):new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [yrel,xrel], null));
|
||||
var r = cljs.core.nth.call(null,vec__9511,(0),null);
|
||||
var s = cljs.core.nth.call(null,vec__9511,(1),null);
|
||||
var idx = clojure.set.index.call(null,r,ks);
|
||||
return cljs.core.reduce.call(null,((function (ks,vec__9511,r,s,idx){
|
||||
return (function (ret,x){
|
||||
var found = idx.call(null,cljs.core.select_keys.call(null,x,ks));
|
||||
if(cljs.core.truth_(found)){
|
||||
return cljs.core.reduce.call(null,((function (found,ks,vec__9511,r,s,idx){
|
||||
return (function (p1__9504_SHARP_,p2__9505_SHARP_){
|
||||
return cljs.core.conj.call(null,p1__9504_SHARP_,cljs.core.merge.call(null,p2__9505_SHARP_,x));
|
||||
});})(found,ks,vec__9511,r,s,idx))
|
||||
,ret,found);
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
});})(ks,vec__9511,r,s,idx))
|
||||
,cljs.core.PersistentHashSet.EMPTY,s);
|
||||
} else {
|
||||
return cljs.core.PersistentHashSet.EMPTY;
|
||||
}
|
||||
});
|
||||
|
||||
clojure.set.join.cljs$core$IFn$_invoke$arity$3 = (function (xrel,yrel,km){
|
||||
var vec__9514 = (((cljs.core.count.call(null,xrel) <= cljs.core.count.call(null,yrel)))?new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [xrel,yrel,clojure.set.map_invert.call(null,km)], null):new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [yrel,xrel,km], null));
|
||||
var r = cljs.core.nth.call(null,vec__9514,(0),null);
|
||||
var s = cljs.core.nth.call(null,vec__9514,(1),null);
|
||||
var k = cljs.core.nth.call(null,vec__9514,(2),null);
|
||||
var idx = clojure.set.index.call(null,r,cljs.core.vals.call(null,k));
|
||||
return cljs.core.reduce.call(null,((function (vec__9514,r,s,k,idx){
|
||||
return (function (ret,x){
|
||||
var found = idx.call(null,clojure.set.rename_keys.call(null,cljs.core.select_keys.call(null,x,cljs.core.keys.call(null,k)),k));
|
||||
if(cljs.core.truth_(found)){
|
||||
return cljs.core.reduce.call(null,((function (found,vec__9514,r,s,k,idx){
|
||||
return (function (p1__9506_SHARP_,p2__9507_SHARP_){
|
||||
return cljs.core.conj.call(null,p1__9506_SHARP_,cljs.core.merge.call(null,p2__9507_SHARP_,x));
|
||||
});})(found,vec__9514,r,s,k,idx))
|
||||
,ret,found);
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
});})(vec__9514,r,s,k,idx))
|
||||
,cljs.core.PersistentHashSet.EMPTY,s);
|
||||
});
|
||||
|
||||
clojure.set.join.cljs$lang$maxFixedArity = 3;
|
||||
|
||||
/**
|
||||
* Is set1 a subset of set2?
|
||||
*/
|
||||
clojure.set.subset_QMARK_ = (function clojure$set$subset_QMARK_(set1,set2){
|
||||
return ((cljs.core.count.call(null,set1) <= cljs.core.count.call(null,set2))) && (cljs.core.every_QMARK_.call(null,(function (p1__9521_SHARP_){
|
||||
return cljs.core.contains_QMARK_.call(null,set2,p1__9521_SHARP_);
|
||||
}),set1));
|
||||
});
|
||||
/**
|
||||
* Is set1 a superset of set2?
|
||||
*/
|
||||
clojure.set.superset_QMARK_ = (function clojure$set$superset_QMARK_(set1,set2){
|
||||
return ((cljs.core.count.call(null,set1) >= cljs.core.count.call(null,set2))) && (cljs.core.every_QMARK_.call(null,(function (p1__9522_SHARP_){
|
||||
return cljs.core.contains_QMARK_.call(null,set1,p1__9522_SHARP_);
|
||||
}),set2));
|
||||
});
|
||||
|
||||
//# sourceMappingURL=set.js.map
|
1
assets/viz/2/clojure/set.js.map
Normal file
1
assets/viz/2/clojure/set.js.map
Normal file
File diff suppressed because one or more lines are too long
258
assets/viz/2/clojure/string.cljs
Normal file
258
assets/viz/2/clojure/string.cljs
Normal file
@ -0,0 +1,258 @@
|
||||
; Copyright (c) Rich Hickey. All rights reserved.
|
||||
; The use and distribution terms for this software are covered by the
|
||||
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
|
||||
; which can be found in the file epl-v10.html at the root of this distribution.
|
||||
; By using this software in any fashion, you are agreeing to be bound by
|
||||
; the terms of this license.
|
||||
; You must not remove this notice, or any other, from this software.
|
||||
|
||||
(ns clojure.string
|
||||
(:refer-clojure :exclude [replace reverse])
|
||||
(:require [goog.string :as gstring])
|
||||
(:import [goog.string StringBuffer]))
|
||||
|
||||
(defn- seq-reverse
|
||||
[coll]
|
||||
(reduce conj () coll))
|
||||
|
||||
(def ^:private re-surrogate-pair
|
||||
(js/RegExp. "([\\uD800-\\uDBFF])([\\uDC00-\\uDFFF])" "g"))
|
||||
|
||||
(defn reverse
|
||||
"Returns s with its characters reversed."
|
||||
[s]
|
||||
(-> (.replace s re-surrogate-pair "$2$1")
|
||||
(.. (split "") (reverse) (join ""))))
|
||||
|
||||
(defn- replace-all
|
||||
[s re replacement]
|
||||
(.replace s (js/RegExp. (.-source re) "g") replacement))
|
||||
|
||||
(defn- replace-with
|
||||
[f]
|
||||
(fn [& args]
|
||||
(let [matches (drop-last 2 args)]
|
||||
(if (= (count matches) 1)
|
||||
(f (first matches))
|
||||
(f (vec matches))))))
|
||||
|
||||
(defn replace
|
||||
"Replaces all instance of match with replacement in s.
|
||||
match/replacement can be:
|
||||
|
||||
string / string
|
||||
pattern / (string or function of match)."
|
||||
[s match replacement]
|
||||
(cond
|
||||
(string? match)
|
||||
(.replace s (js/RegExp. (gstring/regExpEscape match) "g") replacement)
|
||||
|
||||
(instance? js/RegExp match)
|
||||
(if (string? replacement)
|
||||
(replace-all s match replacement)
|
||||
(replace-all s match (replace-with replacement)))
|
||||
|
||||
:else (throw (str "Invalid match arg: " match))))
|
||||
|
||||
(defn replace-first
|
||||
"Replaces the first instance of match with replacement in s.
|
||||
match/replacement can be:
|
||||
|
||||
string / string
|
||||
pattern / (string or function of match)."
|
||||
[s match replacement]
|
||||
(.replace s match replacement))
|
||||
|
||||
(defn join
|
||||
"Returns a string of all elements in coll, as returned by (seq coll),
|
||||
separated by an optional separator."
|
||||
([coll]
|
||||
(loop [sb (StringBuffer.) coll (seq coll)]
|
||||
(if-not (nil? coll)
|
||||
(recur (. sb (append (str (first coll)))) (next coll))
|
||||
(.toString sb))))
|
||||
([separator coll]
|
||||
(loop [sb (StringBuffer.) coll (seq coll)]
|
||||
(if-not (nil? coll)
|
||||
(do
|
||||
(. sb (append (str (first coll))))
|
||||
(let [coll (next coll)]
|
||||
(when-not (nil? coll)
|
||||
(. sb (append separator)))
|
||||
(recur sb coll)))
|
||||
(.toString sb)))))
|
||||
|
||||
(defn upper-case
|
||||
"Converts string to all upper-case."
|
||||
[s]
|
||||
(.toUpperCase s))
|
||||
|
||||
(defn lower-case
|
||||
"Converts string to all lower-case."
|
||||
[s]
|
||||
(.toLowerCase s))
|
||||
|
||||
(defn capitalize
|
||||
"Converts first character of the string to upper-case, all other
|
||||
characters to lower-case."
|
||||
[s]
|
||||
(if (< (count s) 2)
|
||||
(upper-case s)
|
||||
(str (upper-case (subs s 0 1))
|
||||
(lower-case (subs s 1)))))
|
||||
|
||||
;; The JavaScript split function takes a limit argument but the return
|
||||
;; value is not the same as the Java split function.
|
||||
;;
|
||||
;; Java: (.split "a-b-c" #"-" 2) => ["a" "b-c"]
|
||||
;; JavaScript: (.split "a-b-c" #"-" 2) => ["a" "b"]
|
||||
;;
|
||||
;; For consistency, the three arg version has been implemented to
|
||||
;; mimic Java's behavior.
|
||||
|
||||
(defn- pop-last-while-empty
|
||||
[v]
|
||||
(loop [v v]
|
||||
(if (identical? "" (peek v))
|
||||
(recur (pop v))
|
||||
v)))
|
||||
|
||||
(defn- discard-trailing-if-needed
|
||||
[limit v]
|
||||
(if (and (== 0 limit) (< 1 (count v)))
|
||||
(pop-last-while-empty v)
|
||||
v))
|
||||
|
||||
(defn- split-with-empty-regex
|
||||
[s limit]
|
||||
(if (or (<= limit 0) (>= limit (+ 2 (count s))))
|
||||
(conj (vec (cons "" (map str (seq s)))) "")
|
||||
(condp == limit
|
||||
1 (vector s)
|
||||
2 (vector "" s)
|
||||
(let [c (- limit 2)]
|
||||
(conj (vec (cons "" (subvec (vec (map str (seq s))) 0 c))) (subs s c))))))
|
||||
|
||||
(defn split
|
||||
"Splits string on a regular expression. Optional argument limit is
|
||||
the maximum number of splits. Not lazy. Returns vector of the splits."
|
||||
([s re]
|
||||
(split s re 0))
|
||||
([s re limit]
|
||||
(discard-trailing-if-needed limit
|
||||
(if (identical? "/(?:)/" (str re))
|
||||
(split-with-empty-regex s limit)
|
||||
(if (< limit 1)
|
||||
(vec (.split (str s) re))
|
||||
(loop [s s
|
||||
limit limit
|
||||
parts []]
|
||||
(if (== 1 limit)
|
||||
(conj parts s)
|
||||
(let [m (re-find re s)]
|
||||
(if-not (nil? m)
|
||||
(let [index (.indexOf s m)]
|
||||
(recur (.substring s (+ index (count m)))
|
||||
(dec limit)
|
||||
(conj parts (.substring s 0 index))))
|
||||
(conj parts s))))))))))
|
||||
|
||||
(defn split-lines
|
||||
"Splits s on \n or \r\n."
|
||||
[s]
|
||||
(split s #"\n|\r\n"))
|
||||
|
||||
(defn trim
|
||||
"Removes whitespace from both ends of string."
|
||||
[s]
|
||||
(gstring/trim s))
|
||||
|
||||
(defn triml
|
||||
"Removes whitespace from the left side of string."
|
||||
[s]
|
||||
(gstring/trimLeft s))
|
||||
|
||||
(defn trimr
|
||||
"Removes whitespace from the right side of string."
|
||||
[s]
|
||||
(gstring/trimRight s))
|
||||
|
||||
(defn trim-newline
|
||||
"Removes all trailing newline \\n or return \\r characters from
|
||||
string. Similar to Perl's chomp."
|
||||
[s]
|
||||
(loop [index (.-length s)]
|
||||
(if (zero? index)
|
||||
""
|
||||
(let [ch (get s (dec index))]
|
||||
(if (or (identical? \newline ch)
|
||||
(identical? \return ch))
|
||||
(recur (dec index))
|
||||
(.substring s 0 index))))))
|
||||
|
||||
(defn ^boolean blank?
|
||||
"True is s is nil, empty, or contains only whitespace."
|
||||
[s]
|
||||
(gstring/isEmptySafe s))
|
||||
|
||||
(defn escape
|
||||
"Return a new string, using cmap to escape each character ch
|
||||
from s as follows:
|
||||
|
||||
If (cmap ch) is nil, append ch to the new string.
|
||||
If (cmap ch) is non-nil, append (str (cmap ch)) instead."
|
||||
[s cmap]
|
||||
(let [buffer (StringBuffer.)
|
||||
length (.-length s)]
|
||||
(loop [index 0]
|
||||
(if (== length index)
|
||||
(. buffer (toString))
|
||||
(let [ch (.charAt s index)
|
||||
replacement (get cmap ch)]
|
||||
(if-not (nil? replacement)
|
||||
(.append buffer (str replacement))
|
||||
(.append buffer ch))
|
||||
(recur (inc index)))))))
|
||||
|
||||
(defn index-of
|
||||
"Return index of value (string or char) in s, optionally searching
|
||||
forward from from-index or nil if not found."
|
||||
([s value]
|
||||
(let [result (.indexOf s value)]
|
||||
(if (neg? result)
|
||||
nil
|
||||
result)))
|
||||
([s value from-index]
|
||||
(let [result (.indexOf s value from-index)]
|
||||
(if (neg? result)
|
||||
nil
|
||||
result))))
|
||||
|
||||
(defn last-index-of
|
||||
"Return last index of value (string or char) in s, optionally
|
||||
searching backward from from-index or nil if not found."
|
||||
([s value]
|
||||
(let [result (.lastIndexOf s value)]
|
||||
(if (neg? result)
|
||||
nil
|
||||
result)))
|
||||
([s value from-index]
|
||||
(let [result (.lastIndexOf s value from-index)]
|
||||
(if (neg? result)
|
||||
nil
|
||||
result))))
|
||||
|
||||
(defn ^boolean starts-with?
|
||||
"True if s starts with substr."
|
||||
[s substr]
|
||||
(gstring/startsWith s substr))
|
||||
|
||||
(defn ^boolean ends-with?
|
||||
"True if s ends with substr."
|
||||
[s substr]
|
||||
(gstring/endsWith s substr))
|
||||
|
||||
(defn ^boolean includes?
|
||||
"True if s includes substr."
|
||||
[s substr]
|
||||
(gstring/contains s substr))
|
1
assets/viz/2/clojure/string.cljs.cache.edn
Normal file
1
assets/viz/2/clojure/string.cljs.cache.edn
Normal file
File diff suppressed because one or more lines are too long
505
assets/viz/2/clojure/string.js
Normal file
505
assets/viz/2/clojure/string.js
Normal file
@ -0,0 +1,505 @@
|
||||
// Compiled by ClojureScript 1.9.473 {}
|
||||
goog.provide('clojure.string');
|
||||
goog.require('cljs.core');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.StringBuffer');
|
||||
clojure.string.seq_reverse = (function clojure$string$seq_reverse(coll){
|
||||
return cljs.core.reduce.call(null,cljs.core.conj,cljs.core.List.EMPTY,coll);
|
||||
});
|
||||
clojure.string.re_surrogate_pair = (new RegExp("([\\uD800-\\uDBFF])([\\uDC00-\\uDFFF])","g"));
|
||||
/**
|
||||
* Returns s with its characters reversed.
|
||||
*/
|
||||
clojure.string.reverse = (function clojure$string$reverse(s){
|
||||
return s.replace(clojure.string.re_surrogate_pair,"$2$1").split("").reverse().join("");
|
||||
});
|
||||
clojure.string.replace_all = (function clojure$string$replace_all(s,re,replacement){
|
||||
return s.replace((new RegExp(re.source,"g")),replacement);
|
||||
});
|
||||
clojure.string.replace_with = (function clojure$string$replace_with(f){
|
||||
return (function() {
|
||||
var G__8074__delegate = function (args){
|
||||
var matches = cljs.core.drop_last.call(null,(2),args);
|
||||
if(cljs.core._EQ_.call(null,cljs.core.count.call(null,matches),(1))){
|
||||
return f.call(null,cljs.core.first.call(null,matches));
|
||||
} else {
|
||||
return f.call(null,cljs.core.vec.call(null,matches));
|
||||
}
|
||||
};
|
||||
var G__8074 = function (var_args){
|
||||
var args = null;
|
||||
if (arguments.length > 0) {
|
||||
var G__8075__i = 0, G__8075__a = new Array(arguments.length - 0);
|
||||
while (G__8075__i < G__8075__a.length) {G__8075__a[G__8075__i] = arguments[G__8075__i + 0]; ++G__8075__i;}
|
||||
args = new cljs.core.IndexedSeq(G__8075__a,0);
|
||||
}
|
||||
return G__8074__delegate.call(this,args);};
|
||||
G__8074.cljs$lang$maxFixedArity = 0;
|
||||
G__8074.cljs$lang$applyTo = (function (arglist__8076){
|
||||
var args = cljs.core.seq(arglist__8076);
|
||||
return G__8074__delegate(args);
|
||||
});
|
||||
G__8074.cljs$core$IFn$_invoke$arity$variadic = G__8074__delegate;
|
||||
return G__8074;
|
||||
})()
|
||||
;
|
||||
});
|
||||
/**
|
||||
* Replaces all instance of match with replacement in s.
|
||||
* match/replacement can be:
|
||||
*
|
||||
* string / string
|
||||
* pattern / (string or function of match).
|
||||
*/
|
||||
clojure.string.replace = (function clojure$string$replace(s,match,replacement){
|
||||
if(typeof match === 'string'){
|
||||
return s.replace((new RegExp(goog.string.regExpEscape(match),"g")),replacement);
|
||||
} else {
|
||||
if((match instanceof RegExp)){
|
||||
if(typeof replacement === 'string'){
|
||||
return clojure.string.replace_all.call(null,s,match,replacement);
|
||||
} else {
|
||||
return clojure.string.replace_all.call(null,s,match,clojure.string.replace_with.call(null,replacement));
|
||||
}
|
||||
} else {
|
||||
throw [cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid match arg: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(match)].join('');
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Replaces the first instance of match with replacement in s.
|
||||
* match/replacement can be:
|
||||
*
|
||||
* string / string
|
||||
* pattern / (string or function of match).
|
||||
*/
|
||||
clojure.string.replace_first = (function clojure$string$replace_first(s,match,replacement){
|
||||
return s.replace(match,replacement);
|
||||
});
|
||||
/**
|
||||
* Returns a string of all elements in coll, as returned by (seq coll),
|
||||
* separated by an optional separator.
|
||||
*/
|
||||
clojure.string.join = (function clojure$string$join(var_args){
|
||||
var args8077 = [];
|
||||
var len__7927__auto___8080 = arguments.length;
|
||||
var i__7928__auto___8081 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___8081 < len__7927__auto___8080)){
|
||||
args8077.push((arguments[i__7928__auto___8081]));
|
||||
|
||||
var G__8082 = (i__7928__auto___8081 + (1));
|
||||
i__7928__auto___8081 = G__8082;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var G__8079 = args8077.length;
|
||||
switch (G__8079) {
|
||||
case 1:
|
||||
return clojure.string.join.cljs$core$IFn$_invoke$arity$1((arguments[(0)]));
|
||||
|
||||
break;
|
||||
case 2:
|
||||
return clojure.string.join.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
|
||||
|
||||
break;
|
||||
default:
|
||||
throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid arity: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(args8077.length)].join('')));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
clojure.string.join.cljs$core$IFn$_invoke$arity$1 = (function (coll){
|
||||
var sb = (new goog.string.StringBuffer());
|
||||
var coll__$1 = cljs.core.seq.call(null,coll);
|
||||
while(true){
|
||||
if(!((coll__$1 == null))){
|
||||
var G__8084 = sb.append([cljs.core.str.cljs$core$IFn$_invoke$arity$1(cljs.core.first.call(null,coll__$1))].join(''));
|
||||
var G__8085 = cljs.core.next.call(null,coll__$1);
|
||||
sb = G__8084;
|
||||
coll__$1 = G__8085;
|
||||
continue;
|
||||
} else {
|
||||
return sb.toString();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
clojure.string.join.cljs$core$IFn$_invoke$arity$2 = (function (separator,coll){
|
||||
var sb = (new goog.string.StringBuffer());
|
||||
var coll__$1 = cljs.core.seq.call(null,coll);
|
||||
while(true){
|
||||
if(!((coll__$1 == null))){
|
||||
sb.append([cljs.core.str.cljs$core$IFn$_invoke$arity$1(cljs.core.first.call(null,coll__$1))].join(''));
|
||||
|
||||
var coll__$2 = cljs.core.next.call(null,coll__$1);
|
||||
if((coll__$2 == null)){
|
||||
} else {
|
||||
sb.append(separator);
|
||||
}
|
||||
|
||||
var G__8086 = sb;
|
||||
var G__8087 = coll__$2;
|
||||
sb = G__8086;
|
||||
coll__$1 = G__8087;
|
||||
continue;
|
||||
} else {
|
||||
return sb.toString();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
clojure.string.join.cljs$lang$maxFixedArity = 2;
|
||||
|
||||
/**
|
||||
* Converts string to all upper-case.
|
||||
*/
|
||||
clojure.string.upper_case = (function clojure$string$upper_case(s){
|
||||
return s.toUpperCase();
|
||||
});
|
||||
/**
|
||||
* Converts string to all lower-case.
|
||||
*/
|
||||
clojure.string.lower_case = (function clojure$string$lower_case(s){
|
||||
return s.toLowerCase();
|
||||
});
|
||||
/**
|
||||
* Converts first character of the string to upper-case, all other
|
||||
* characters to lower-case.
|
||||
*/
|
||||
clojure.string.capitalize = (function clojure$string$capitalize(s){
|
||||
if((cljs.core.count.call(null,s) < (2))){
|
||||
return clojure.string.upper_case.call(null,s);
|
||||
} else {
|
||||
return [cljs.core.str.cljs$core$IFn$_invoke$arity$1(clojure.string.upper_case.call(null,cljs.core.subs.call(null,s,(0),(1)))),cljs.core.str.cljs$core$IFn$_invoke$arity$1(clojure.string.lower_case.call(null,cljs.core.subs.call(null,s,(1))))].join('');
|
||||
}
|
||||
});
|
||||
clojure.string.pop_last_while_empty = (function clojure$string$pop_last_while_empty(v){
|
||||
var v__$1 = v;
|
||||
while(true){
|
||||
if(("" === cljs.core.peek.call(null,v__$1))){
|
||||
var G__8088 = cljs.core.pop.call(null,v__$1);
|
||||
v__$1 = G__8088;
|
||||
continue;
|
||||
} else {
|
||||
return v__$1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
clojure.string.discard_trailing_if_needed = (function clojure$string$discard_trailing_if_needed(limit,v){
|
||||
if((((0) === limit)) && (((1) < cljs.core.count.call(null,v)))){
|
||||
return clojure.string.pop_last_while_empty.call(null,v);
|
||||
} else {
|
||||
return v;
|
||||
}
|
||||
});
|
||||
clojure.string.split_with_empty_regex = (function clojure$string$split_with_empty_regex(s,limit){
|
||||
if(((limit <= (0))) || ((limit >= ((2) + cljs.core.count.call(null,s))))){
|
||||
return cljs.core.conj.call(null,cljs.core.vec.call(null,cljs.core.cons.call(null,"",cljs.core.map.call(null,cljs.core.str,cljs.core.seq.call(null,s)))),"");
|
||||
} else {
|
||||
var pred__8092 = cljs.core._EQ__EQ_;
|
||||
var expr__8093 = limit;
|
||||
if(cljs.core.truth_(pred__8092.call(null,(1),expr__8093))){
|
||||
return (new cljs.core.PersistentVector(null,1,(5),cljs.core.PersistentVector.EMPTY_NODE,[s],null));
|
||||
} else {
|
||||
if(cljs.core.truth_(pred__8092.call(null,(2),expr__8093))){
|
||||
return (new cljs.core.PersistentVector(null,2,(5),cljs.core.PersistentVector.EMPTY_NODE,["",s],null));
|
||||
} else {
|
||||
var c = (limit - (2));
|
||||
return cljs.core.conj.call(null,cljs.core.vec.call(null,cljs.core.cons.call(null,"",cljs.core.subvec.call(null,cljs.core.vec.call(null,cljs.core.map.call(null,cljs.core.str,cljs.core.seq.call(null,s))),(0),c))),cljs.core.subs.call(null,s,c));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Splits string on a regular expression. Optional argument limit is
|
||||
* the maximum number of splits. Not lazy. Returns vector of the splits.
|
||||
*/
|
||||
clojure.string.split = (function clojure$string$split(var_args){
|
||||
var args8095 = [];
|
||||
var len__7927__auto___8098 = arguments.length;
|
||||
var i__7928__auto___8099 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___8099 < len__7927__auto___8098)){
|
||||
args8095.push((arguments[i__7928__auto___8099]));
|
||||
|
||||
var G__8100 = (i__7928__auto___8099 + (1));
|
||||
i__7928__auto___8099 = G__8100;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var G__8097 = args8095.length;
|
||||
switch (G__8097) {
|
||||
case 2:
|
||||
return clojure.string.split.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
|
||||
|
||||
break;
|
||||
case 3:
|
||||
return clojure.string.split.cljs$core$IFn$_invoke$arity$3((arguments[(0)]),(arguments[(1)]),(arguments[(2)]));
|
||||
|
||||
break;
|
||||
default:
|
||||
throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid arity: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(args8095.length)].join('')));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
clojure.string.split.cljs$core$IFn$_invoke$arity$2 = (function (s,re){
|
||||
return clojure.string.split.call(null,s,re,(0));
|
||||
});
|
||||
|
||||
clojure.string.split.cljs$core$IFn$_invoke$arity$3 = (function (s,re,limit){
|
||||
return clojure.string.discard_trailing_if_needed.call(null,limit,((("/(?:)/" === [cljs.core.str.cljs$core$IFn$_invoke$arity$1(re)].join('')))?clojure.string.split_with_empty_regex.call(null,s,limit):(((limit < (1)))?cljs.core.vec.call(null,[cljs.core.str.cljs$core$IFn$_invoke$arity$1(s)].join('').split(re)):(function (){var s__$1 = s;
|
||||
var limit__$1 = limit;
|
||||
var parts = cljs.core.PersistentVector.EMPTY;
|
||||
while(true){
|
||||
if(((1) === limit__$1)){
|
||||
return cljs.core.conj.call(null,parts,s__$1);
|
||||
} else {
|
||||
var m = cljs.core.re_find.call(null,re,s__$1);
|
||||
if(!((m == null))){
|
||||
var index = s__$1.indexOf(m);
|
||||
var G__8102 = s__$1.substring((index + cljs.core.count.call(null,m)));
|
||||
var G__8103 = (limit__$1 - (1));
|
||||
var G__8104 = cljs.core.conj.call(null,parts,s__$1.substring((0),index));
|
||||
s__$1 = G__8102;
|
||||
limit__$1 = G__8103;
|
||||
parts = G__8104;
|
||||
continue;
|
||||
} else {
|
||||
return cljs.core.conj.call(null,parts,s__$1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
})())));
|
||||
});
|
||||
|
||||
clojure.string.split.cljs$lang$maxFixedArity = 3;
|
||||
|
||||
/**
|
||||
* Splits s on
|
||||
* or
|
||||
* .
|
||||
*/
|
||||
clojure.string.split_lines = (function clojure$string$split_lines(s){
|
||||
return clojure.string.split.call(null,s,/\n|\r\n/);
|
||||
});
|
||||
/**
|
||||
* Removes whitespace from both ends of string.
|
||||
*/
|
||||
clojure.string.trim = (function clojure$string$trim(s){
|
||||
return goog.string.trim(s);
|
||||
});
|
||||
/**
|
||||
* Removes whitespace from the left side of string.
|
||||
*/
|
||||
clojure.string.triml = (function clojure$string$triml(s){
|
||||
return goog.string.trimLeft(s);
|
||||
});
|
||||
/**
|
||||
* Removes whitespace from the right side of string.
|
||||
*/
|
||||
clojure.string.trimr = (function clojure$string$trimr(s){
|
||||
return goog.string.trimRight(s);
|
||||
});
|
||||
/**
|
||||
* Removes all trailing newline \n or return \r characters from
|
||||
* string. Similar to Perl's chomp.
|
||||
*/
|
||||
clojure.string.trim_newline = (function clojure$string$trim_newline(s){
|
||||
var index = s.length;
|
||||
while(true){
|
||||
if((index === (0))){
|
||||
return "";
|
||||
} else {
|
||||
var ch = cljs.core.get.call(null,s,(index - (1)));
|
||||
if((("\n" === ch)) || (("\r" === ch))){
|
||||
var G__8105 = (index - (1));
|
||||
index = G__8105;
|
||||
continue;
|
||||
} else {
|
||||
return s.substring((0),index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* True is s is nil, empty, or contains only whitespace.
|
||||
*/
|
||||
clojure.string.blank_QMARK_ = (function clojure$string$blank_QMARK_(s){
|
||||
return goog.string.isEmptySafe(s);
|
||||
});
|
||||
/**
|
||||
* Return a new string, using cmap to escape each character ch
|
||||
* from s as follows:
|
||||
*
|
||||
* If (cmap ch) is nil, append ch to the new string.
|
||||
* If (cmap ch) is non-nil, append (str (cmap ch)) instead.
|
||||
*/
|
||||
clojure.string.escape = (function clojure$string$escape(s,cmap){
|
||||
var buffer = (new goog.string.StringBuffer());
|
||||
var length = s.length;
|
||||
var index = (0);
|
||||
while(true){
|
||||
if((length === index)){
|
||||
return buffer.toString();
|
||||
} else {
|
||||
var ch = s.charAt(index);
|
||||
var replacement = cljs.core.get.call(null,cmap,ch);
|
||||
if(!((replacement == null))){
|
||||
buffer.append([cljs.core.str.cljs$core$IFn$_invoke$arity$1(replacement)].join(''));
|
||||
} else {
|
||||
buffer.append(ch);
|
||||
}
|
||||
|
||||
var G__8106 = (index + (1));
|
||||
index = G__8106;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Return index of value (string or char) in s, optionally searching
|
||||
* forward from from-index or nil if not found.
|
||||
*/
|
||||
clojure.string.index_of = (function clojure$string$index_of(var_args){
|
||||
var args8107 = [];
|
||||
var len__7927__auto___8110 = arguments.length;
|
||||
var i__7928__auto___8111 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___8111 < len__7927__auto___8110)){
|
||||
args8107.push((arguments[i__7928__auto___8111]));
|
||||
|
||||
var G__8112 = (i__7928__auto___8111 + (1));
|
||||
i__7928__auto___8111 = G__8112;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var G__8109 = args8107.length;
|
||||
switch (G__8109) {
|
||||
case 2:
|
||||
return clojure.string.index_of.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
|
||||
|
||||
break;
|
||||
case 3:
|
||||
return clojure.string.index_of.cljs$core$IFn$_invoke$arity$3((arguments[(0)]),(arguments[(1)]),(arguments[(2)]));
|
||||
|
||||
break;
|
||||
default:
|
||||
throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid arity: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(args8107.length)].join('')));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
clojure.string.index_of.cljs$core$IFn$_invoke$arity$2 = (function (s,value){
|
||||
var result = s.indexOf(value);
|
||||
if((result < (0))){
|
||||
return null;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
clojure.string.index_of.cljs$core$IFn$_invoke$arity$3 = (function (s,value,from_index){
|
||||
var result = s.indexOf(value,from_index);
|
||||
if((result < (0))){
|
||||
return null;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
clojure.string.index_of.cljs$lang$maxFixedArity = 3;
|
||||
|
||||
/**
|
||||
* Return last index of value (string or char) in s, optionally
|
||||
* searching backward from from-index or nil if not found.
|
||||
*/
|
||||
clojure.string.last_index_of = (function clojure$string$last_index_of(var_args){
|
||||
var args8114 = [];
|
||||
var len__7927__auto___8117 = arguments.length;
|
||||
var i__7928__auto___8118 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___8118 < len__7927__auto___8117)){
|
||||
args8114.push((arguments[i__7928__auto___8118]));
|
||||
|
||||
var G__8119 = (i__7928__auto___8118 + (1));
|
||||
i__7928__auto___8118 = G__8119;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var G__8116 = args8114.length;
|
||||
switch (G__8116) {
|
||||
case 2:
|
||||
return clojure.string.last_index_of.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
|
||||
|
||||
break;
|
||||
case 3:
|
||||
return clojure.string.last_index_of.cljs$core$IFn$_invoke$arity$3((arguments[(0)]),(arguments[(1)]),(arguments[(2)]));
|
||||
|
||||
break;
|
||||
default:
|
||||
throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid arity: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(args8114.length)].join('')));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
clojure.string.last_index_of.cljs$core$IFn$_invoke$arity$2 = (function (s,value){
|
||||
var result = s.lastIndexOf(value);
|
||||
if((result < (0))){
|
||||
return null;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
clojure.string.last_index_of.cljs$core$IFn$_invoke$arity$3 = (function (s,value,from_index){
|
||||
var result = s.lastIndexOf(value,from_index);
|
||||
if((result < (0))){
|
||||
return null;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
clojure.string.last_index_of.cljs$lang$maxFixedArity = 3;
|
||||
|
||||
/**
|
||||
* True if s starts with substr.
|
||||
*/
|
||||
clojure.string.starts_with_QMARK_ = (function clojure$string$starts_with_QMARK_(s,substr){
|
||||
return goog.string.startsWith(s,substr);
|
||||
});
|
||||
/**
|
||||
* True if s ends with substr.
|
||||
*/
|
||||
clojure.string.ends_with_QMARK_ = (function clojure$string$ends_with_QMARK_(s,substr){
|
||||
return goog.string.endsWith(s,substr);
|
||||
});
|
||||
/**
|
||||
* True if s includes substr.
|
||||
*/
|
||||
clojure.string.includes_QMARK_ = (function clojure$string$includes_QMARK_(s,substr){
|
||||
return goog.string.contains(s,substr);
|
||||
});
|
||||
|
||||
//# sourceMappingURL=string.js.map
|
1
assets/viz/2/clojure/string.js.map
Normal file
1
assets/viz/2/clojure/string.js.map
Normal file
File diff suppressed because one or more lines are too long
1665
assets/viz/2/goog/array/array.js
Normal file
1665
assets/viz/2/goog/array/array.js
Normal file
File diff suppressed because it is too large
Load Diff
369
assets/viz/2/goog/asserts/asserts.js
Normal file
369
assets/viz/2/goog/asserts/asserts.js
Normal file
@ -0,0 +1,369 @@
|
||||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities to check the preconditions, postconditions and
|
||||
* invariants runtime.
|
||||
*
|
||||
* Methods in this package should be given special treatment by the compiler
|
||||
* for type-inference. For example, <code>goog.asserts.assert(foo)</code>
|
||||
* will restrict <code>foo</code> to a truthy value.
|
||||
*
|
||||
* The compiler has an option to disable asserts. So code like:
|
||||
* <code>
|
||||
* var x = goog.asserts.assert(foo()); goog.asserts.assert(bar());
|
||||
* </code>
|
||||
* will be transformed into:
|
||||
* <code>
|
||||
* var x = foo();
|
||||
* </code>
|
||||
* The compiler will leave in foo() (because its return value is used),
|
||||
* but it will remove bar() because it assumes it does not have side-effects.
|
||||
*
|
||||
* @author agrieve@google.com (Andrew Grieve)
|
||||
*/
|
||||
|
||||
goog.provide('goog.asserts');
|
||||
goog.provide('goog.asserts.AssertionError');
|
||||
|
||||
goog.require('goog.debug.Error');
|
||||
goog.require('goog.dom.NodeType');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether to strip out asserts or to leave them in.
|
||||
*/
|
||||
goog.define('goog.asserts.ENABLE_ASSERTS', goog.DEBUG);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Error object for failed assertions.
|
||||
* @param {string} messagePattern The pattern that was used to form message.
|
||||
* @param {!Array<*>} messageArgs The items to substitute into the pattern.
|
||||
* @constructor
|
||||
* @extends {goog.debug.Error}
|
||||
* @final
|
||||
*/
|
||||
goog.asserts.AssertionError = function(messagePattern, messageArgs) {
|
||||
messageArgs.unshift(messagePattern);
|
||||
goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs));
|
||||
// Remove the messagePattern afterwards to avoid permanently modifying the
|
||||
// passed in array.
|
||||
messageArgs.shift();
|
||||
|
||||
/**
|
||||
* The message pattern used to format the error message. Error handlers can
|
||||
* use this to uniquely identify the assertion.
|
||||
* @type {string}
|
||||
*/
|
||||
this.messagePattern = messagePattern;
|
||||
};
|
||||
goog.inherits(goog.asserts.AssertionError, goog.debug.Error);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.asserts.AssertionError.prototype.name = 'AssertionError';
|
||||
|
||||
|
||||
/**
|
||||
* The default error handler.
|
||||
* @param {!goog.asserts.AssertionError} e The exception to be handled.
|
||||
*/
|
||||
goog.asserts.DEFAULT_ERROR_HANDLER = function(e) {
|
||||
throw e;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The handler responsible for throwing or logging assertion errors.
|
||||
* @private {function(!goog.asserts.AssertionError)}
|
||||
*/
|
||||
goog.asserts.errorHandler_ = goog.asserts.DEFAULT_ERROR_HANDLER;
|
||||
|
||||
|
||||
/**
|
||||
* Throws an exception with the given message and "Assertion failed" prefixed
|
||||
* onto it.
|
||||
* @param {string} defaultMessage The message to use if givenMessage is empty.
|
||||
* @param {Array<*>} defaultArgs The substitution arguments for defaultMessage.
|
||||
* @param {string|undefined} givenMessage Message supplied by the caller.
|
||||
* @param {Array<*>} givenArgs The substitution arguments for givenMessage.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a number.
|
||||
* @private
|
||||
*/
|
||||
goog.asserts.doAssertFailure_ = function(
|
||||
defaultMessage, defaultArgs, givenMessage, givenArgs) {
|
||||
var message = 'Assertion failed';
|
||||
if (givenMessage) {
|
||||
message += ': ' + givenMessage;
|
||||
var args = givenArgs;
|
||||
} else if (defaultMessage) {
|
||||
message += ': ' + defaultMessage;
|
||||
args = defaultArgs;
|
||||
}
|
||||
// The '' + works around an Opera 10 bug in the unit tests. Without it,
|
||||
// a stack trace is added to var message above. With this, a stack trace is
|
||||
// not added until this line (it causes the extra garbage to be added after
|
||||
// the assertion message instead of in the middle of it).
|
||||
var e = new goog.asserts.AssertionError('' + message, args || []);
|
||||
goog.asserts.errorHandler_(e);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets a custom error handler that can be used to customize the behavior of
|
||||
* assertion failures, for example by turning all assertion failures into log
|
||||
* messages.
|
||||
* @param {function(!goog.asserts.AssertionError)} errorHandler
|
||||
*/
|
||||
goog.asserts.setErrorHandler = function(errorHandler) {
|
||||
if (goog.asserts.ENABLE_ASSERTS) {
|
||||
goog.asserts.errorHandler_ = errorHandler;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the condition evaluates to true if goog.asserts.ENABLE_ASSERTS is
|
||||
* true.
|
||||
* @template T
|
||||
* @param {T} condition The condition to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {T} The value of the condition.
|
||||
* @throws {goog.asserts.AssertionError} When the condition evaluates to false.
|
||||
*/
|
||||
goog.asserts.assert = function(condition, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !condition) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'', null, opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return condition;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fails if goog.asserts.ENABLE_ASSERTS is true. This function is useful in case
|
||||
* when we want to add a check in the unreachable area like switch-case
|
||||
* statement:
|
||||
*
|
||||
* <pre>
|
||||
* switch(type) {
|
||||
* case FOO: doSomething(); break;
|
||||
* case BAR: doSomethingElse(); break;
|
||||
* default: goog.asserts.fail('Unrecognized type: ' + type);
|
||||
* // We have only 2 types - "default:" section is unreachable code.
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @throws {goog.asserts.AssertionError} Failure.
|
||||
*/
|
||||
goog.asserts.fail = function(opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS) {
|
||||
goog.asserts.errorHandler_(
|
||||
new goog.asserts.AssertionError(
|
||||
'Failure' + (opt_message ? ': ' + opt_message : ''),
|
||||
Array.prototype.slice.call(arguments, 1)));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a number if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {number} The value, guaranteed to be a number when asserts enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a number.
|
||||
*/
|
||||
goog.asserts.assertNumber = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected number but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {number} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a string if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {string} The value, guaranteed to be a string when asserts enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a string.
|
||||
*/
|
||||
goog.asserts.assertString = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected string but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {string} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a function if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {!Function} The value, guaranteed to be a function when asserts
|
||||
* enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a function.
|
||||
*/
|
||||
goog.asserts.assertFunction = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected function but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {!Function} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is an Object if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {!Object} The value, guaranteed to be a non-null object.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not an object.
|
||||
*/
|
||||
goog.asserts.assertObject = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected object but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {!Object} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is an Array if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {!Array<?>} The value, guaranteed to be a non-null array.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not an array.
|
||||
*/
|
||||
goog.asserts.assertArray = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected array but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {!Array<?>} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a boolean if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {boolean} The value, guaranteed to be a boolean when asserts are
|
||||
* enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a boolean.
|
||||
*/
|
||||
goog.asserts.assertBoolean = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected boolean but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {boolean} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a DOM Element if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {!Element} The value, likely to be a DOM Element when asserts are
|
||||
* enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not an Element.
|
||||
*/
|
||||
goog.asserts.assertElement = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS &&
|
||||
(!goog.isObject(value) || value.nodeType != goog.dom.NodeType.ELEMENT)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected Element but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {!Element} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is an instance of the user-defined type if
|
||||
* goog.asserts.ENABLE_ASSERTS is true.
|
||||
*
|
||||
* The compiler may tighten the type returned by this function.
|
||||
*
|
||||
* @param {?} value The value to check.
|
||||
* @param {function(new: T, ...)} type A user-defined constructor.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not an instance of
|
||||
* type.
|
||||
* @return {T}
|
||||
* @template T
|
||||
*/
|
||||
goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected instanceof %s but got %s.',
|
||||
[goog.asserts.getType_(type), goog.asserts.getType_(value)],
|
||||
opt_message, Array.prototype.slice.call(arguments, 3));
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks that no enumerable keys are present in Object.prototype. Such keys
|
||||
* would break most code that use {@code for (var ... in ...)} loops.
|
||||
*/
|
||||
goog.asserts.assertObjectPrototypeIsIntact = function() {
|
||||
for (var key in Object.prototype) {
|
||||
goog.asserts.fail(key + ' should not be enumerable in Object.prototype.');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the type of a value. If a constructor is passed, and a suitable
|
||||
* string cannot be found, 'unknown type name' will be returned.
|
||||
* @param {*} value A constructor, object, or primitive.
|
||||
* @return {string} The best display name for the value, or 'unknown type name'.
|
||||
* @private
|
||||
*/
|
||||
goog.asserts.getType_ = function(value) {
|
||||
if (value instanceof Function) {
|
||||
return value.displayName || value.name || 'unknown type name';
|
||||
} else if (value instanceof Object) {
|
||||
return value.constructor.displayName || value.constructor.name ||
|
||||
Object.prototype.toString.call(value);
|
||||
} else {
|
||||
return value === null ? 'null' : typeof value;
|
||||
}
|
||||
};
|
2727
assets/viz/2/goog/base.js
Normal file
2727
assets/viz/2/goog/base.js
Normal file
File diff suppressed because it is too large
Load Diff
159
assets/viz/2/goog/debug/entrypointregistry.js
Normal file
159
assets/viz/2/goog/debug/entrypointregistry.js
Normal file
@ -0,0 +1,159 @@
|
||||
// Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A global registry for entry points into a program,
|
||||
* so that they can be instrumented. Each module should register their
|
||||
* entry points with this registry. Designed to be compiled out
|
||||
* if no instrumentation is requested.
|
||||
*
|
||||
* Entry points may be registered before or after a call to
|
||||
* goog.debug.entryPointRegistry.monitorAll. If an entry point is registered
|
||||
* later, the existing monitor will instrument the new entry point.
|
||||
*
|
||||
* @author nicksantos@google.com (Nick Santos)
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.EntryPointMonitor');
|
||||
goog.provide('goog.debug.entryPointRegistry');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*/
|
||||
goog.debug.EntryPointMonitor = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Instruments a function.
|
||||
*
|
||||
* @param {!Function} fn A function to instrument.
|
||||
* @return {!Function} The instrumented function.
|
||||
*/
|
||||
goog.debug.EntryPointMonitor.prototype.wrap;
|
||||
|
||||
|
||||
/**
|
||||
* Try to remove an instrumentation wrapper created by this monitor.
|
||||
* If the function passed to unwrap is not a wrapper created by this
|
||||
* monitor, then we will do nothing.
|
||||
*
|
||||
* Notice that some wrappers may not be unwrappable. For example, if other
|
||||
* monitors have applied their own wrappers, then it will be impossible to
|
||||
* unwrap them because their wrappers will have captured our wrapper.
|
||||
*
|
||||
* So it is important that entry points are unwrapped in the reverse
|
||||
* order that they were wrapped.
|
||||
*
|
||||
* @param {!Function} fn A function to unwrap.
|
||||
* @return {!Function} The unwrapped function, or {@code fn} if it was not
|
||||
* a wrapped function created by this monitor.
|
||||
*/
|
||||
goog.debug.EntryPointMonitor.prototype.unwrap;
|
||||
|
||||
|
||||
/**
|
||||
* An array of entry point callbacks.
|
||||
* @type {!Array<function(!Function)>}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.entryPointRegistry.refList_ = [];
|
||||
|
||||
|
||||
/**
|
||||
* Monitors that should wrap all the entry points.
|
||||
* @type {!Array<!goog.debug.EntryPointMonitor>}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.entryPointRegistry.monitors_ = [];
|
||||
|
||||
|
||||
/**
|
||||
* Whether goog.debug.entryPointRegistry.monitorAll has ever been called.
|
||||
* Checking this allows the compiler to optimize out the registrations.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.entryPointRegistry.monitorsMayExist_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* Register an entry point with this module.
|
||||
*
|
||||
* The entry point will be instrumented when a monitor is passed to
|
||||
* goog.debug.entryPointRegistry.monitorAll. If this has already occurred, the
|
||||
* entry point is instrumented immediately.
|
||||
*
|
||||
* @param {function(!Function)} callback A callback function which is called
|
||||
* with a transforming function to instrument the entry point. The callback
|
||||
* is responsible for wrapping the relevant entry point with the
|
||||
* transforming function.
|
||||
*/
|
||||
goog.debug.entryPointRegistry.register = function(callback) {
|
||||
// Don't use push(), so that this can be compiled out.
|
||||
goog.debug.entryPointRegistry
|
||||
.refList_[goog.debug.entryPointRegistry.refList_.length] = callback;
|
||||
// If no one calls monitorAll, this can be compiled out.
|
||||
if (goog.debug.entryPointRegistry.monitorsMayExist_) {
|
||||
var monitors = goog.debug.entryPointRegistry.monitors_;
|
||||
for (var i = 0; i < monitors.length; i++) {
|
||||
callback(goog.bind(monitors[i].wrap, monitors[i]));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Configures a monitor to wrap all entry points.
|
||||
*
|
||||
* Entry points that have already been registered are immediately wrapped by
|
||||
* the monitor. When an entry point is registered in the future, it will also
|
||||
* be wrapped by the monitor when it is registered.
|
||||
*
|
||||
* @param {!goog.debug.EntryPointMonitor} monitor An entry point monitor.
|
||||
*/
|
||||
goog.debug.entryPointRegistry.monitorAll = function(monitor) {
|
||||
goog.debug.entryPointRegistry.monitorsMayExist_ = true;
|
||||
var transformer = goog.bind(monitor.wrap, monitor);
|
||||
for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) {
|
||||
goog.debug.entryPointRegistry.refList_[i](transformer);
|
||||
}
|
||||
goog.debug.entryPointRegistry.monitors_.push(monitor);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Try to unmonitor all the entry points that have already been registered. If
|
||||
* an entry point is registered in the future, it will not be wrapped by the
|
||||
* monitor when it is registered. Note that this may fail if the entry points
|
||||
* have additional wrapping.
|
||||
*
|
||||
* @param {!goog.debug.EntryPointMonitor} monitor The last monitor to wrap
|
||||
* the entry points.
|
||||
* @throws {Error} If the monitor is not the most recently configured monitor.
|
||||
*/
|
||||
goog.debug.entryPointRegistry.unmonitorAllIfPossible = function(monitor) {
|
||||
var monitors = goog.debug.entryPointRegistry.monitors_;
|
||||
goog.asserts.assert(
|
||||
monitor == monitors[monitors.length - 1],
|
||||
'Only the most recent monitor can be unwrapped.');
|
||||
var transformer = goog.bind(monitor.unwrap, monitor);
|
||||
for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) {
|
||||
goog.debug.entryPointRegistry.refList_[i](transformer);
|
||||
}
|
||||
monitors.length--;
|
||||
};
|
63
assets/viz/2/goog/debug/error.js
Normal file
63
assets/viz/2/goog/debug/error.js
Normal file
@ -0,0 +1,63 @@
|
||||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Provides a base class for custom Error objects such that the
|
||||
* stack is correctly maintained.
|
||||
*
|
||||
* You should never need to throw goog.debug.Error(msg) directly, Error(msg) is
|
||||
* sufficient.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.Error');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class for custom error objects.
|
||||
* @param {*=} opt_msg The message associated with the error.
|
||||
* @constructor
|
||||
* @extends {Error}
|
||||
*/
|
||||
goog.debug.Error = function(opt_msg) {
|
||||
|
||||
// Attempt to ensure there is a stack trace.
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, goog.debug.Error);
|
||||
} else {
|
||||
var stack = new Error().stack;
|
||||
if (stack) {
|
||||
this.stack = stack;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt_msg) {
|
||||
this.message = String(opt_msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to report this error to the server. Setting this to false will
|
||||
* cause the error reporter to not report the error back to the server,
|
||||
* which can be useful if the client knows that the error has already been
|
||||
* logged on the server.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.reportErrorToServer = true;
|
||||
};
|
||||
goog.inherits(goog.debug.Error, Error);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.debug.Error.prototype.name = 'CustomError';
|
1508
assets/viz/2/goog/deps.js
Normal file
1508
assets/viz/2/goog/deps.js
Normal file
File diff suppressed because one or more lines are too long
308
assets/viz/2/goog/disposable/disposable.js
Normal file
308
assets/viz/2/goog/disposable/disposable.js
Normal file
@ -0,0 +1,308 @@
|
||||
// Copyright 2005 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Implements the disposable interface. The dispose method is used
|
||||
* to clean up references and resources.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.Disposable');
|
||||
/** @suppress {extraProvide} */
|
||||
goog.provide('goog.dispose');
|
||||
/** @suppress {extraProvide} */
|
||||
goog.provide('goog.disposeAll');
|
||||
|
||||
goog.require('goog.disposable.IDisposable');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class that provides the basic implementation for disposable objects. If your
|
||||
* class holds one or more references to COM objects, DOM nodes, or other
|
||||
* disposable objects, it should extend this class or implement the disposable
|
||||
* interface (defined in goog.disposable.IDisposable).
|
||||
* @constructor
|
||||
* @implements {goog.disposable.IDisposable}
|
||||
*/
|
||||
goog.Disposable = function() {
|
||||
if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {
|
||||
if (goog.Disposable.INCLUDE_STACK_ON_CREATION) {
|
||||
this.creationStack = new Error().stack;
|
||||
}
|
||||
goog.Disposable.instances_[goog.getUid(this)] = this;
|
||||
}
|
||||
// Support sealing
|
||||
this.disposed_ = this.disposed_;
|
||||
this.onDisposeCallbacks_ = this.onDisposeCallbacks_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {number} Different monitoring modes for Disposable.
|
||||
*/
|
||||
goog.Disposable.MonitoringMode = {
|
||||
/**
|
||||
* No monitoring.
|
||||
*/
|
||||
OFF: 0,
|
||||
/**
|
||||
* Creating and disposing the goog.Disposable instances is monitored. All
|
||||
* disposable objects need to call the {@code goog.Disposable} base
|
||||
* constructor. The PERMANENT mode must be switched on before creating any
|
||||
* goog.Disposable instances.
|
||||
*/
|
||||
PERMANENT: 1,
|
||||
/**
|
||||
* INTERACTIVE mode can be switched on and off on the fly without producing
|
||||
* errors. It also doesn't warn if the disposable objects don't call the
|
||||
* {@code goog.Disposable} base constructor.
|
||||
*/
|
||||
INTERACTIVE: 2
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @define {number} The monitoring mode of the goog.Disposable
|
||||
* instances. Default is OFF. Switching on the monitoring is only
|
||||
* recommended for debugging because it has a significant impact on
|
||||
* performance and memory usage. If switched off, the monitoring code
|
||||
* compiles down to 0 bytes.
|
||||
*/
|
||||
goog.define('goog.Disposable.MONITORING_MODE', 0);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether to attach creation stack to each created disposable
|
||||
* instance; This is only relevant for when MonitoringMode != OFF.
|
||||
*/
|
||||
goog.define('goog.Disposable.INCLUDE_STACK_ON_CREATION', true);
|
||||
|
||||
|
||||
/**
|
||||
* Maps the unique ID of every undisposed {@code goog.Disposable} object to
|
||||
* the object itself.
|
||||
* @type {!Object<number, !goog.Disposable>}
|
||||
* @private
|
||||
*/
|
||||
goog.Disposable.instances_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Array<!goog.Disposable>} All {@code goog.Disposable} objects that
|
||||
* haven't been disposed of.
|
||||
*/
|
||||
goog.Disposable.getUndisposedObjects = function() {
|
||||
var ret = [];
|
||||
for (var id in goog.Disposable.instances_) {
|
||||
if (goog.Disposable.instances_.hasOwnProperty(id)) {
|
||||
ret.push(goog.Disposable.instances_[Number(id)]);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the registry of undisposed objects but doesn't dispose of them.
|
||||
*/
|
||||
goog.Disposable.clearUndisposedObjects = function() {
|
||||
goog.Disposable.instances_ = {};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the object has been disposed of.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.Disposable.prototype.disposed_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* Callbacks to invoke when this object is disposed.
|
||||
* @type {Array<!Function>}
|
||||
* @private
|
||||
*/
|
||||
goog.Disposable.prototype.onDisposeCallbacks_;
|
||||
|
||||
|
||||
/**
|
||||
* If monitoring the goog.Disposable instances is enabled, stores the creation
|
||||
* stack trace of the Disposable instance.
|
||||
* @const {string}
|
||||
*/
|
||||
goog.Disposable.prototype.creationStack;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the object has been disposed of.
|
||||
* @override
|
||||
*/
|
||||
goog.Disposable.prototype.isDisposed = function() {
|
||||
return this.disposed_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the object has been disposed of.
|
||||
* @deprecated Use {@link #isDisposed} instead.
|
||||
*/
|
||||
goog.Disposable.prototype.getDisposed = goog.Disposable.prototype.isDisposed;
|
||||
|
||||
|
||||
/**
|
||||
* Disposes of the object. If the object hasn't already been disposed of, calls
|
||||
* {@link #disposeInternal}. Classes that extend {@code goog.Disposable} should
|
||||
* override {@link #disposeInternal} in order to delete references to COM
|
||||
* objects, DOM nodes, and other disposable objects. Reentrant.
|
||||
*
|
||||
* @return {void} Nothing.
|
||||
* @override
|
||||
*/
|
||||
goog.Disposable.prototype.dispose = function() {
|
||||
if (!this.disposed_) {
|
||||
// Set disposed_ to true first, in case during the chain of disposal this
|
||||
// gets disposed recursively.
|
||||
this.disposed_ = true;
|
||||
this.disposeInternal();
|
||||
if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {
|
||||
var uid = goog.getUid(this);
|
||||
if (goog.Disposable.MONITORING_MODE ==
|
||||
goog.Disposable.MonitoringMode.PERMANENT &&
|
||||
!goog.Disposable.instances_.hasOwnProperty(uid)) {
|
||||
throw Error(
|
||||
this + ' did not call the goog.Disposable base ' +
|
||||
'constructor or was disposed of after a clearUndisposedObjects ' +
|
||||
'call');
|
||||
}
|
||||
delete goog.Disposable.instances_[uid];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Associates a disposable object with this object so that they will be disposed
|
||||
* together.
|
||||
* @param {goog.disposable.IDisposable} disposable that will be disposed when
|
||||
* this object is disposed.
|
||||
*/
|
||||
goog.Disposable.prototype.registerDisposable = function(disposable) {
|
||||
this.addOnDisposeCallback(goog.partial(goog.dispose, disposable));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Invokes a callback function when this object is disposed. Callbacks are
|
||||
* invoked in the order in which they were added. If a callback is added to
|
||||
* an already disposed Disposable, it will be called immediately.
|
||||
* @param {function(this:T):?} callback The callback function.
|
||||
* @param {T=} opt_scope An optional scope to call the callback in.
|
||||
* @template T
|
||||
*/
|
||||
goog.Disposable.prototype.addOnDisposeCallback = function(callback, opt_scope) {
|
||||
if (this.disposed_) {
|
||||
callback.call(opt_scope);
|
||||
return;
|
||||
}
|
||||
if (!this.onDisposeCallbacks_) {
|
||||
this.onDisposeCallbacks_ = [];
|
||||
}
|
||||
|
||||
this.onDisposeCallbacks_.push(
|
||||
goog.isDef(opt_scope) ? goog.bind(callback, opt_scope) : callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deletes or nulls out any references to COM objects, DOM nodes, or other
|
||||
* disposable objects. Classes that extend {@code goog.Disposable} should
|
||||
* override this method.
|
||||
* Not reentrant. To avoid calling it twice, it must only be called from the
|
||||
* subclass' {@code disposeInternal} method. Everywhere else the public
|
||||
* {@code dispose} method must be used.
|
||||
* For example:
|
||||
* <pre>
|
||||
* mypackage.MyClass = function() {
|
||||
* mypackage.MyClass.base(this, 'constructor');
|
||||
* // Constructor logic specific to MyClass.
|
||||
* ...
|
||||
* };
|
||||
* goog.inherits(mypackage.MyClass, goog.Disposable);
|
||||
*
|
||||
* mypackage.MyClass.prototype.disposeInternal = function() {
|
||||
* // Dispose logic specific to MyClass.
|
||||
* ...
|
||||
* // Call superclass's disposeInternal at the end of the subclass's, like
|
||||
* // in C++, to avoid hard-to-catch issues.
|
||||
* mypackage.MyClass.base(this, 'disposeInternal');
|
||||
* };
|
||||
* </pre>
|
||||
* @protected
|
||||
*/
|
||||
goog.Disposable.prototype.disposeInternal = function() {
|
||||
if (this.onDisposeCallbacks_) {
|
||||
while (this.onDisposeCallbacks_.length) {
|
||||
this.onDisposeCallbacks_.shift()();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns True if we can verify the object is disposed.
|
||||
* Calls {@code isDisposed} on the argument if it supports it. If obj
|
||||
* is not an object with an isDisposed() method, return false.
|
||||
* @param {*} obj The object to investigate.
|
||||
* @return {boolean} True if we can verify the object is disposed.
|
||||
*/
|
||||
goog.Disposable.isDisposed = function(obj) {
|
||||
if (obj && typeof obj.isDisposed == 'function') {
|
||||
return obj.isDisposed();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls {@code dispose} on the argument if it supports it. If obj is not an
|
||||
* object with a dispose() method, this is a no-op.
|
||||
* @param {*} obj The object to dispose of.
|
||||
*/
|
||||
goog.dispose = function(obj) {
|
||||
if (obj && typeof obj.dispose == 'function') {
|
||||
obj.dispose();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls {@code dispose} on each member of the list that supports it. (If the
|
||||
* member is an ArrayLike, then {@code goog.disposeAll()} will be called
|
||||
* recursively on each of its members.) If the member is not an object with a
|
||||
* {@code dispose()} method, then it is ignored.
|
||||
* @param {...*} var_args The list.
|
||||
*/
|
||||
goog.disposeAll = function(var_args) {
|
||||
for (var i = 0, len = arguments.length; i < len; ++i) {
|
||||
var disposable = arguments[i];
|
||||
if (goog.isArrayLike(disposable)) {
|
||||
goog.disposeAll.apply(null, disposable);
|
||||
} else {
|
||||
goog.dispose(disposable);
|
||||
}
|
||||
}
|
||||
};
|
45
assets/viz/2/goog/disposable/idisposable.js
Normal file
45
assets/viz/2/goog/disposable/idisposable.js
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Definition of the disposable interface. A disposable object
|
||||
* has a dispose method to to clean up references and resources.
|
||||
* @author nnaze@google.com (Nathan Naze)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.disposable.IDisposable');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a disposable object. If a instance requires cleanup
|
||||
* (references COM objects, DOM notes, or other disposable objects), it should
|
||||
* implement this interface (it may subclass goog.Disposable).
|
||||
* @interface
|
||||
*/
|
||||
goog.disposable.IDisposable = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Disposes of the object and its resources.
|
||||
* @return {void} Nothing.
|
||||
*/
|
||||
goog.disposable.IDisposable.prototype.dispose = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the object has been disposed of.
|
||||
*/
|
||||
goog.disposable.IDisposable.prototype.isDisposed = goog.abstractMethod;
|
73
assets/viz/2/goog/dom/browserfeature.js
Normal file
73
assets/viz/2/goog/dom/browserfeature.js
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Browser capability checks for the dom package.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.dom.BrowserFeature');
|
||||
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
* Enum of browser capabilities.
|
||||
* @enum {boolean}
|
||||
*/
|
||||
goog.dom.BrowserFeature = {
|
||||
/**
|
||||
* Whether attributes 'name' and 'type' can be added to an element after it's
|
||||
* created. False in Internet Explorer prior to version 9.
|
||||
*/
|
||||
CAN_ADD_NAME_OR_TYPE_ATTRIBUTES:
|
||||
!goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9),
|
||||
|
||||
/**
|
||||
* Whether we can use element.children to access an element's Element
|
||||
* children. Available since Gecko 1.9.1, IE 9. (IE<9 also includes comment
|
||||
* nodes in the collection.)
|
||||
*/
|
||||
CAN_USE_CHILDREN_ATTRIBUTE: !goog.userAgent.GECKO && !goog.userAgent.IE ||
|
||||
goog.userAgent.IE && goog.userAgent.isDocumentModeOrHigher(9) ||
|
||||
goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9.1'),
|
||||
|
||||
/**
|
||||
* Opera, Safari 3, and Internet Explorer 9 all support innerText but they
|
||||
* include text nodes in script and style tags. Not document-mode-dependent.
|
||||
*/
|
||||
CAN_USE_INNER_TEXT:
|
||||
(goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9')),
|
||||
|
||||
/**
|
||||
* MSIE, Opera, and Safari>=4 support element.parentElement to access an
|
||||
* element's parent if it is an Element.
|
||||
*/
|
||||
CAN_USE_PARENT_ELEMENT_PROPERTY:
|
||||
goog.userAgent.IE || goog.userAgent.OPERA || goog.userAgent.WEBKIT,
|
||||
|
||||
/**
|
||||
* Whether NoScope elements need a scoped element written before them in
|
||||
* innerHTML.
|
||||
* MSDN: http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx#1
|
||||
*/
|
||||
INNER_HTML_NEEDS_SCOPED_ELEMENT: goog.userAgent.IE,
|
||||
|
||||
/**
|
||||
* Whether we use legacy IE range API.
|
||||
*/
|
||||
LEGACY_IE_RANGES:
|
||||
goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)
|
||||
};
|
2992
assets/viz/2/goog/dom/dom.js
Normal file
2992
assets/viz/2/goog/dom/dom.js
Normal file
File diff suppressed because it is too large
Load Diff
48
assets/viz/2/goog/dom/nodetype.js
Normal file
48
assets/viz/2/goog/dom/nodetype.js
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Definition of goog.dom.NodeType.
|
||||
*/
|
||||
|
||||
goog.provide('goog.dom.NodeType');
|
||||
|
||||
|
||||
/**
|
||||
* Constants for the nodeType attribute in the Node interface.
|
||||
*
|
||||
* These constants match those specified in the Node interface. These are
|
||||
* usually present on the Node object in recent browsers, but not in older
|
||||
* browsers (specifically, early IEs) and thus are given here.
|
||||
*
|
||||
* In some browsers (early IEs), these are not defined on the Node object,
|
||||
* so they are provided here.
|
||||
*
|
||||
* See http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247
|
||||
* @enum {number}
|
||||
*/
|
||||
goog.dom.NodeType = {
|
||||
ELEMENT: 1,
|
||||
ATTRIBUTE: 2,
|
||||
TEXT: 3,
|
||||
CDATA_SECTION: 4,
|
||||
ENTITY_REFERENCE: 5,
|
||||
ENTITY: 6,
|
||||
PROCESSING_INSTRUCTION: 7,
|
||||
COMMENT: 8,
|
||||
DOCUMENT: 9,
|
||||
DOCUMENT_TYPE: 10,
|
||||
DOCUMENT_FRAGMENT: 11,
|
||||
NOTATION: 12
|
||||
};
|
372
assets/viz/2/goog/dom/safe.js
Normal file
372
assets/viz/2/goog/dom/safe.js
Normal file
@ -0,0 +1,372 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Type-safe wrappers for unsafe DOM APIs.
|
||||
*
|
||||
* This file provides type-safe wrappers for DOM APIs that can result in
|
||||
* cross-site scripting (XSS) vulnerabilities, if the API is supplied with
|
||||
* untrusted (attacker-controlled) input. Instead of plain strings, the type
|
||||
* safe wrappers consume values of types from the goog.html package whose
|
||||
* contract promises that values are safe to use in the corresponding context.
|
||||
*
|
||||
* Hence, a program that exclusively uses the wrappers in this file (i.e., whose
|
||||
* only reference to security-sensitive raw DOM APIs are in this file) is
|
||||
* guaranteed to be free of XSS due to incorrect use of such DOM APIs (modulo
|
||||
* correctness of code that produces values of the respective goog.html types,
|
||||
* and absent code that violates type safety).
|
||||
*
|
||||
* For example, assigning to an element's .innerHTML property a string that is
|
||||
* derived (even partially) from untrusted input typically results in an XSS
|
||||
* vulnerability. The type-safe wrapper goog.html.setInnerHtml consumes a value
|
||||
* of type goog.html.SafeHtml, whose contract states that using its values in a
|
||||
* HTML context will not result in XSS. Hence a program that is free of direct
|
||||
* assignments to any element's innerHTML property (with the exception of the
|
||||
* assignment to .innerHTML in this file) is guaranteed to be free of XSS due to
|
||||
* assignment of untrusted strings to the innerHTML property.
|
||||
*/
|
||||
|
||||
goog.provide('goog.dom.safe');
|
||||
goog.provide('goog.dom.safe.InsertAdjacentHtmlPosition');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.html.SafeHtml');
|
||||
goog.require('goog.html.SafeUrl');
|
||||
goog.require('goog.html.TrustedResourceUrl');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.Const');
|
||||
|
||||
|
||||
/** @enum {string} */
|
||||
goog.dom.safe.InsertAdjacentHtmlPosition = {
|
||||
AFTERBEGIN: 'afterbegin',
|
||||
AFTEREND: 'afterend',
|
||||
BEFOREBEGIN: 'beforebegin',
|
||||
BEFOREEND: 'beforeend'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Inserts known-safe HTML into a Node, at the specified position.
|
||||
* @param {!Node} node The node on which to call insertAdjacentHTML.
|
||||
* @param {!goog.dom.safe.InsertAdjacentHtmlPosition} position Position where
|
||||
* to insert the HTML.
|
||||
* @param {!goog.html.SafeHtml} html The known-safe HTML to insert.
|
||||
*/
|
||||
goog.dom.safe.insertAdjacentHtml = function(node, position, html) {
|
||||
node.insertAdjacentHTML(position, goog.html.SafeHtml.unwrap(html));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Assigns known-safe HTML to an element's innerHTML property.
|
||||
* @param {!Element} elem The element whose innerHTML is to be assigned to.
|
||||
* @param {!goog.html.SafeHtml} html The known-safe HTML to assign.
|
||||
*/
|
||||
goog.dom.safe.setInnerHtml = function(elem, html) {
|
||||
elem.innerHTML = goog.html.SafeHtml.unwrap(html);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Assigns known-safe HTML to an element's outerHTML property.
|
||||
* @param {!Element} elem The element whose outerHTML is to be assigned to.
|
||||
* @param {!goog.html.SafeHtml} html The known-safe HTML to assign.
|
||||
*/
|
||||
goog.dom.safe.setOuterHtml = function(elem, html) {
|
||||
elem.outerHTML = goog.html.SafeHtml.unwrap(html);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes known-safe HTML to a document.
|
||||
* @param {!Document} doc The document to be written to.
|
||||
* @param {!goog.html.SafeHtml} html The known-safe HTML to assign.
|
||||
*/
|
||||
goog.dom.safe.documentWrite = function(doc, html) {
|
||||
doc.write(goog.html.SafeHtml.unwrap(html));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to an anchor element's href property.
|
||||
*
|
||||
* If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to
|
||||
* anchor's href property. If url is of type string however, it is first
|
||||
* sanitized using goog.html.SafeUrl.sanitize.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setAnchorHref(anchorEl, url);
|
||||
* which is a safe alternative to
|
||||
* anchorEl.href = url;
|
||||
* The latter can result in XSS vulnerabilities if url is a
|
||||
* user-/attacker-controlled value.
|
||||
*
|
||||
* @param {!HTMLAnchorElement} anchor The anchor element whose href property
|
||||
* is to be assigned to.
|
||||
* @param {string|!goog.html.SafeUrl} url The URL to assign.
|
||||
* @see goog.html.SafeUrl#sanitize
|
||||
*/
|
||||
goog.dom.safe.setAnchorHref = function(anchor, url) {
|
||||
/** @type {!goog.html.SafeUrl} */
|
||||
var safeUrl;
|
||||
if (url instanceof goog.html.SafeUrl) {
|
||||
safeUrl = url;
|
||||
} else {
|
||||
safeUrl = goog.html.SafeUrl.sanitize(url);
|
||||
}
|
||||
anchor.href = goog.html.SafeUrl.unwrap(safeUrl);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to an image element's src property.
|
||||
*
|
||||
* If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to
|
||||
* image's src property. If url is of type string however, it is first
|
||||
* sanitized using goog.html.SafeUrl.sanitize.
|
||||
*
|
||||
* @param {!HTMLImageElement} imageElement The image element whose src property
|
||||
* is to be assigned to.
|
||||
* @param {string|!goog.html.SafeUrl} url The URL to assign.
|
||||
* @see goog.html.SafeUrl#sanitize
|
||||
*/
|
||||
goog.dom.safe.setImageSrc = function(imageElement, url) {
|
||||
/** @type {!goog.html.SafeUrl} */
|
||||
var safeUrl;
|
||||
if (url instanceof goog.html.SafeUrl) {
|
||||
safeUrl = url;
|
||||
} else {
|
||||
safeUrl = goog.html.SafeUrl.sanitize(url);
|
||||
}
|
||||
imageElement.src = goog.html.SafeUrl.unwrap(safeUrl);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to an embed element's src property.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setEmbedSrc(embedEl, url);
|
||||
* which is a safe alternative to
|
||||
* embedEl.src = url;
|
||||
* The latter can result in loading untrusted code unless it is ensured that
|
||||
* the URL refers to a trustworthy resource.
|
||||
*
|
||||
* @param {!HTMLEmbedElement} embed The embed element whose src property
|
||||
* is to be assigned to.
|
||||
* @param {!goog.html.TrustedResourceUrl} url The URL to assign.
|
||||
*/
|
||||
goog.dom.safe.setEmbedSrc = function(embed, url) {
|
||||
embed.src = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to a frame element's src property.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setFrameSrc(frameEl, url);
|
||||
* which is a safe alternative to
|
||||
* frameEl.src = url;
|
||||
* The latter can result in loading untrusted code unless it is ensured that
|
||||
* the URL refers to a trustworthy resource.
|
||||
*
|
||||
* @param {!HTMLFrameElement} frame The frame element whose src property
|
||||
* is to be assigned to.
|
||||
* @param {!goog.html.TrustedResourceUrl} url The URL to assign.
|
||||
*/
|
||||
goog.dom.safe.setFrameSrc = function(frame, url) {
|
||||
frame.src = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to an iframe element's src property.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setIframeSrc(iframeEl, url);
|
||||
* which is a safe alternative to
|
||||
* iframeEl.src = url;
|
||||
* The latter can result in loading untrusted code unless it is ensured that
|
||||
* the URL refers to a trustworthy resource.
|
||||
*
|
||||
* @param {!HTMLIFrameElement} iframe The iframe element whose src property
|
||||
* is to be assigned to.
|
||||
* @param {!goog.html.TrustedResourceUrl} url The URL to assign.
|
||||
*/
|
||||
goog.dom.safe.setIframeSrc = function(iframe, url) {
|
||||
iframe.src = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely sets a link element's href and rel properties. Whether or not
|
||||
* the URL assigned to href has to be a goog.html.TrustedResourceUrl
|
||||
* depends on the value of the rel property. If rel contains "stylesheet"
|
||||
* then a TrustedResourceUrl is required.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setLinkHrefAndRel(linkEl, url, 'stylesheet');
|
||||
* which is a safe alternative to
|
||||
* linkEl.rel = 'stylesheet';
|
||||
* linkEl.href = url;
|
||||
* The latter can result in loading untrusted code unless it is ensured that
|
||||
* the URL refers to a trustworthy resource.
|
||||
*
|
||||
* @param {!HTMLLinkElement} link The link element whose href property
|
||||
* is to be assigned to.
|
||||
* @param {string|!goog.html.SafeUrl|!goog.html.TrustedResourceUrl} url The URL
|
||||
* to assign to the href property. Must be a TrustedResourceUrl if the
|
||||
* value assigned to rel contains "stylesheet". A string value is
|
||||
* sanitized with goog.html.SafeUrl.sanitize.
|
||||
* @param {string} rel The value to assign to the rel property.
|
||||
* @throws {Error} if rel contains "stylesheet" and url is not a
|
||||
* TrustedResourceUrl
|
||||
* @see goog.html.SafeUrl#sanitize
|
||||
*/
|
||||
goog.dom.safe.setLinkHrefAndRel = function(link, url, rel) {
|
||||
link.rel = rel;
|
||||
if (goog.string.caseInsensitiveContains(rel, 'stylesheet')) {
|
||||
goog.asserts.assert(
|
||||
url instanceof goog.html.TrustedResourceUrl,
|
||||
'URL must be TrustedResourceUrl because "rel" contains "stylesheet"');
|
||||
link.href = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
} else if (url instanceof goog.html.TrustedResourceUrl) {
|
||||
link.href = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
} else if (url instanceof goog.html.SafeUrl) {
|
||||
link.href = goog.html.SafeUrl.unwrap(url);
|
||||
} else { // string
|
||||
// SafeUrl.sanitize must return legitimate SafeUrl when passed a string.
|
||||
link.href = goog.html.SafeUrl.sanitize(url).getTypedStringValue();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to an object element's data property.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setObjectData(objectEl, url);
|
||||
* which is a safe alternative to
|
||||
* objectEl.data = url;
|
||||
* The latter can result in loading untrusted code unless setit is ensured that
|
||||
* the URL refers to a trustworthy resource.
|
||||
*
|
||||
* @param {!HTMLObjectElement} object The object element whose data property
|
||||
* is to be assigned to.
|
||||
* @param {!goog.html.TrustedResourceUrl} url The URL to assign.
|
||||
*/
|
||||
goog.dom.safe.setObjectData = function(object, url) {
|
||||
object.data = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to an iframe element's src property.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setScriptSrc(scriptEl, url);
|
||||
* which is a safe alternative to
|
||||
* scriptEl.src = url;
|
||||
* The latter can result in loading untrusted code unless it is ensured that
|
||||
* the URL refers to a trustworthy resource.
|
||||
*
|
||||
* @param {!HTMLScriptElement} script The script element whose src property
|
||||
* is to be assigned to.
|
||||
* @param {!goog.html.TrustedResourceUrl} url The URL to assign.
|
||||
*/
|
||||
goog.dom.safe.setScriptSrc = function(script, url) {
|
||||
script.src = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to a Location object's href property.
|
||||
*
|
||||
* If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to
|
||||
* loc's href property. If url is of type string however, it is first sanitized
|
||||
* using goog.html.SafeUrl.sanitize.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setLocationHref(document.location, redirectUrl);
|
||||
* which is a safe alternative to
|
||||
* document.location.href = redirectUrl;
|
||||
* The latter can result in XSS vulnerabilities if redirectUrl is a
|
||||
* user-/attacker-controlled value.
|
||||
*
|
||||
* @param {!Location} loc The Location object whose href property is to be
|
||||
* assigned to.
|
||||
* @param {string|!goog.html.SafeUrl} url The URL to assign.
|
||||
* @see goog.html.SafeUrl#sanitize
|
||||
*/
|
||||
goog.dom.safe.setLocationHref = function(loc, url) {
|
||||
/** @type {!goog.html.SafeUrl} */
|
||||
var safeUrl;
|
||||
if (url instanceof goog.html.SafeUrl) {
|
||||
safeUrl = url;
|
||||
} else {
|
||||
safeUrl = goog.html.SafeUrl.sanitize(url);
|
||||
}
|
||||
loc.href = goog.html.SafeUrl.unwrap(safeUrl);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely opens a URL in a new window (via window.open).
|
||||
*
|
||||
* If url is of type goog.html.SafeUrl, its value is unwrapped and passed in to
|
||||
* window.open. If url is of type string however, it is first sanitized
|
||||
* using goog.html.SafeUrl.sanitize.
|
||||
*
|
||||
* Note that this function does not prevent leakages via the referer that is
|
||||
* sent by window.open. It is advised to only use this to open 1st party URLs.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.openInWindow(url);
|
||||
* which is a safe alternative to
|
||||
* window.open(url);
|
||||
* The latter can result in XSS vulnerabilities if redirectUrl is a
|
||||
* user-/attacker-controlled value.
|
||||
*
|
||||
* @param {string|!goog.html.SafeUrl} url The URL to open.
|
||||
* @param {Window=} opt_openerWin Window of which to call the .open() method.
|
||||
* Defaults to the global window.
|
||||
* @param {!goog.string.Const=} opt_name Name of the window to open in. Can be
|
||||
* _top, etc as allowed by window.open().
|
||||
* @param {string=} opt_specs Comma-separated list of specifications, same as
|
||||
* in window.open().
|
||||
* @param {boolean=} opt_replace Whether to replace the current entry in browser
|
||||
* history, same as in window.open().
|
||||
* @return {Window} Window the url was opened in.
|
||||
*/
|
||||
goog.dom.safe.openInWindow = function(
|
||||
url, opt_openerWin, opt_name, opt_specs, opt_replace) {
|
||||
/** @type {!goog.html.SafeUrl} */
|
||||
var safeUrl;
|
||||
if (url instanceof goog.html.SafeUrl) {
|
||||
safeUrl = url;
|
||||
} else {
|
||||
safeUrl = goog.html.SafeUrl.sanitize(url);
|
||||
}
|
||||
var win = opt_openerWin || window;
|
||||
return win.open(
|
||||
goog.html.SafeUrl.unwrap(safeUrl),
|
||||
// If opt_name is undefined, simply passing that in to open() causes IE to
|
||||
// reuse the current window instead of opening a new one. Thus we pass ''
|
||||
// in instead, which according to spec opens a new window. See
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#dom-open .
|
||||
opt_name ? goog.string.Const.unwrap(opt_name) : '', opt_specs,
|
||||
opt_replace);
|
||||
};
|
160
assets/viz/2/goog/dom/tagname.js
Normal file
160
assets/viz/2/goog/dom/tagname.js
Normal file
@ -0,0 +1,160 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Defines the goog.dom.TagName enum. This enumerates
|
||||
* all HTML tag names specified in either the the W3C HTML 4.01 index of
|
||||
* elements or the HTML5 draft specification.
|
||||
*
|
||||
* References:
|
||||
* http://www.w3.org/TR/html401/index/elements.html
|
||||
* http://dev.w3.org/html5/spec/section-index.html
|
||||
*
|
||||
*/
|
||||
goog.provide('goog.dom.TagName');
|
||||
|
||||
|
||||
/**
|
||||
* Enum of all html tag names specified by the W3C HTML4.01 and HTML5
|
||||
* specifications.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.dom.TagName = {
|
||||
A: 'A',
|
||||
ABBR: 'ABBR',
|
||||
ACRONYM: 'ACRONYM',
|
||||
ADDRESS: 'ADDRESS',
|
||||
APPLET: 'APPLET',
|
||||
AREA: 'AREA',
|
||||
ARTICLE: 'ARTICLE',
|
||||
ASIDE: 'ASIDE',
|
||||
AUDIO: 'AUDIO',
|
||||
B: 'B',
|
||||
BASE: 'BASE',
|
||||
BASEFONT: 'BASEFONT',
|
||||
BDI: 'BDI',
|
||||
BDO: 'BDO',
|
||||
BIG: 'BIG',
|
||||
BLOCKQUOTE: 'BLOCKQUOTE',
|
||||
BODY: 'BODY',
|
||||
BR: 'BR',
|
||||
BUTTON: 'BUTTON',
|
||||
CANVAS: 'CANVAS',
|
||||
CAPTION: 'CAPTION',
|
||||
CENTER: 'CENTER',
|
||||
CITE: 'CITE',
|
||||
CODE: 'CODE',
|
||||
COL: 'COL',
|
||||
COLGROUP: 'COLGROUP',
|
||||
COMMAND: 'COMMAND',
|
||||
DATA: 'DATA',
|
||||
DATALIST: 'DATALIST',
|
||||
DD: 'DD',
|
||||
DEL: 'DEL',
|
||||
DETAILS: 'DETAILS',
|
||||
DFN: 'DFN',
|
||||
DIALOG: 'DIALOG',
|
||||
DIR: 'DIR',
|
||||
DIV: 'DIV',
|
||||
DL: 'DL',
|
||||
DT: 'DT',
|
||||
EM: 'EM',
|
||||
EMBED: 'EMBED',
|
||||
FIELDSET: 'FIELDSET',
|
||||
FIGCAPTION: 'FIGCAPTION',
|
||||
FIGURE: 'FIGURE',
|
||||
FONT: 'FONT',
|
||||
FOOTER: 'FOOTER',
|
||||
FORM: 'FORM',
|
||||
FRAME: 'FRAME',
|
||||
FRAMESET: 'FRAMESET',
|
||||
H1: 'H1',
|
||||
H2: 'H2',
|
||||
H3: 'H3',
|
||||
H4: 'H4',
|
||||
H5: 'H5',
|
||||
H6: 'H6',
|
||||
HEAD: 'HEAD',
|
||||
HEADER: 'HEADER',
|
||||
HGROUP: 'HGROUP',
|
||||
HR: 'HR',
|
||||
HTML: 'HTML',
|
||||
I: 'I',
|
||||
IFRAME: 'IFRAME',
|
||||
IMG: 'IMG',
|
||||
INPUT: 'INPUT',
|
||||
INS: 'INS',
|
||||
ISINDEX: 'ISINDEX',
|
||||
KBD: 'KBD',
|
||||
KEYGEN: 'KEYGEN',
|
||||
LABEL: 'LABEL',
|
||||
LEGEND: 'LEGEND',
|
||||
LI: 'LI',
|
||||
LINK: 'LINK',
|
||||
MAP: 'MAP',
|
||||
MARK: 'MARK',
|
||||
MATH: 'MATH',
|
||||
MENU: 'MENU',
|
||||
META: 'META',
|
||||
METER: 'METER',
|
||||
NAV: 'NAV',
|
||||
NOFRAMES: 'NOFRAMES',
|
||||
NOSCRIPT: 'NOSCRIPT',
|
||||
OBJECT: 'OBJECT',
|
||||
OL: 'OL',
|
||||
OPTGROUP: 'OPTGROUP',
|
||||
OPTION: 'OPTION',
|
||||
OUTPUT: 'OUTPUT',
|
||||
P: 'P',
|
||||
PARAM: 'PARAM',
|
||||
PRE: 'PRE',
|
||||
PROGRESS: 'PROGRESS',
|
||||
Q: 'Q',
|
||||
RP: 'RP',
|
||||
RT: 'RT',
|
||||
RUBY: 'RUBY',
|
||||
S: 'S',
|
||||
SAMP: 'SAMP',
|
||||
SCRIPT: 'SCRIPT',
|
||||
SECTION: 'SECTION',
|
||||
SELECT: 'SELECT',
|
||||
SMALL: 'SMALL',
|
||||
SOURCE: 'SOURCE',
|
||||
SPAN: 'SPAN',
|
||||
STRIKE: 'STRIKE',
|
||||
STRONG: 'STRONG',
|
||||
STYLE: 'STYLE',
|
||||
SUB: 'SUB',
|
||||
SUMMARY: 'SUMMARY',
|
||||
SUP: 'SUP',
|
||||
SVG: 'SVG',
|
||||
TABLE: 'TABLE',
|
||||
TBODY: 'TBODY',
|
||||
TD: 'TD',
|
||||
TEMPLATE: 'TEMPLATE',
|
||||
TEXTAREA: 'TEXTAREA',
|
||||
TFOOT: 'TFOOT',
|
||||
TH: 'TH',
|
||||
THEAD: 'THEAD',
|
||||
TIME: 'TIME',
|
||||
TITLE: 'TITLE',
|
||||
TR: 'TR',
|
||||
TRACK: 'TRACK',
|
||||
TT: 'TT',
|
||||
U: 'U',
|
||||
UL: 'UL',
|
||||
VAR: 'VAR',
|
||||
VIDEO: 'VIDEO',
|
||||
WBR: 'WBR'
|
||||
};
|
41
assets/viz/2/goog/dom/tags.js
Normal file
41
assets/viz/2/goog/dom/tags.js
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2014 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities for HTML element tag names.
|
||||
*/
|
||||
goog.provide('goog.dom.tags');
|
||||
|
||||
goog.require('goog.object');
|
||||
|
||||
|
||||
/**
|
||||
* The void elements specified by
|
||||
* http://www.w3.org/TR/html-markup/syntax.html#void-elements.
|
||||
* @const @private {!Object<string, boolean>}
|
||||
*/
|
||||
goog.dom.tags.VOID_TAGS_ = goog.object.createSet(
|
||||
'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input',
|
||||
'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr');
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the tag is void (with no contents allowed and no legal end
|
||||
* tag), for example 'br'.
|
||||
* @param {string} tagName The tag name in lower case.
|
||||
* @return {boolean}
|
||||
*/
|
||||
goog.dom.tags.isVoidTag = function(tagName) {
|
||||
return goog.dom.tags.VOID_TAGS_[tagName] === true;
|
||||
};
|
402
assets/viz/2/goog/events/browserevent.js
Normal file
402
assets/viz/2/goog/events/browserevent.js
Normal file
@ -0,0 +1,402 @@
|
||||
// Copyright 2005 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A patched, standardized event object for browser events.
|
||||
*
|
||||
* <pre>
|
||||
* The patched event object contains the following members:
|
||||
* - type {string} Event type, e.g. 'click'
|
||||
* - target {Object} The element that actually triggered the event
|
||||
* - currentTarget {Object} The element the listener is attached to
|
||||
* - relatedTarget {Object} For mouseover and mouseout, the previous object
|
||||
* - offsetX {number} X-coordinate relative to target
|
||||
* - offsetY {number} Y-coordinate relative to target
|
||||
* - clientX {number} X-coordinate relative to viewport
|
||||
* - clientY {number} Y-coordinate relative to viewport
|
||||
* - screenX {number} X-coordinate relative to the edge of the screen
|
||||
* - screenY {number} Y-coordinate relative to the edge of the screen
|
||||
* - button {number} Mouse button. Use isButton() to test.
|
||||
* - keyCode {number} Key-code
|
||||
* - ctrlKey {boolean} Was ctrl key depressed
|
||||
* - altKey {boolean} Was alt key depressed
|
||||
* - shiftKey {boolean} Was shift key depressed
|
||||
* - metaKey {boolean} Was meta key depressed
|
||||
* - defaultPrevented {boolean} Whether the default action has been prevented
|
||||
* - state {Object} History state object
|
||||
*
|
||||
* NOTE: The keyCode member contains the raw browser keyCode. For normalized
|
||||
* key and character code use {@link goog.events.KeyHandler}.
|
||||
* </pre>
|
||||
*
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*/
|
||||
|
||||
goog.provide('goog.events.BrowserEvent');
|
||||
goog.provide('goog.events.BrowserEvent.MouseButton');
|
||||
|
||||
goog.require('goog.events.BrowserFeature');
|
||||
goog.require('goog.events.Event');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.reflect');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Accepts a browser event object and creates a patched, cross browser event
|
||||
* object.
|
||||
* The content of this object will not be initialized if no event object is
|
||||
* provided. If this is the case, init() needs to be invoked separately.
|
||||
* @param {Event=} opt_e Browser event object.
|
||||
* @param {EventTarget=} opt_currentTarget Current target for event.
|
||||
* @constructor
|
||||
* @extends {goog.events.Event}
|
||||
*/
|
||||
goog.events.BrowserEvent = function(opt_e, opt_currentTarget) {
|
||||
goog.events.BrowserEvent.base(this, 'constructor', opt_e ? opt_e.type : '');
|
||||
|
||||
/**
|
||||
* Target that fired the event.
|
||||
* @override
|
||||
* @type {Node}
|
||||
*/
|
||||
this.target = null;
|
||||
|
||||
/**
|
||||
* Node that had the listener attached.
|
||||
* @override
|
||||
* @type {Node|undefined}
|
||||
*/
|
||||
this.currentTarget = null;
|
||||
|
||||
/**
|
||||
* For mouseover and mouseout events, the related object for the event.
|
||||
* @type {Node}
|
||||
*/
|
||||
this.relatedTarget = null;
|
||||
|
||||
/**
|
||||
* X-coordinate relative to target.
|
||||
* @type {number}
|
||||
*/
|
||||
this.offsetX = 0;
|
||||
|
||||
/**
|
||||
* Y-coordinate relative to target.
|
||||
* @type {number}
|
||||
*/
|
||||
this.offsetY = 0;
|
||||
|
||||
/**
|
||||
* X-coordinate relative to the window.
|
||||
* @type {number}
|
||||
*/
|
||||
this.clientX = 0;
|
||||
|
||||
/**
|
||||
* Y-coordinate relative to the window.
|
||||
* @type {number}
|
||||
*/
|
||||
this.clientY = 0;
|
||||
|
||||
/**
|
||||
* X-coordinate relative to the monitor.
|
||||
* @type {number}
|
||||
*/
|
||||
this.screenX = 0;
|
||||
|
||||
/**
|
||||
* Y-coordinate relative to the monitor.
|
||||
* @type {number}
|
||||
*/
|
||||
this.screenY = 0;
|
||||
|
||||
/**
|
||||
* Which mouse button was pressed.
|
||||
* @type {number}
|
||||
*/
|
||||
this.button = 0;
|
||||
|
||||
/**
|
||||
* Keycode of key press.
|
||||
* @type {number}
|
||||
*/
|
||||
this.keyCode = 0;
|
||||
|
||||
/**
|
||||
* Keycode of key press.
|
||||
* @type {number}
|
||||
*/
|
||||
this.charCode = 0;
|
||||
|
||||
/**
|
||||
* Whether control was pressed at time of event.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.ctrlKey = false;
|
||||
|
||||
/**
|
||||
* Whether alt was pressed at time of event.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.altKey = false;
|
||||
|
||||
/**
|
||||
* Whether shift was pressed at time of event.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.shiftKey = false;
|
||||
|
||||
/**
|
||||
* Whether the meta key was pressed at time of event.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.metaKey = false;
|
||||
|
||||
/**
|
||||
* History state object, only set for PopState events where it's a copy of the
|
||||
* state object provided to pushState or replaceState.
|
||||
* @type {Object}
|
||||
*/
|
||||
this.state = null;
|
||||
|
||||
/**
|
||||
* Whether the default platform modifier key was pressed at time of event.
|
||||
* (This is control for all platforms except Mac, where it's Meta.)
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.platformModifierKey = false;
|
||||
|
||||
/**
|
||||
* The browser event object.
|
||||
* @private {Event}
|
||||
*/
|
||||
this.event_ = null;
|
||||
|
||||
if (opt_e) {
|
||||
this.init(opt_e, opt_currentTarget);
|
||||
}
|
||||
};
|
||||
goog.inherits(goog.events.BrowserEvent, goog.events.Event);
|
||||
|
||||
|
||||
/**
|
||||
* Normalized button constants for the mouse.
|
||||
* @enum {number}
|
||||
*/
|
||||
goog.events.BrowserEvent.MouseButton = {
|
||||
LEFT: 0,
|
||||
MIDDLE: 1,
|
||||
RIGHT: 2
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static data for mapping mouse buttons.
|
||||
* @type {!Array<number>}
|
||||
*/
|
||||
goog.events.BrowserEvent.IEButtonMap = [
|
||||
1, // LEFT
|
||||
4, // MIDDLE
|
||||
2 // RIGHT
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Accepts a browser event object and creates a patched, cross browser event
|
||||
* object.
|
||||
* @param {Event} e Browser event object.
|
||||
* @param {EventTarget=} opt_currentTarget Current target for event.
|
||||
*/
|
||||
goog.events.BrowserEvent.prototype.init = function(e, opt_currentTarget) {
|
||||
var type = this.type = e.type;
|
||||
|
||||
/**
|
||||
* On touch devices use the first "changed touch" as the relevant touch.
|
||||
* @type {Touch}
|
||||
*/
|
||||
var relevantTouch = e.changedTouches ? e.changedTouches[0] : null;
|
||||
|
||||
// TODO(nicksantos): Change this.target to type EventTarget.
|
||||
this.target = /** @type {Node} */ (e.target) || e.srcElement;
|
||||
|
||||
// TODO(nicksantos): Change this.currentTarget to type EventTarget.
|
||||
this.currentTarget = /** @type {Node} */ (opt_currentTarget);
|
||||
|
||||
var relatedTarget = /** @type {Node} */ (e.relatedTarget);
|
||||
if (relatedTarget) {
|
||||
// There's a bug in FireFox where sometimes, relatedTarget will be a
|
||||
// chrome element, and accessing any property of it will get a permission
|
||||
// denied exception. See:
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=497780
|
||||
if (goog.userAgent.GECKO) {
|
||||
if (!goog.reflect.canAccessProperty(relatedTarget, 'nodeName')) {
|
||||
relatedTarget = null;
|
||||
}
|
||||
}
|
||||
// TODO(arv): Use goog.events.EventType when it has been refactored into its
|
||||
// own file.
|
||||
} else if (type == goog.events.EventType.MOUSEOVER) {
|
||||
relatedTarget = e.fromElement;
|
||||
} else if (type == goog.events.EventType.MOUSEOUT) {
|
||||
relatedTarget = e.toElement;
|
||||
}
|
||||
|
||||
this.relatedTarget = relatedTarget;
|
||||
|
||||
if (!goog.isNull(relevantTouch)) {
|
||||
this.clientX = relevantTouch.clientX !== undefined ? relevantTouch.clientX :
|
||||
relevantTouch.pageX;
|
||||
this.clientY = relevantTouch.clientY !== undefined ? relevantTouch.clientY :
|
||||
relevantTouch.pageY;
|
||||
this.screenX = relevantTouch.screenX || 0;
|
||||
this.screenY = relevantTouch.screenY || 0;
|
||||
} else {
|
||||
// Webkit emits a lame warning whenever layerX/layerY is accessed.
|
||||
// http://code.google.com/p/chromium/issues/detail?id=101733
|
||||
this.offsetX = (goog.userAgent.WEBKIT || e.offsetX !== undefined) ?
|
||||
e.offsetX :
|
||||
e.layerX;
|
||||
this.offsetY = (goog.userAgent.WEBKIT || e.offsetY !== undefined) ?
|
||||
e.offsetY :
|
||||
e.layerY;
|
||||
this.clientX = e.clientX !== undefined ? e.clientX : e.pageX;
|
||||
this.clientY = e.clientY !== undefined ? e.clientY : e.pageY;
|
||||
this.screenX = e.screenX || 0;
|
||||
this.screenY = e.screenY || 0;
|
||||
}
|
||||
|
||||
this.button = e.button;
|
||||
|
||||
this.keyCode = e.keyCode || 0;
|
||||
this.charCode = e.charCode || (type == 'keypress' ? e.keyCode : 0);
|
||||
this.ctrlKey = e.ctrlKey;
|
||||
this.altKey = e.altKey;
|
||||
this.shiftKey = e.shiftKey;
|
||||
this.metaKey = e.metaKey;
|
||||
this.platformModifierKey = goog.userAgent.MAC ? e.metaKey : e.ctrlKey;
|
||||
this.state = e.state;
|
||||
this.event_ = e;
|
||||
if (e.defaultPrevented) {
|
||||
this.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tests to see which button was pressed during the event. This is really only
|
||||
* useful in IE and Gecko browsers. And in IE, it's only useful for
|
||||
* mousedown/mouseup events, because click only fires for the left mouse button.
|
||||
*
|
||||
* Safari 2 only reports the left button being clicked, and uses the value '1'
|
||||
* instead of 0. Opera only reports a mousedown event for the middle button, and
|
||||
* no mouse events for the right button. Opera has default behavior for left and
|
||||
* middle click that can only be overridden via a configuration setting.
|
||||
*
|
||||
* There's a nice table of this mess at http://www.unixpapa.com/js/mouse.html.
|
||||
*
|
||||
* @param {goog.events.BrowserEvent.MouseButton} button The button
|
||||
* to test for.
|
||||
* @return {boolean} True if button was pressed.
|
||||
*/
|
||||
goog.events.BrowserEvent.prototype.isButton = function(button) {
|
||||
if (!goog.events.BrowserFeature.HAS_W3C_BUTTON) {
|
||||
if (this.type == 'click') {
|
||||
return button == goog.events.BrowserEvent.MouseButton.LEFT;
|
||||
} else {
|
||||
return !!(
|
||||
this.event_.button & goog.events.BrowserEvent.IEButtonMap[button]);
|
||||
}
|
||||
} else {
|
||||
return this.event_.button == button;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether this has an "action"-producing mouse button.
|
||||
*
|
||||
* By definition, this includes left-click on windows/linux, and left-click
|
||||
* without the ctrl key on Macs.
|
||||
*
|
||||
* @return {boolean} The result.
|
||||
*/
|
||||
goog.events.BrowserEvent.prototype.isMouseActionButton = function() {
|
||||
// Webkit does not ctrl+click to be a right-click, so we
|
||||
// normalize it to behave like Gecko and Opera.
|
||||
return this.isButton(goog.events.BrowserEvent.MouseButton.LEFT) &&
|
||||
!(goog.userAgent.WEBKIT && goog.userAgent.MAC && this.ctrlKey);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.events.BrowserEvent.prototype.stopPropagation = function() {
|
||||
goog.events.BrowserEvent.superClass_.stopPropagation.call(this);
|
||||
if (this.event_.stopPropagation) {
|
||||
this.event_.stopPropagation();
|
||||
} else {
|
||||
this.event_.cancelBubble = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.events.BrowserEvent.prototype.preventDefault = function() {
|
||||
goog.events.BrowserEvent.superClass_.preventDefault.call(this);
|
||||
var be = this.event_;
|
||||
if (!be.preventDefault) {
|
||||
be.returnValue = false;
|
||||
if (goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT) {
|
||||
/** @preserveTry */
|
||||
try {
|
||||
// Most keys can be prevented using returnValue. Some special keys
|
||||
// require setting the keyCode to -1 as well:
|
||||
//
|
||||
// In IE7:
|
||||
// F3, F5, F10, F11, Ctrl+P, Crtl+O, Ctrl+F (these are taken from IE6)
|
||||
//
|
||||
// In IE8:
|
||||
// Ctrl+P, Crtl+O, Ctrl+F (F1-F12 cannot be stopped through the event)
|
||||
//
|
||||
// We therefore do this for all function keys as well as when Ctrl key
|
||||
// is pressed.
|
||||
var VK_F1 = 112;
|
||||
var VK_F12 = 123;
|
||||
if (be.ctrlKey || be.keyCode >= VK_F1 && be.keyCode <= VK_F12) {
|
||||
be.keyCode = -1;
|
||||
}
|
||||
} catch (ex) {
|
||||
// IE throws an 'access denied' exception when trying to change
|
||||
// keyCode in some situations (e.g. srcElement is input[type=file],
|
||||
// or srcElement is an anchor tag rewritten by parent's innerHTML).
|
||||
// Do nothing in this case.
|
||||
}
|
||||
}
|
||||
} else {
|
||||
be.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Event} The underlying browser event object.
|
||||
*/
|
||||
goog.events.BrowserEvent.prototype.getBrowserEvent = function() {
|
||||
return this.event_;
|
||||
};
|
84
assets/viz/2/goog/events/browserfeature.js
Normal file
84
assets/viz/2/goog/events/browserfeature.js
Normal file
@ -0,0 +1,84 @@
|
||||
// Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Browser capability checks for the events package.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.events.BrowserFeature');
|
||||
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
* Enum of browser capabilities.
|
||||
* @enum {boolean}
|
||||
*/
|
||||
goog.events.BrowserFeature = {
|
||||
/**
|
||||
* Whether the button attribute of the event is W3C compliant. False in
|
||||
* Internet Explorer prior to version 9; document-version dependent.
|
||||
*/
|
||||
HAS_W3C_BUTTON:
|
||||
!goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9),
|
||||
|
||||
/**
|
||||
* Whether the browser supports full W3C event model.
|
||||
*/
|
||||
HAS_W3C_EVENT_SUPPORT:
|
||||
!goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9),
|
||||
|
||||
/**
|
||||
* To prevent default in IE7-8 for certain keydown events we need set the
|
||||
* keyCode to -1.
|
||||
*/
|
||||
SET_KEY_CODE_TO_PREVENT_DEFAULT:
|
||||
goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9'),
|
||||
|
||||
/**
|
||||
* Whether the {@code navigator.onLine} property is supported.
|
||||
*/
|
||||
HAS_NAVIGATOR_ONLINE_PROPERTY:
|
||||
!goog.userAgent.WEBKIT || goog.userAgent.isVersionOrHigher('528'),
|
||||
|
||||
/**
|
||||
* Whether HTML5 network online/offline events are supported.
|
||||
*/
|
||||
HAS_HTML5_NETWORK_EVENT_SUPPORT:
|
||||
goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9b') ||
|
||||
goog.userAgent.IE && goog.userAgent.isVersionOrHigher('8') ||
|
||||
goog.userAgent.OPERA && goog.userAgent.isVersionOrHigher('9.5') ||
|
||||
goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('528'),
|
||||
|
||||
/**
|
||||
* Whether HTML5 network events fire on document.body, or otherwise the
|
||||
* window.
|
||||
*/
|
||||
HTML5_NETWORK_EVENTS_FIRE_ON_BODY:
|
||||
goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('8') ||
|
||||
goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9'),
|
||||
|
||||
/**
|
||||
* Whether touch is enabled in the browser.
|
||||
*/
|
||||
TOUCH_ENABLED:
|
||||
('ontouchstart' in goog.global ||
|
||||
!!(goog.global['document'] && document.documentElement &&
|
||||
'ontouchstart' in document.documentElement) ||
|
||||
// IE10 uses non-standard touch events, so it has a different check.
|
||||
!!(goog.global['navigator'] &&
|
||||
goog.global['navigator']['msMaxTouchPoints']))
|
||||
};
|
145
assets/viz/2/goog/events/event.js
Normal file
145
assets/viz/2/goog/events/event.js
Normal file
@ -0,0 +1,145 @@
|
||||
// Copyright 2005 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A base class for event objects.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.events.Event');
|
||||
goog.provide('goog.events.EventLike');
|
||||
|
||||
/**
|
||||
* goog.events.Event no longer depends on goog.Disposable. Keep requiring
|
||||
* goog.Disposable here to not break projects which assume this dependency.
|
||||
* @suppress {extraRequire}
|
||||
*/
|
||||
goog.require('goog.Disposable');
|
||||
goog.require('goog.events.EventId');
|
||||
|
||||
|
||||
/**
|
||||
* A typedef for event like objects that are dispatchable via the
|
||||
* goog.events.dispatchEvent function. strings are treated as the type for a
|
||||
* goog.events.Event. Objects are treated as an extension of a new
|
||||
* goog.events.Event with the type property of the object being used as the type
|
||||
* of the Event.
|
||||
* @typedef {string|Object|goog.events.Event|goog.events.EventId}
|
||||
*/
|
||||
goog.events.EventLike;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A base class for event objects, so that they can support preventDefault and
|
||||
* stopPropagation.
|
||||
*
|
||||
* @suppress {underscore} Several properties on this class are technically
|
||||
* public, but referencing these properties outside this package is strongly
|
||||
* discouraged.
|
||||
*
|
||||
* @param {string|!goog.events.EventId} type Event Type.
|
||||
* @param {Object=} opt_target Reference to the object that is the target of
|
||||
* this event. It has to implement the {@code EventTarget} interface
|
||||
* declared at {@link http://developer.mozilla.org/en/DOM/EventTarget}.
|
||||
* @constructor
|
||||
*/
|
||||
goog.events.Event = function(type, opt_target) {
|
||||
/**
|
||||
* Event type.
|
||||
* @type {string}
|
||||
*/
|
||||
this.type = type instanceof goog.events.EventId ? String(type) : type;
|
||||
|
||||
/**
|
||||
* TODO(tbreisacher): The type should probably be
|
||||
* EventTarget|goog.events.EventTarget.
|
||||
*
|
||||
* Target of the event.
|
||||
* @type {Object|undefined}
|
||||
*/
|
||||
this.target = opt_target;
|
||||
|
||||
/**
|
||||
* Object that had the listener attached.
|
||||
* @type {Object|undefined}
|
||||
*/
|
||||
this.currentTarget = this.target;
|
||||
|
||||
/**
|
||||
* Whether to cancel the event in internal capture/bubble processing for IE.
|
||||
* @type {boolean}
|
||||
* @public
|
||||
*/
|
||||
this.propagationStopped_ = false;
|
||||
|
||||
/**
|
||||
* Whether the default action has been prevented.
|
||||
* This is a property to match the W3C specification at
|
||||
* {@link http://www.w3.org/TR/DOM-Level-3-Events/
|
||||
* #events-event-type-defaultPrevented}.
|
||||
* Must be treated as read-only outside the class.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.defaultPrevented = false;
|
||||
|
||||
/**
|
||||
* Return value for in internal capture/bubble processing for IE.
|
||||
* @type {boolean}
|
||||
* @public
|
||||
* @suppress {underscore|visibility} Technically public, but referencing this
|
||||
* outside this package is strongly discouraged.
|
||||
*/
|
||||
this.returnValue_ = true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stops event propagation.
|
||||
*/
|
||||
goog.events.Event.prototype.stopPropagation = function() {
|
||||
this.propagationStopped_ = true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Prevents the default action, for example a link redirecting to a url.
|
||||
*/
|
||||
goog.events.Event.prototype.preventDefault = function() {
|
||||
this.defaultPrevented = true;
|
||||
this.returnValue_ = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stops the propagation of the event. It is equivalent to
|
||||
* {@code e.stopPropagation()}, but can be used as the callback argument of
|
||||
* {@link goog.events.listen} without declaring another function.
|
||||
* @param {!goog.events.Event} e An event.
|
||||
*/
|
||||
goog.events.Event.stopPropagation = function(e) {
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Prevents the default action. It is equivalent to
|
||||
* {@code e.preventDefault()}, but can be used as the callback argument of
|
||||
* {@link goog.events.listen} without declaring another function.
|
||||
* @param {!goog.events.Event} e An event.
|
||||
*/
|
||||
goog.events.Event.preventDefault = function(e) {
|
||||
e.preventDefault();
|
||||
};
|
46
assets/viz/2/goog/events/eventid.js
Normal file
46
assets/viz/2/goog/events/eventid.js
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.events.EventId');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A templated class that is used when registering for events. Typical usage:
|
||||
*
|
||||
* /** @type {goog.events.EventId<MyEventObj>} *\
|
||||
* var myEventId = new goog.events.EventId(
|
||||
* goog.events.getUniqueId(('someEvent'));
|
||||
*
|
||||
* // No need to cast or declare here since the compiler knows the
|
||||
* // correct type of 'evt' (MyEventObj).
|
||||
* something.listen(myEventId, function(evt) {});
|
||||
*
|
||||
* @param {string} eventId
|
||||
* @template T
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
goog.events.EventId = function(eventId) {
|
||||
/** @const */ this.id = eventId;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
goog.events.EventId.prototype.toString = function() {
|
||||
return this.id;
|
||||
};
|
989
assets/viz/2/goog/events/events.js
Normal file
989
assets/viz/2/goog/events/events.js
Normal file
@ -0,0 +1,989 @@
|
||||
// Copyright 2005 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview An event manager for both native browser event
|
||||
* targets and custom JavaScript event targets
|
||||
* ({@code goog.events.Listenable}). This provides an abstraction
|
||||
* over browsers' event systems.
|
||||
*
|
||||
* It also provides a simulation of W3C event model's capture phase in
|
||||
* Internet Explorer (IE 8 and below). Caveat: the simulation does not
|
||||
* interact well with listeners registered directly on the elements
|
||||
* (bypassing goog.events) or even with listeners registered via
|
||||
* goog.events in a separate JS binary. In these cases, we provide
|
||||
* no ordering guarantees.
|
||||
*
|
||||
* The listeners will receive a "patched" event object. Such event object
|
||||
* contains normalized values for certain event properties that differs in
|
||||
* different browsers.
|
||||
*
|
||||
* Example usage:
|
||||
* <pre>
|
||||
* goog.events.listen(myNode, 'click', function(e) { alert('woo') });
|
||||
* goog.events.listen(myNode, 'mouseover', mouseHandler, true);
|
||||
* goog.events.unlisten(myNode, 'mouseover', mouseHandler, true);
|
||||
* goog.events.removeAll(myNode);
|
||||
* </pre>
|
||||
*
|
||||
* in IE and event object patching]
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*
|
||||
* @see ../demos/events.html
|
||||
* @see ../demos/event-propagation.html
|
||||
* @see ../demos/stopevent.html
|
||||
*/
|
||||
|
||||
// IMPLEMENTATION NOTES:
|
||||
// goog.events stores an auxiliary data structure on each EventTarget
|
||||
// source being listened on. This allows us to take advantage of GC,
|
||||
// having the data structure GC'd when the EventTarget is GC'd. This
|
||||
// GC behavior is equivalent to using W3C DOM Events directly.
|
||||
|
||||
goog.provide('goog.events');
|
||||
goog.provide('goog.events.CaptureSimulationMode');
|
||||
goog.provide('goog.events.Key');
|
||||
goog.provide('goog.events.ListenableType');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.debug.entryPointRegistry');
|
||||
goog.require('goog.events.BrowserEvent');
|
||||
goog.require('goog.events.BrowserFeature');
|
||||
goog.require('goog.events.Listenable');
|
||||
goog.require('goog.events.ListenerMap');
|
||||
|
||||
goog.forwardDeclare('goog.debug.ErrorHandler');
|
||||
goog.forwardDeclare('goog.events.EventWrapper');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {number|goog.events.ListenableKey}
|
||||
*/
|
||||
goog.events.Key;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {EventTarget|goog.events.Listenable}
|
||||
*/
|
||||
goog.events.ListenableType;
|
||||
|
||||
|
||||
/**
|
||||
* Property name on a native event target for the listener map
|
||||
* associated with the event target.
|
||||
* @private @const {string}
|
||||
*/
|
||||
goog.events.LISTENER_MAP_PROP_ = 'closure_lm_' + ((Math.random() * 1e6) | 0);
|
||||
|
||||
|
||||
/**
|
||||
* String used to prepend to IE event types.
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
goog.events.onString_ = 'on';
|
||||
|
||||
|
||||
/**
|
||||
* Map of computed "on<eventname>" strings for IE event types. Caching
|
||||
* this removes an extra object allocation in goog.events.listen which
|
||||
* improves IE6 performance.
|
||||
* @const
|
||||
* @dict
|
||||
* @private
|
||||
*/
|
||||
goog.events.onStringMap_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {number} Different capture simulation mode for IE8-.
|
||||
*/
|
||||
goog.events.CaptureSimulationMode = {
|
||||
/**
|
||||
* Does not perform capture simulation. Will asserts in IE8- when you
|
||||
* add capture listeners.
|
||||
*/
|
||||
OFF_AND_FAIL: 0,
|
||||
|
||||
/**
|
||||
* Does not perform capture simulation, silently ignore capture
|
||||
* listeners.
|
||||
*/
|
||||
OFF_AND_SILENT: 1,
|
||||
|
||||
/**
|
||||
* Performs capture simulation.
|
||||
*/
|
||||
ON: 2
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @define {number} The capture simulation mode for IE8-. By default,
|
||||
* this is ON.
|
||||
*/
|
||||
goog.define('goog.events.CAPTURE_SIMULATION_MODE', 2);
|
||||
|
||||
|
||||
/**
|
||||
* Estimated count of total native listeners.
|
||||
* @private {number}
|
||||
*/
|
||||
goog.events.listenerCountEstimate_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Adds an event listener for a specific event on a native event
|
||||
* target (such as a DOM element) or an object that has implemented
|
||||
* {@link goog.events.Listenable}. A listener can only be added once
|
||||
* to an object and if it is added again the key for the listener is
|
||||
* returned. Note that if the existing listener is a one-off listener
|
||||
* (registered via listenOnce), it will no longer be a one-off
|
||||
* listener after a call to listen().
|
||||
*
|
||||
* @param {EventTarget|goog.events.Listenable} src The node to listen
|
||||
* to events on.
|
||||
* @param {string|Array<string>|
|
||||
* !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}
|
||||
* type Event type or array of event types.
|
||||
* @param {function(this:T, EVENTOBJ):?|{handleEvent:function(?):?}|null}
|
||||
* listener Callback method, or an object with a handleEvent function.
|
||||
* WARNING: passing an Object is now softly deprecated.
|
||||
* @param {boolean=} opt_capt Whether to fire in capture phase (defaults to
|
||||
* false).
|
||||
* @param {T=} opt_handler Element in whose scope to call the listener.
|
||||
* @return {goog.events.Key} Unique key for the listener.
|
||||
* @template T,EVENTOBJ
|
||||
*/
|
||||
goog.events.listen = function(src, type, listener, opt_capt, opt_handler) {
|
||||
if (goog.isArray(type)) {
|
||||
for (var i = 0; i < type.length; i++) {
|
||||
goog.events.listen(src, type[i], listener, opt_capt, opt_handler);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
listener = goog.events.wrapListener(listener);
|
||||
if (goog.events.Listenable.isImplementedBy(src)) {
|
||||
return src.listen(
|
||||
/** @type {string|!goog.events.EventId} */ (type), listener, opt_capt,
|
||||
opt_handler);
|
||||
} else {
|
||||
return goog.events.listen_(
|
||||
/** @type {!EventTarget} */ (src),
|
||||
/** @type {string|!goog.events.EventId} */ (type), listener,
|
||||
/* callOnce */ false, opt_capt, opt_handler);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds an event listener for a specific event on a native event
|
||||
* target. A listener can only be added once to an object and if it
|
||||
* is added again the key for the listener is returned.
|
||||
*
|
||||
* Note that a one-off listener will not change an existing listener,
|
||||
* if any. On the other hand a normal listener will change existing
|
||||
* one-off listener to become a normal listener.
|
||||
*
|
||||
* @param {EventTarget} src The node to listen to events on.
|
||||
* @param {string|!goog.events.EventId} type Event type.
|
||||
* @param {!Function} listener Callback function.
|
||||
* @param {boolean} callOnce Whether the listener is a one-off
|
||||
* listener or otherwise.
|
||||
* @param {boolean=} opt_capt Whether to fire in capture phase (defaults to
|
||||
* false).
|
||||
* @param {Object=} opt_handler Element in whose scope to call the listener.
|
||||
* @return {goog.events.ListenableKey} Unique key for the listener.
|
||||
* @private
|
||||
*/
|
||||
goog.events.listen_ = function(
|
||||
src, type, listener, callOnce, opt_capt, opt_handler) {
|
||||
if (!type) {
|
||||
throw Error('Invalid event type');
|
||||
}
|
||||
|
||||
var capture = !!opt_capt;
|
||||
if (capture && !goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) {
|
||||
if (goog.events.CAPTURE_SIMULATION_MODE ==
|
||||
goog.events.CaptureSimulationMode.OFF_AND_FAIL) {
|
||||
goog.asserts.fail('Can not register capture listener in IE8-.');
|
||||
return null;
|
||||
} else if (
|
||||
goog.events.CAPTURE_SIMULATION_MODE ==
|
||||
goog.events.CaptureSimulationMode.OFF_AND_SILENT) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
var listenerMap = goog.events.getListenerMap_(src);
|
||||
if (!listenerMap) {
|
||||
src[goog.events.LISTENER_MAP_PROP_] = listenerMap =
|
||||
new goog.events.ListenerMap(src);
|
||||
}
|
||||
|
||||
var listenerObj =
|
||||
listenerMap.add(type, listener, callOnce, opt_capt, opt_handler);
|
||||
|
||||
// If the listenerObj already has a proxy, it has been set up
|
||||
// previously. We simply return.
|
||||
if (listenerObj.proxy) {
|
||||
return listenerObj;
|
||||
}
|
||||
|
||||
var proxy = goog.events.getProxy();
|
||||
listenerObj.proxy = proxy;
|
||||
|
||||
proxy.src = src;
|
||||
proxy.listener = listenerObj;
|
||||
|
||||
// Attach the proxy through the browser's API
|
||||
if (src.addEventListener) {
|
||||
src.addEventListener(type.toString(), proxy, capture);
|
||||
} else if (src.attachEvent) {
|
||||
// The else if above used to be an unconditional else. It would call
|
||||
// exception on IE11, spoiling the day of some callers. The previous
|
||||
// incarnation of this code, from 2007, indicates that it replaced an
|
||||
// earlier still version that caused excess allocations on IE6.
|
||||
src.attachEvent(goog.events.getOnString_(type.toString()), proxy);
|
||||
} else {
|
||||
throw Error('addEventListener and attachEvent are unavailable.');
|
||||
}
|
||||
|
||||
goog.events.listenerCountEstimate_++;
|
||||
return listenerObj;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper function for returning a proxy function.
|
||||
* @return {!Function} A new or reused function object.
|
||||
*/
|
||||
goog.events.getProxy = function() {
|
||||
var proxyCallbackFunction = goog.events.handleBrowserEvent_;
|
||||
// Use a local var f to prevent one allocation.
|
||||
var f =
|
||||
goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT ? function(eventObject) {
|
||||
return proxyCallbackFunction.call(f.src, f.listener, eventObject);
|
||||
} : function(eventObject) {
|
||||
var v = proxyCallbackFunction.call(f.src, f.listener, eventObject);
|
||||
// NOTE(chrishenry): In IE, we hack in a capture phase. However, if
|
||||
// there is inline event handler which tries to prevent default (for
|
||||
// example <a href="..." onclick="return false">...</a>) in a
|
||||
// descendant element, the prevent default will be overridden
|
||||
// by this listener if this listener were to return true. Hence, we
|
||||
// return undefined.
|
||||
if (!v) return v;
|
||||
};
|
||||
return f;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds an event listener for a specific event on a native event
|
||||
* target (such as a DOM element) or an object that has implemented
|
||||
* {@link goog.events.Listenable}. After the event has fired the event
|
||||
* listener is removed from the target.
|
||||
*
|
||||
* If an existing listener already exists, listenOnce will do
|
||||
* nothing. In particular, if the listener was previously registered
|
||||
* via listen(), listenOnce() will not turn the listener into a
|
||||
* one-off listener. Similarly, if there is already an existing
|
||||
* one-off listener, listenOnce does not modify the listeners (it is
|
||||
* still a once listener).
|
||||
*
|
||||
* @param {EventTarget|goog.events.Listenable} src The node to listen
|
||||
* to events on.
|
||||
* @param {string|Array<string>|
|
||||
* !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}
|
||||
* type Event type or array of event types.
|
||||
* @param {function(this:T, EVENTOBJ):?|{handleEvent:function(?):?}|null}
|
||||
* listener Callback method.
|
||||
* @param {boolean=} opt_capt Fire in capture phase?.
|
||||
* @param {T=} opt_handler Element in whose scope to call the listener.
|
||||
* @return {goog.events.Key} Unique key for the listener.
|
||||
* @template T,EVENTOBJ
|
||||
*/
|
||||
goog.events.listenOnce = function(src, type, listener, opt_capt, opt_handler) {
|
||||
if (goog.isArray(type)) {
|
||||
for (var i = 0; i < type.length; i++) {
|
||||
goog.events.listenOnce(src, type[i], listener, opt_capt, opt_handler);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
listener = goog.events.wrapListener(listener);
|
||||
if (goog.events.Listenable.isImplementedBy(src)) {
|
||||
return src.listenOnce(
|
||||
/** @type {string|!goog.events.EventId} */ (type), listener, opt_capt,
|
||||
opt_handler);
|
||||
} else {
|
||||
return goog.events.listen_(
|
||||
/** @type {!EventTarget} */ (src),
|
||||
/** @type {string|!goog.events.EventId} */ (type), listener,
|
||||
/* callOnce */ true, opt_capt, opt_handler);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds an event listener with a specific event wrapper on a DOM Node or an
|
||||
* object that has implemented {@link goog.events.Listenable}. A listener can
|
||||
* only be added once to an object.
|
||||
*
|
||||
* @param {EventTarget|goog.events.Listenable} src The target to
|
||||
* listen to events on.
|
||||
* @param {goog.events.EventWrapper} wrapper Event wrapper to use.
|
||||
* @param {function(this:T, ?):?|{handleEvent:function(?):?}|null} listener
|
||||
* Callback method, or an object with a handleEvent function.
|
||||
* @param {boolean=} opt_capt Whether to fire in capture phase (defaults to
|
||||
* false).
|
||||
* @param {T=} opt_handler Element in whose scope to call the listener.
|
||||
* @template T
|
||||
*/
|
||||
goog.events.listenWithWrapper = function(
|
||||
src, wrapper, listener, opt_capt, opt_handler) {
|
||||
wrapper.listen(src, listener, opt_capt, opt_handler);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes an event listener which was added with listen().
|
||||
*
|
||||
* @param {EventTarget|goog.events.Listenable} src The target to stop
|
||||
* listening to events on.
|
||||
* @param {string|Array<string>|
|
||||
* !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>}
|
||||
* type Event type or array of event types to unlisten to.
|
||||
* @param {function(?):?|{handleEvent:function(?):?}|null} listener The
|
||||
* listener function to remove.
|
||||
* @param {boolean=} opt_capt In DOM-compliant browsers, this determines
|
||||
* whether the listener is fired during the capture or bubble phase of the
|
||||
* event.
|
||||
* @param {Object=} opt_handler Element in whose scope to call the listener.
|
||||
* @return {?boolean} indicating whether the listener was there to remove.
|
||||
* @template EVENTOBJ
|
||||
*/
|
||||
goog.events.unlisten = function(src, type, listener, opt_capt, opt_handler) {
|
||||
if (goog.isArray(type)) {
|
||||
for (var i = 0; i < type.length; i++) {
|
||||
goog.events.unlisten(src, type[i], listener, opt_capt, opt_handler);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
listener = goog.events.wrapListener(listener);
|
||||
if (goog.events.Listenable.isImplementedBy(src)) {
|
||||
return src.unlisten(
|
||||
/** @type {string|!goog.events.EventId} */ (type), listener, opt_capt,
|
||||
opt_handler);
|
||||
}
|
||||
|
||||
if (!src) {
|
||||
// TODO(chrishenry): We should tighten the API to only accept
|
||||
// non-null objects, or add an assertion here.
|
||||
return false;
|
||||
}
|
||||
|
||||
var capture = !!opt_capt;
|
||||
var listenerMap = goog.events.getListenerMap_(
|
||||
/** @type {!EventTarget} */ (src));
|
||||
if (listenerMap) {
|
||||
var listenerObj = listenerMap.getListener(
|
||||
/** @type {string|!goog.events.EventId} */ (type), listener, capture,
|
||||
opt_handler);
|
||||
if (listenerObj) {
|
||||
return goog.events.unlistenByKey(listenerObj);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes an event listener which was added with listen() by the key
|
||||
* returned by listen().
|
||||
*
|
||||
* @param {goog.events.Key} key The key returned by listen() for this
|
||||
* event listener.
|
||||
* @return {boolean} indicating whether the listener was there to remove.
|
||||
*/
|
||||
goog.events.unlistenByKey = function(key) {
|
||||
// TODO(chrishenry): Remove this check when tests that rely on this
|
||||
// are fixed.
|
||||
if (goog.isNumber(key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var listener = key;
|
||||
if (!listener || listener.removed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var src = listener.src;
|
||||
if (goog.events.Listenable.isImplementedBy(src)) {
|
||||
return /** @type {!goog.events.Listenable} */ (src).unlistenByKey(listener);
|
||||
}
|
||||
|
||||
var type = listener.type;
|
||||
var proxy = listener.proxy;
|
||||
if (src.removeEventListener) {
|
||||
src.removeEventListener(type, proxy, listener.capture);
|
||||
} else if (src.detachEvent) {
|
||||
src.detachEvent(goog.events.getOnString_(type), proxy);
|
||||
}
|
||||
goog.events.listenerCountEstimate_--;
|
||||
|
||||
var listenerMap = goog.events.getListenerMap_(
|
||||
/** @type {!EventTarget} */ (src));
|
||||
// TODO(chrishenry): Try to remove this conditional and execute the
|
||||
// first branch always. This should be safe.
|
||||
if (listenerMap) {
|
||||
listenerMap.removeByKey(listener);
|
||||
if (listenerMap.getTypeCount() == 0) {
|
||||
// Null the src, just because this is simple to do (and useful
|
||||
// for IE <= 7).
|
||||
listenerMap.src = null;
|
||||
// We don't use delete here because IE does not allow delete
|
||||
// on a window object.
|
||||
src[goog.events.LISTENER_MAP_PROP_] = null;
|
||||
}
|
||||
} else {
|
||||
listener.markAsRemoved();
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes an event listener which was added with listenWithWrapper().
|
||||
*
|
||||
* @param {EventTarget|goog.events.Listenable} src The target to stop
|
||||
* listening to events on.
|
||||
* @param {goog.events.EventWrapper} wrapper Event wrapper to use.
|
||||
* @param {function(?):?|{handleEvent:function(?):?}|null} listener The
|
||||
* listener function to remove.
|
||||
* @param {boolean=} opt_capt In DOM-compliant browsers, this determines
|
||||
* whether the listener is fired during the capture or bubble phase of the
|
||||
* event.
|
||||
* @param {Object=} opt_handler Element in whose scope to call the listener.
|
||||
*/
|
||||
goog.events.unlistenWithWrapper = function(
|
||||
src, wrapper, listener, opt_capt, opt_handler) {
|
||||
wrapper.unlisten(src, listener, opt_capt, opt_handler);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes all listeners from an object. You can also optionally
|
||||
* remove listeners of a particular type.
|
||||
*
|
||||
* @param {Object|undefined} obj Object to remove listeners from. Must be an
|
||||
* EventTarget or a goog.events.Listenable.
|
||||
* @param {string|!goog.events.EventId=} opt_type Type of event to remove.
|
||||
* Default is all types.
|
||||
* @return {number} Number of listeners removed.
|
||||
*/
|
||||
goog.events.removeAll = function(obj, opt_type) {
|
||||
// TODO(chrishenry): Change the type of obj to
|
||||
// (!EventTarget|!goog.events.Listenable).
|
||||
|
||||
if (!obj) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (goog.events.Listenable.isImplementedBy(obj)) {
|
||||
return /** @type {?} */ (obj).removeAllListeners(opt_type);
|
||||
}
|
||||
|
||||
var listenerMap = goog.events.getListenerMap_(
|
||||
/** @type {!EventTarget} */ (obj));
|
||||
if (!listenerMap) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var count = 0;
|
||||
var typeStr = opt_type && opt_type.toString();
|
||||
for (var type in listenerMap.listeners) {
|
||||
if (!typeStr || type == typeStr) {
|
||||
// Clone so that we don't need to worry about unlistenByKey
|
||||
// changing the content of the ListenerMap.
|
||||
var listeners = listenerMap.listeners[type].concat();
|
||||
for (var i = 0; i < listeners.length; ++i) {
|
||||
if (goog.events.unlistenByKey(listeners[i])) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the listeners for a given object, type and capture phase.
|
||||
*
|
||||
* @param {Object} obj Object to get listeners for.
|
||||
* @param {string|!goog.events.EventId} type Event type.
|
||||
* @param {boolean} capture Capture phase?.
|
||||
* @return {Array<!goog.events.Listener>} Array of listener objects.
|
||||
*/
|
||||
goog.events.getListeners = function(obj, type, capture) {
|
||||
if (goog.events.Listenable.isImplementedBy(obj)) {
|
||||
return /** @type {!goog.events.Listenable} */ (obj).getListeners(
|
||||
type, capture);
|
||||
} else {
|
||||
if (!obj) {
|
||||
// TODO(chrishenry): We should tighten the API to accept
|
||||
// !EventTarget|goog.events.Listenable, and add an assertion here.
|
||||
return [];
|
||||
}
|
||||
|
||||
var listenerMap = goog.events.getListenerMap_(
|
||||
/** @type {!EventTarget} */ (obj));
|
||||
return listenerMap ? listenerMap.getListeners(type, capture) : [];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the goog.events.Listener for the event or null if no such listener is
|
||||
* in use.
|
||||
*
|
||||
* @param {EventTarget|goog.events.Listenable} src The target from
|
||||
* which to get listeners.
|
||||
* @param {?string|!goog.events.EventId<EVENTOBJ>} type The type of the event.
|
||||
* @param {function(EVENTOBJ):?|{handleEvent:function(?):?}|null} listener The
|
||||
* listener function to get.
|
||||
* @param {boolean=} opt_capt In DOM-compliant browsers, this determines
|
||||
* whether the listener is fired during the
|
||||
* capture or bubble phase of the event.
|
||||
* @param {Object=} opt_handler Element in whose scope to call the listener.
|
||||
* @return {goog.events.ListenableKey} the found listener or null if not found.
|
||||
* @template EVENTOBJ
|
||||
*/
|
||||
goog.events.getListener = function(src, type, listener, opt_capt, opt_handler) {
|
||||
// TODO(chrishenry): Change type from ?string to string, or add assertion.
|
||||
type = /** @type {string} */ (type);
|
||||
listener = goog.events.wrapListener(listener);
|
||||
var capture = !!opt_capt;
|
||||
if (goog.events.Listenable.isImplementedBy(src)) {
|
||||
return src.getListener(type, listener, capture, opt_handler);
|
||||
}
|
||||
|
||||
if (!src) {
|
||||
// TODO(chrishenry): We should tighten the API to only accept
|
||||
// non-null objects, or add an assertion here.
|
||||
return null;
|
||||
}
|
||||
|
||||
var listenerMap = goog.events.getListenerMap_(
|
||||
/** @type {!EventTarget} */ (src));
|
||||
if (listenerMap) {
|
||||
return listenerMap.getListener(type, listener, capture, opt_handler);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether an event target has any active listeners matching the
|
||||
* specified signature. If either the type or capture parameters are
|
||||
* unspecified, the function will match on the remaining criteria.
|
||||
*
|
||||
* @param {EventTarget|goog.events.Listenable} obj Target to get
|
||||
* listeners for.
|
||||
* @param {string|!goog.events.EventId=} opt_type Event type.
|
||||
* @param {boolean=} opt_capture Whether to check for capture or bubble-phase
|
||||
* listeners.
|
||||
* @return {boolean} Whether an event target has one or more listeners matching
|
||||
* the requested type and/or capture phase.
|
||||
*/
|
||||
goog.events.hasListener = function(obj, opt_type, opt_capture) {
|
||||
if (goog.events.Listenable.isImplementedBy(obj)) {
|
||||
return obj.hasListener(opt_type, opt_capture);
|
||||
}
|
||||
|
||||
var listenerMap = goog.events.getListenerMap_(
|
||||
/** @type {!EventTarget} */ (obj));
|
||||
return !!listenerMap && listenerMap.hasListener(opt_type, opt_capture);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Provides a nice string showing the normalized event objects public members
|
||||
* @param {Object} e Event Object.
|
||||
* @return {string} String of the public members of the normalized event object.
|
||||
*/
|
||||
goog.events.expose = function(e) {
|
||||
var str = [];
|
||||
for (var key in e) {
|
||||
if (e[key] && e[key].id) {
|
||||
str.push(key + ' = ' + e[key] + ' (' + e[key].id + ')');
|
||||
} else {
|
||||
str.push(key + ' = ' + e[key]);
|
||||
}
|
||||
}
|
||||
return str.join('\n');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string with on prepended to the specified type. This is used for IE
|
||||
* which expects "on" to be prepended. This function caches the string in order
|
||||
* to avoid extra allocations in steady state.
|
||||
* @param {string} type Event type.
|
||||
* @return {string} The type string with 'on' prepended.
|
||||
* @private
|
||||
*/
|
||||
goog.events.getOnString_ = function(type) {
|
||||
if (type in goog.events.onStringMap_) {
|
||||
return goog.events.onStringMap_[type];
|
||||
}
|
||||
return goog.events.onStringMap_[type] = goog.events.onString_ + type;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fires an object's listeners of a particular type and phase
|
||||
*
|
||||
* @param {Object} obj Object whose listeners to call.
|
||||
* @param {string|!goog.events.EventId} type Event type.
|
||||
* @param {boolean} capture Which event phase.
|
||||
* @param {Object} eventObject Event object to be passed to listener.
|
||||
* @return {boolean} True if all listeners returned true else false.
|
||||
*/
|
||||
goog.events.fireListeners = function(obj, type, capture, eventObject) {
|
||||
if (goog.events.Listenable.isImplementedBy(obj)) {
|
||||
return /** @type {!goog.events.Listenable} */ (obj).fireListeners(
|
||||
type, capture, eventObject);
|
||||
}
|
||||
|
||||
return goog.events.fireListeners_(obj, type, capture, eventObject);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fires an object's listeners of a particular type and phase.
|
||||
* @param {Object} obj Object whose listeners to call.
|
||||
* @param {string|!goog.events.EventId} type Event type.
|
||||
* @param {boolean} capture Which event phase.
|
||||
* @param {Object} eventObject Event object to be passed to listener.
|
||||
* @return {boolean} True if all listeners returned true else false.
|
||||
* @private
|
||||
*/
|
||||
goog.events.fireListeners_ = function(obj, type, capture, eventObject) {
|
||||
/** @type {boolean} */
|
||||
var retval = true;
|
||||
|
||||
var listenerMap = goog.events.getListenerMap_(
|
||||
/** @type {EventTarget} */ (obj));
|
||||
if (listenerMap) {
|
||||
// TODO(chrishenry): Original code avoids array creation when there
|
||||
// is no listener, so we do the same. If this optimization turns
|
||||
// out to be not required, we can replace this with
|
||||
// listenerMap.getListeners(type, capture) instead, which is simpler.
|
||||
var listenerArray = listenerMap.listeners[type.toString()];
|
||||
if (listenerArray) {
|
||||
listenerArray = listenerArray.concat();
|
||||
for (var i = 0; i < listenerArray.length; i++) {
|
||||
var listener = listenerArray[i];
|
||||
// We might not have a listener if the listener was removed.
|
||||
if (listener && listener.capture == capture && !listener.removed) {
|
||||
var result = goog.events.fireListener(listener, eventObject);
|
||||
retval = retval && (result !== false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fires a listener with a set of arguments
|
||||
*
|
||||
* @param {goog.events.Listener} listener The listener object to call.
|
||||
* @param {Object} eventObject The event object to pass to the listener.
|
||||
* @return {boolean} Result of listener.
|
||||
*/
|
||||
goog.events.fireListener = function(listener, eventObject) {
|
||||
var listenerFn = listener.listener;
|
||||
var listenerHandler = listener.handler || listener.src;
|
||||
|
||||
if (listener.callOnce) {
|
||||
goog.events.unlistenByKey(listener);
|
||||
}
|
||||
return listenerFn.call(listenerHandler, eventObject);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the total number of listeners currently in the system.
|
||||
* @return {number} Number of listeners.
|
||||
* @deprecated This returns estimated count, now that Closure no longer
|
||||
* stores a central listener registry. We still return an estimation
|
||||
* to keep existing listener-related tests passing. In the near future,
|
||||
* this function will be removed.
|
||||
*/
|
||||
goog.events.getTotalListenerCount = function() {
|
||||
return goog.events.listenerCountEstimate_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Dispatches an event (or event like object) and calls all listeners
|
||||
* listening for events of this type. The type of the event is decided by the
|
||||
* type property on the event object.
|
||||
*
|
||||
* If any of the listeners returns false OR calls preventDefault then this
|
||||
* function will return false. If one of the capture listeners calls
|
||||
* stopPropagation, then the bubble listeners won't fire.
|
||||
*
|
||||
* @param {goog.events.Listenable} src The event target.
|
||||
* @param {goog.events.EventLike} e Event object.
|
||||
* @return {boolean} If anyone called preventDefault on the event object (or
|
||||
* if any of the handlers returns false) this will also return false.
|
||||
* If there are no handlers, or if all handlers return true, this returns
|
||||
* true.
|
||||
*/
|
||||
goog.events.dispatchEvent = function(src, e) {
|
||||
goog.asserts.assert(
|
||||
goog.events.Listenable.isImplementedBy(src),
|
||||
'Can not use goog.events.dispatchEvent with ' +
|
||||
'non-goog.events.Listenable instance.');
|
||||
return src.dispatchEvent(e);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Installs exception protection for the browser event entry point using the
|
||||
* given error handler.
|
||||
*
|
||||
* @param {goog.debug.ErrorHandler} errorHandler Error handler with which to
|
||||
* protect the entry point.
|
||||
*/
|
||||
goog.events.protectBrowserEventEntryPoint = function(errorHandler) {
|
||||
goog.events.handleBrowserEvent_ =
|
||||
errorHandler.protectEntryPoint(goog.events.handleBrowserEvent_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handles an event and dispatches it to the correct listeners. This
|
||||
* function is a proxy for the real listener the user specified.
|
||||
*
|
||||
* @param {goog.events.Listener} listener The listener object.
|
||||
* @param {Event=} opt_evt Optional event object that gets passed in via the
|
||||
* native event handlers.
|
||||
* @return {boolean} Result of the event handler.
|
||||
* @this {EventTarget} The object or Element that fired the event.
|
||||
* @private
|
||||
*/
|
||||
goog.events.handleBrowserEvent_ = function(listener, opt_evt) {
|
||||
if (listener.removed) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Synthesize event propagation if the browser does not support W3C
|
||||
// event model.
|
||||
if (!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) {
|
||||
var ieEvent = opt_evt ||
|
||||
/** @type {Event} */ (goog.getObjectByName('window.event'));
|
||||
var evt = new goog.events.BrowserEvent(ieEvent, this);
|
||||
/** @type {boolean} */
|
||||
var retval = true;
|
||||
|
||||
if (goog.events.CAPTURE_SIMULATION_MODE ==
|
||||
goog.events.CaptureSimulationMode.ON) {
|
||||
// If we have not marked this event yet, we should perform capture
|
||||
// simulation.
|
||||
if (!goog.events.isMarkedIeEvent_(ieEvent)) {
|
||||
goog.events.markIeEvent_(ieEvent);
|
||||
|
||||
var ancestors = [];
|
||||
for (var parent = evt.currentTarget; parent;
|
||||
parent = parent.parentNode) {
|
||||
ancestors.push(parent);
|
||||
}
|
||||
|
||||
// Fire capture listeners.
|
||||
var type = listener.type;
|
||||
for (var i = ancestors.length - 1; !evt.propagationStopped_ && i >= 0;
|
||||
i--) {
|
||||
evt.currentTarget = ancestors[i];
|
||||
var result =
|
||||
goog.events.fireListeners_(ancestors[i], type, true, evt);
|
||||
retval = retval && result;
|
||||
}
|
||||
|
||||
// Fire bubble listeners.
|
||||
//
|
||||
// We can technically rely on IE to perform bubble event
|
||||
// propagation. However, it turns out that IE fires events in
|
||||
// opposite order of attachEvent registration, which broke
|
||||
// some code and tests that rely on the order. (While W3C DOM
|
||||
// Level 2 Events TR leaves the event ordering unspecified,
|
||||
// modern browsers and W3C DOM Level 3 Events Working Draft
|
||||
// actually specify the order as the registration order.)
|
||||
for (var i = 0; !evt.propagationStopped_ && i < ancestors.length; i++) {
|
||||
evt.currentTarget = ancestors[i];
|
||||
var result =
|
||||
goog.events.fireListeners_(ancestors[i], type, false, evt);
|
||||
retval = retval && result;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
retval = goog.events.fireListener(listener, evt);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Otherwise, simply fire the listener.
|
||||
return goog.events.fireListener(
|
||||
listener, new goog.events.BrowserEvent(opt_evt, this));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This is used to mark the IE event object so we do not do the Closure pass
|
||||
* twice for a bubbling event.
|
||||
* @param {Event} e The IE browser event.
|
||||
* @private
|
||||
*/
|
||||
goog.events.markIeEvent_ = function(e) {
|
||||
// Only the keyCode and the returnValue can be changed. We use keyCode for
|
||||
// non keyboard events.
|
||||
// event.returnValue is a bit more tricky. It is undefined by default. A
|
||||
// boolean false prevents the default action. In a window.onbeforeunload and
|
||||
// the returnValue is non undefined it will be alerted. However, we will only
|
||||
// modify the returnValue for keyboard events. We can get a problem if non
|
||||
// closure events sets the keyCode or the returnValue
|
||||
|
||||
var useReturnValue = false;
|
||||
|
||||
if (e.keyCode == 0) {
|
||||
// We cannot change the keyCode in case that srcElement is input[type=file].
|
||||
// We could test that that is the case but that would allocate 3 objects.
|
||||
// If we use try/catch we will only allocate extra objects in the case of a
|
||||
// failure.
|
||||
/** @preserveTry */
|
||||
try {
|
||||
e.keyCode = -1;
|
||||
return;
|
||||
} catch (ex) {
|
||||
useReturnValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (useReturnValue ||
|
||||
/** @type {boolean|undefined} */ (e.returnValue) == undefined) {
|
||||
e.returnValue = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This is used to check if an IE event has already been handled by the Closure
|
||||
* system so we do not do the Closure pass twice for a bubbling event.
|
||||
* @param {Event} e The IE browser event.
|
||||
* @return {boolean} True if the event object has been marked.
|
||||
* @private
|
||||
*/
|
||||
goog.events.isMarkedIeEvent_ = function(e) {
|
||||
return e.keyCode < 0 || e.returnValue != undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Counter to create unique event ids.
|
||||
* @private {number}
|
||||
*/
|
||||
goog.events.uniqueIdCounter_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a unique event id.
|
||||
*
|
||||
* @param {string} identifier The identifier.
|
||||
* @return {string} A unique identifier.
|
||||
* @idGenerator {unique}
|
||||
*/
|
||||
goog.events.getUniqueId = function(identifier) {
|
||||
return identifier + '_' + goog.events.uniqueIdCounter_++;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {EventTarget} src The source object.
|
||||
* @return {goog.events.ListenerMap} A listener map for the given
|
||||
* source object, or null if none exists.
|
||||
* @private
|
||||
*/
|
||||
goog.events.getListenerMap_ = function(src) {
|
||||
var listenerMap = src[goog.events.LISTENER_MAP_PROP_];
|
||||
// IE serializes the property as well (e.g. when serializing outer
|
||||
// HTML). So we must check that the value is of the correct type.
|
||||
return listenerMap instanceof goog.events.ListenerMap ? listenerMap : null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Expando property for listener function wrapper for Object with
|
||||
* handleEvent.
|
||||
* @private @const {string}
|
||||
*/
|
||||
goog.events.LISTENER_WRAPPER_PROP_ =
|
||||
'__closure_events_fn_' + ((Math.random() * 1e9) >>> 0);
|
||||
|
||||
|
||||
/**
|
||||
* @param {Object|Function} listener The listener function or an
|
||||
* object that contains handleEvent method.
|
||||
* @return {!Function} Either the original function or a function that
|
||||
* calls obj.handleEvent. If the same listener is passed to this
|
||||
* function more than once, the same function is guaranteed to be
|
||||
* returned.
|
||||
*/
|
||||
goog.events.wrapListener = function(listener) {
|
||||
goog.asserts.assert(listener, 'Listener can not be null.');
|
||||
|
||||
if (goog.isFunction(listener)) {
|
||||
return listener;
|
||||
}
|
||||
|
||||
goog.asserts.assert(
|
||||
listener.handleEvent, 'An object listener must have handleEvent method.');
|
||||
if (!listener[goog.events.LISTENER_WRAPPER_PROP_]) {
|
||||
listener[goog.events.LISTENER_WRAPPER_PROP_] = function(e) {
|
||||
return /** @type {?} */ (listener).handleEvent(e);
|
||||
};
|
||||
}
|
||||
return listener[goog.events.LISTENER_WRAPPER_PROP_];
|
||||
};
|
||||
|
||||
|
||||
// Register the browser event handler as an entry point, so that
|
||||
// it can be monitored for exception handling, etc.
|
||||
goog.debug.entryPointRegistry.register(
|
||||
/**
|
||||
* @param {function(!Function): !Function} transformer The transforming
|
||||
* function.
|
||||
*/
|
||||
function(transformer) {
|
||||
goog.events.handleBrowserEvent_ =
|
||||
transformer(goog.events.handleBrowserEvent_);
|
||||
});
|
239
assets/viz/2/goog/events/eventtype.js
Normal file
239
assets/viz/2/goog/events/eventtype.js
Normal file
@ -0,0 +1,239 @@
|
||||
// Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Event Types.
|
||||
*
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.events.EventType');
|
||||
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
* Returns a prefixed event name for the current browser.
|
||||
* @param {string} eventName The name of the event.
|
||||
* @return {string} The prefixed event name.
|
||||
* @suppress {missingRequire|missingProvide}
|
||||
* @private
|
||||
*/
|
||||
goog.events.getVendorPrefixedName_ = function(eventName) {
|
||||
return goog.userAgent.WEBKIT ?
|
||||
'webkit' + eventName :
|
||||
(goog.userAgent.OPERA ? 'o' + eventName.toLowerCase() :
|
||||
eventName.toLowerCase());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Constants for event names.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.events.EventType = {
|
||||
// Mouse events
|
||||
CLICK: 'click',
|
||||
RIGHTCLICK: 'rightclick',
|
||||
DBLCLICK: 'dblclick',
|
||||
MOUSEDOWN: 'mousedown',
|
||||
MOUSEUP: 'mouseup',
|
||||
MOUSEOVER: 'mouseover',
|
||||
MOUSEOUT: 'mouseout',
|
||||
MOUSEMOVE: 'mousemove',
|
||||
MOUSEENTER: 'mouseenter',
|
||||
MOUSELEAVE: 'mouseleave',
|
||||
// Select start is non-standard.
|
||||
// See http://msdn.microsoft.com/en-us/library/ie/ms536969(v=vs.85).aspx.
|
||||
SELECTSTART: 'selectstart', // IE, Safari, Chrome
|
||||
|
||||
// Wheel events
|
||||
// http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
|
||||
WHEEL: 'wheel',
|
||||
|
||||
// Key events
|
||||
KEYPRESS: 'keypress',
|
||||
KEYDOWN: 'keydown',
|
||||
KEYUP: 'keyup',
|
||||
|
||||
// Focus
|
||||
BLUR: 'blur',
|
||||
FOCUS: 'focus',
|
||||
DEACTIVATE: 'deactivate', // IE only
|
||||
// NOTE: The following two events are not stable in cross-browser usage.
|
||||
// WebKit and Opera implement DOMFocusIn/Out.
|
||||
// IE implements focusin/out.
|
||||
// Gecko implements neither see bug at
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=396927.
|
||||
// The DOM Events Level 3 Draft deprecates DOMFocusIn in favor of focusin:
|
||||
// http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html
|
||||
// You can use FOCUS in Capture phase until implementations converge.
|
||||
FOCUSIN: goog.userAgent.IE ? 'focusin' : 'DOMFocusIn',
|
||||
FOCUSOUT: goog.userAgent.IE ? 'focusout' : 'DOMFocusOut',
|
||||
|
||||
// Forms
|
||||
CHANGE: 'change',
|
||||
RESET: 'reset',
|
||||
SELECT: 'select',
|
||||
SUBMIT: 'submit',
|
||||
INPUT: 'input',
|
||||
PROPERTYCHANGE: 'propertychange', // IE only
|
||||
|
||||
// Drag and drop
|
||||
DRAGSTART: 'dragstart',
|
||||
DRAG: 'drag',
|
||||
DRAGENTER: 'dragenter',
|
||||
DRAGOVER: 'dragover',
|
||||
DRAGLEAVE: 'dragleave',
|
||||
DROP: 'drop',
|
||||
DRAGEND: 'dragend',
|
||||
|
||||
// Touch events
|
||||
// Note that other touch events exist, but we should follow the W3C list here.
|
||||
// http://www.w3.org/TR/touch-events/#list-of-touchevent-types
|
||||
TOUCHSTART: 'touchstart',
|
||||
TOUCHMOVE: 'touchmove',
|
||||
TOUCHEND: 'touchend',
|
||||
TOUCHCANCEL: 'touchcancel',
|
||||
|
||||
// Misc
|
||||
BEFOREUNLOAD: 'beforeunload',
|
||||
CONSOLEMESSAGE: 'consolemessage',
|
||||
CONTEXTMENU: 'contextmenu',
|
||||
DOMCONTENTLOADED: 'DOMContentLoaded',
|
||||
ERROR: 'error',
|
||||
HELP: 'help',
|
||||
LOAD: 'load',
|
||||
LOSECAPTURE: 'losecapture',
|
||||
ORIENTATIONCHANGE: 'orientationchange',
|
||||
READYSTATECHANGE: 'readystatechange',
|
||||
RESIZE: 'resize',
|
||||
SCROLL: 'scroll',
|
||||
TIMEUPDATE: 'timeupdate',
|
||||
UNLOAD: 'unload',
|
||||
|
||||
// HTML 5 History events
|
||||
// See http://www.w3.org/TR/html5/browsers.html#event-definitions-0
|
||||
HASHCHANGE: 'hashchange',
|
||||
PAGEHIDE: 'pagehide',
|
||||
PAGESHOW: 'pageshow',
|
||||
POPSTATE: 'popstate',
|
||||
|
||||
// Copy and Paste
|
||||
// Support is limited. Make sure it works on your favorite browser
|
||||
// before using.
|
||||
// http://www.quirksmode.org/dom/events/cutcopypaste.html
|
||||
COPY: 'copy',
|
||||
PASTE: 'paste',
|
||||
CUT: 'cut',
|
||||
BEFORECOPY: 'beforecopy',
|
||||
BEFORECUT: 'beforecut',
|
||||
BEFOREPASTE: 'beforepaste',
|
||||
|
||||
// HTML5 online/offline events.
|
||||
// http://www.w3.org/TR/offline-webapps/#related
|
||||
ONLINE: 'online',
|
||||
OFFLINE: 'offline',
|
||||
|
||||
// HTML 5 worker events
|
||||
MESSAGE: 'message',
|
||||
CONNECT: 'connect',
|
||||
|
||||
// CSS animation events.
|
||||
/** @suppress {missingRequire} */
|
||||
ANIMATIONSTART: goog.events.getVendorPrefixedName_('AnimationStart'),
|
||||
/** @suppress {missingRequire} */
|
||||
ANIMATIONEND: goog.events.getVendorPrefixedName_('AnimationEnd'),
|
||||
/** @suppress {missingRequire} */
|
||||
ANIMATIONITERATION: goog.events.getVendorPrefixedName_('AnimationIteration'),
|
||||
|
||||
// CSS transition events. Based on the browser support described at:
|
||||
// https://developer.mozilla.org/en/css/css_transitions#Browser_compatibility
|
||||
/** @suppress {missingRequire} */
|
||||
TRANSITIONEND: goog.events.getVendorPrefixedName_('TransitionEnd'),
|
||||
|
||||
// W3C Pointer Events
|
||||
// http://www.w3.org/TR/pointerevents/
|
||||
POINTERDOWN: 'pointerdown',
|
||||
POINTERUP: 'pointerup',
|
||||
POINTERCANCEL: 'pointercancel',
|
||||
POINTERMOVE: 'pointermove',
|
||||
POINTEROVER: 'pointerover',
|
||||
POINTEROUT: 'pointerout',
|
||||
POINTERENTER: 'pointerenter',
|
||||
POINTERLEAVE: 'pointerleave',
|
||||
GOTPOINTERCAPTURE: 'gotpointercapture',
|
||||
LOSTPOINTERCAPTURE: 'lostpointercapture',
|
||||
|
||||
// IE specific events.
|
||||
// See http://msdn.microsoft.com/en-us/library/ie/hh772103(v=vs.85).aspx
|
||||
// Note: these events will be supplanted in IE11.
|
||||
MSGESTURECHANGE: 'MSGestureChange',
|
||||
MSGESTUREEND: 'MSGestureEnd',
|
||||
MSGESTUREHOLD: 'MSGestureHold',
|
||||
MSGESTURESTART: 'MSGestureStart',
|
||||
MSGESTURETAP: 'MSGestureTap',
|
||||
MSGOTPOINTERCAPTURE: 'MSGotPointerCapture',
|
||||
MSINERTIASTART: 'MSInertiaStart',
|
||||
MSLOSTPOINTERCAPTURE: 'MSLostPointerCapture',
|
||||
MSPOINTERCANCEL: 'MSPointerCancel',
|
||||
MSPOINTERDOWN: 'MSPointerDown',
|
||||
MSPOINTERENTER: 'MSPointerEnter',
|
||||
MSPOINTERHOVER: 'MSPointerHover',
|
||||
MSPOINTERLEAVE: 'MSPointerLeave',
|
||||
MSPOINTERMOVE: 'MSPointerMove',
|
||||
MSPOINTEROUT: 'MSPointerOut',
|
||||
MSPOINTEROVER: 'MSPointerOver',
|
||||
MSPOINTERUP: 'MSPointerUp',
|
||||
|
||||
// Native IMEs/input tools events.
|
||||
TEXT: 'text',
|
||||
TEXTINPUT: 'textInput',
|
||||
COMPOSITIONSTART: 'compositionstart',
|
||||
COMPOSITIONUPDATE: 'compositionupdate',
|
||||
COMPOSITIONEND: 'compositionend',
|
||||
|
||||
// Webview tag events
|
||||
// See http://developer.chrome.com/dev/apps/webview_tag.html
|
||||
EXIT: 'exit',
|
||||
LOADABORT: 'loadabort',
|
||||
LOADCOMMIT: 'loadcommit',
|
||||
LOADREDIRECT: 'loadredirect',
|
||||
LOADSTART: 'loadstart',
|
||||
LOADSTOP: 'loadstop',
|
||||
RESPONSIVE: 'responsive',
|
||||
SIZECHANGED: 'sizechanged',
|
||||
UNRESPONSIVE: 'unresponsive',
|
||||
|
||||
// HTML5 Page Visibility API. See details at
|
||||
// {@code goog.labs.dom.PageVisibilityMonitor}.
|
||||
VISIBILITYCHANGE: 'visibilitychange',
|
||||
|
||||
// LocalStorage event.
|
||||
STORAGE: 'storage',
|
||||
|
||||
// DOM Level 2 mutation events (deprecated).
|
||||
DOMSUBTREEMODIFIED: 'DOMSubtreeModified',
|
||||
DOMNODEINSERTED: 'DOMNodeInserted',
|
||||
DOMNODEREMOVED: 'DOMNodeRemoved',
|
||||
DOMNODEREMOVEDFROMDOCUMENT: 'DOMNodeRemovedFromDocument',
|
||||
DOMNODEINSERTEDINTODOCUMENT: 'DOMNodeInsertedIntoDocument',
|
||||
DOMATTRMODIFIED: 'DOMAttrModified',
|
||||
DOMCHARACTERDATAMODIFIED: 'DOMCharacterDataModified',
|
||||
|
||||
// Print events.
|
||||
BEFOREPRINT: 'beforeprint',
|
||||
AFTERPRINT: 'afterprint'
|
||||
};
|
338
assets/viz/2/goog/events/listenable.js
Normal file
338
assets/viz/2/goog/events/listenable.js
Normal file
@ -0,0 +1,338 @@
|
||||
// Copyright 2012 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview An interface for a listenable JavaScript object.
|
||||
* @author chrishenry@google.com (Chris Henry)
|
||||
*/
|
||||
|
||||
goog.provide('goog.events.Listenable');
|
||||
goog.provide('goog.events.ListenableKey');
|
||||
|
||||
/** @suppress {extraRequire} */
|
||||
goog.require('goog.events.EventId');
|
||||
|
||||
goog.forwardDeclare('goog.events.EventLike');
|
||||
goog.forwardDeclare('goog.events.EventTarget');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A listenable interface. A listenable is an object with the ability
|
||||
* to dispatch/broadcast events to "event listeners" registered via
|
||||
* listen/listenOnce.
|
||||
*
|
||||
* The interface allows for an event propagation mechanism similar
|
||||
* to one offered by native browser event targets, such as
|
||||
* capture/bubble mechanism, stopping propagation, and preventing
|
||||
* default actions. Capture/bubble mechanism depends on the ancestor
|
||||
* tree constructed via {@code #getParentEventTarget}; this tree
|
||||
* must be directed acyclic graph. The meaning of default action(s)
|
||||
* in preventDefault is specific to a particular use case.
|
||||
*
|
||||
* Implementations that do not support capture/bubble or can not have
|
||||
* a parent listenable can simply not implement any ability to set the
|
||||
* parent listenable (and have {@code #getParentEventTarget} return
|
||||
* null).
|
||||
*
|
||||
* Implementation of this class can be used with or independently from
|
||||
* goog.events.
|
||||
*
|
||||
* Implementation must call {@code #addImplementation(implClass)}.
|
||||
*
|
||||
* @interface
|
||||
* @see goog.events
|
||||
* @see http://www.w3.org/TR/DOM-Level-2-Events/events.html
|
||||
*/
|
||||
goog.events.Listenable = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* An expando property to indicate that an object implements
|
||||
* goog.events.Listenable.
|
||||
*
|
||||
* See addImplementation/isImplementedBy.
|
||||
*
|
||||
* @type {string}
|
||||
* @const
|
||||
*/
|
||||
goog.events.Listenable.IMPLEMENTED_BY_PROP =
|
||||
'closure_listenable_' + ((Math.random() * 1e6) | 0);
|
||||
|
||||
|
||||
/**
|
||||
* Marks a given class (constructor) as an implementation of
|
||||
* Listenable, do that we can query that fact at runtime. The class
|
||||
* must have already implemented the interface.
|
||||
* @param {!Function} cls The class constructor. The corresponding
|
||||
* class must have already implemented the interface.
|
||||
*/
|
||||
goog.events.Listenable.addImplementation = function(cls) {
|
||||
cls.prototype[goog.events.Listenable.IMPLEMENTED_BY_PROP] = true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Object} obj The object to check.
|
||||
* @return {boolean} Whether a given instance implements Listenable. The
|
||||
* class/superclass of the instance must call addImplementation.
|
||||
*/
|
||||
goog.events.Listenable.isImplementedBy = function(obj) {
|
||||
return !!(obj && obj[goog.events.Listenable.IMPLEMENTED_BY_PROP]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds an event listener. A listener can only be added once to an
|
||||
* object and if it is added again the key for the listener is
|
||||
* returned. Note that if the existing listener is a one-off listener
|
||||
* (registered via listenOnce), it will no longer be a one-off
|
||||
* listener after a call to listen().
|
||||
*
|
||||
* @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id.
|
||||
* @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback
|
||||
* method.
|
||||
* @param {boolean=} opt_useCapture Whether to fire in capture phase
|
||||
* (defaults to false).
|
||||
* @param {SCOPE=} opt_listenerScope Object in whose scope to call the
|
||||
* listener.
|
||||
* @return {!goog.events.ListenableKey} Unique key for the listener.
|
||||
* @template SCOPE,EVENTOBJ
|
||||
*/
|
||||
goog.events.Listenable.prototype.listen;
|
||||
|
||||
|
||||
/**
|
||||
* Adds an event listener that is removed automatically after the
|
||||
* listener fired once.
|
||||
*
|
||||
* If an existing listener already exists, listenOnce will do
|
||||
* nothing. In particular, if the listener was previously registered
|
||||
* via listen(), listenOnce() will not turn the listener into a
|
||||
* one-off listener. Similarly, if there is already an existing
|
||||
* one-off listener, listenOnce does not modify the listeners (it is
|
||||
* still a once listener).
|
||||
*
|
||||
* @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id.
|
||||
* @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback
|
||||
* method.
|
||||
* @param {boolean=} opt_useCapture Whether to fire in capture phase
|
||||
* (defaults to false).
|
||||
* @param {SCOPE=} opt_listenerScope Object in whose scope to call the
|
||||
* listener.
|
||||
* @return {!goog.events.ListenableKey} Unique key for the listener.
|
||||
* @template SCOPE,EVENTOBJ
|
||||
*/
|
||||
goog.events.Listenable.prototype.listenOnce;
|
||||
|
||||
|
||||
/**
|
||||
* Removes an event listener which was added with listen() or listenOnce().
|
||||
*
|
||||
* @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id.
|
||||
* @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback
|
||||
* method.
|
||||
* @param {boolean=} opt_useCapture Whether to fire in capture phase
|
||||
* (defaults to false).
|
||||
* @param {SCOPE=} opt_listenerScope Object in whose scope to call
|
||||
* the listener.
|
||||
* @return {boolean} Whether any listener was removed.
|
||||
* @template SCOPE,EVENTOBJ
|
||||
*/
|
||||
goog.events.Listenable.prototype.unlisten;
|
||||
|
||||
|
||||
/**
|
||||
* Removes an event listener which was added with listen() by the key
|
||||
* returned by listen().
|
||||
*
|
||||
* @param {!goog.events.ListenableKey} key The key returned by
|
||||
* listen() or listenOnce().
|
||||
* @return {boolean} Whether any listener was removed.
|
||||
*/
|
||||
goog.events.Listenable.prototype.unlistenByKey;
|
||||
|
||||
|
||||
/**
|
||||
* Dispatches an event (or event like object) and calls all listeners
|
||||
* listening for events of this type. The type of the event is decided by the
|
||||
* type property on the event object.
|
||||
*
|
||||
* If any of the listeners returns false OR calls preventDefault then this
|
||||
* function will return false. If one of the capture listeners calls
|
||||
* stopPropagation, then the bubble listeners won't fire.
|
||||
*
|
||||
* @param {goog.events.EventLike} e Event object.
|
||||
* @return {boolean} If anyone called preventDefault on the event object (or
|
||||
* if any of the listeners returns false) this will also return false.
|
||||
*/
|
||||
goog.events.Listenable.prototype.dispatchEvent;
|
||||
|
||||
|
||||
/**
|
||||
* Removes all listeners from this listenable. If type is specified,
|
||||
* it will only remove listeners of the particular type. otherwise all
|
||||
* registered listeners will be removed.
|
||||
*
|
||||
* @param {string=} opt_type Type of event to remove, default is to
|
||||
* remove all types.
|
||||
* @return {number} Number of listeners removed.
|
||||
*/
|
||||
goog.events.Listenable.prototype.removeAllListeners;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the parent of this event target to use for capture/bubble
|
||||
* mechanism.
|
||||
*
|
||||
* NOTE(chrishenry): The name reflects the original implementation of
|
||||
* custom event target ({@code goog.events.EventTarget}). We decided
|
||||
* that changing the name is not worth it.
|
||||
*
|
||||
* @return {goog.events.Listenable} The parent EventTarget or null if
|
||||
* there is no parent.
|
||||
*/
|
||||
goog.events.Listenable.prototype.getParentEventTarget;
|
||||
|
||||
|
||||
/**
|
||||
* Fires all registered listeners in this listenable for the given
|
||||
* type and capture mode, passing them the given eventObject. This
|
||||
* does not perform actual capture/bubble. Only implementors of the
|
||||
* interface should be using this.
|
||||
*
|
||||
* @param {string|!goog.events.EventId<EVENTOBJ>} type The type of the
|
||||
* listeners to fire.
|
||||
* @param {boolean} capture The capture mode of the listeners to fire.
|
||||
* @param {EVENTOBJ} eventObject The event object to fire.
|
||||
* @return {boolean} Whether all listeners succeeded without
|
||||
* attempting to prevent default behavior. If any listener returns
|
||||
* false or called goog.events.Event#preventDefault, this returns
|
||||
* false.
|
||||
* @template EVENTOBJ
|
||||
*/
|
||||
goog.events.Listenable.prototype.fireListeners;
|
||||
|
||||
|
||||
/**
|
||||
* Gets all listeners in this listenable for the given type and
|
||||
* capture mode.
|
||||
*
|
||||
* @param {string|!goog.events.EventId} type The type of the listeners to fire.
|
||||
* @param {boolean} capture The capture mode of the listeners to fire.
|
||||
* @return {!Array<!goog.events.ListenableKey>} An array of registered
|
||||
* listeners.
|
||||
* @template EVENTOBJ
|
||||
*/
|
||||
goog.events.Listenable.prototype.getListeners;
|
||||
|
||||
|
||||
/**
|
||||
* Gets the goog.events.ListenableKey for the event or null if no such
|
||||
* listener is in use.
|
||||
*
|
||||
* @param {string|!goog.events.EventId<EVENTOBJ>} type The name of the event
|
||||
* without the 'on' prefix.
|
||||
* @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener The
|
||||
* listener function to get.
|
||||
* @param {boolean} capture Whether the listener is a capturing listener.
|
||||
* @param {SCOPE=} opt_listenerScope Object in whose scope to call the
|
||||
* listener.
|
||||
* @return {goog.events.ListenableKey} the found listener or null if not found.
|
||||
* @template SCOPE,EVENTOBJ
|
||||
*/
|
||||
goog.events.Listenable.prototype.getListener;
|
||||
|
||||
|
||||
/**
|
||||
* Whether there is any active listeners matching the specified
|
||||
* signature. If either the type or capture parameters are
|
||||
* unspecified, the function will match on the remaining criteria.
|
||||
*
|
||||
* @param {string|!goog.events.EventId<EVENTOBJ>=} opt_type Event type.
|
||||
* @param {boolean=} opt_capture Whether to check for capture or bubble
|
||||
* listeners.
|
||||
* @return {boolean} Whether there is any active listeners matching
|
||||
* the requested type and/or capture phase.
|
||||
* @template EVENTOBJ
|
||||
*/
|
||||
goog.events.Listenable.prototype.hasListener;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An interface that describes a single registered listener.
|
||||
* @interface
|
||||
*/
|
||||
goog.events.ListenableKey = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Counter used to create a unique key
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.events.ListenableKey.counter_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Reserves a key to be used for ListenableKey#key field.
|
||||
* @return {number} A number to be used to fill ListenableKey#key
|
||||
* field.
|
||||
*/
|
||||
goog.events.ListenableKey.reserveKey = function() {
|
||||
return ++goog.events.ListenableKey.counter_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The source event target.
|
||||
* @type {Object|goog.events.Listenable|goog.events.EventTarget}
|
||||
*/
|
||||
goog.events.ListenableKey.prototype.src;
|
||||
|
||||
|
||||
/**
|
||||
* The event type the listener is listening to.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.events.ListenableKey.prototype.type;
|
||||
|
||||
|
||||
/**
|
||||
* The listener function.
|
||||
* @type {function(?):?|{handleEvent:function(?):?}|null}
|
||||
*/
|
||||
goog.events.ListenableKey.prototype.listener;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the listener works on capture phase.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.events.ListenableKey.prototype.capture;
|
||||
|
||||
|
||||
/**
|
||||
* The 'this' object for the listener function's scope.
|
||||
* @type {Object|undefined}
|
||||
*/
|
||||
goog.events.ListenableKey.prototype.handler;
|
||||
|
||||
|
||||
/**
|
||||
* A globally unique number to identify the key.
|
||||
* @type {number}
|
||||
*/
|
||||
goog.events.ListenableKey.prototype.key;
|
131
assets/viz/2/goog/events/listener.js
Normal file
131
assets/viz/2/goog/events/listener.js
Normal file
@ -0,0 +1,131 @@
|
||||
// Copyright 2005 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Listener object.
|
||||
* @see ../demos/events.html
|
||||
*/
|
||||
|
||||
goog.provide('goog.events.Listener');
|
||||
|
||||
goog.require('goog.events.ListenableKey');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Simple class that stores information about a listener
|
||||
* @param {!Function} listener Callback function.
|
||||
* @param {Function} proxy Wrapper for the listener that patches the event.
|
||||
* @param {EventTarget|goog.events.Listenable} src Source object for
|
||||
* the event.
|
||||
* @param {string} type Event type.
|
||||
* @param {boolean} capture Whether in capture or bubble phase.
|
||||
* @param {Object=} opt_handler Object in whose context to execute the callback.
|
||||
* @implements {goog.events.ListenableKey}
|
||||
* @constructor
|
||||
*/
|
||||
goog.events.Listener = function(
|
||||
listener, proxy, src, type, capture, opt_handler) {
|
||||
if (goog.events.Listener.ENABLE_MONITORING) {
|
||||
this.creationStack = new Error().stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function.
|
||||
* @type {Function}
|
||||
*/
|
||||
this.listener = listener;
|
||||
|
||||
/**
|
||||
* A wrapper over the original listener. This is used solely to
|
||||
* handle native browser events (it is used to simulate the capture
|
||||
* phase and to patch the event object).
|
||||
* @type {Function}
|
||||
*/
|
||||
this.proxy = proxy;
|
||||
|
||||
/**
|
||||
* Object or node that callback is listening to
|
||||
* @type {EventTarget|goog.events.Listenable}
|
||||
*/
|
||||
this.src = src;
|
||||
|
||||
/**
|
||||
* The event type.
|
||||
* @const {string}
|
||||
*/
|
||||
this.type = type;
|
||||
|
||||
/**
|
||||
* Whether the listener is being called in the capture or bubble phase
|
||||
* @const {boolean}
|
||||
*/
|
||||
this.capture = !!capture;
|
||||
|
||||
/**
|
||||
* Optional object whose context to execute the listener in
|
||||
* @type {Object|undefined}
|
||||
*/
|
||||
this.handler = opt_handler;
|
||||
|
||||
/**
|
||||
* The key of the listener.
|
||||
* @const {number}
|
||||
* @override
|
||||
*/
|
||||
this.key = goog.events.ListenableKey.reserveKey();
|
||||
|
||||
/**
|
||||
* Whether to remove the listener after it has been called.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.callOnce = false;
|
||||
|
||||
/**
|
||||
* Whether the listener has been removed.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.removed = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether to enable the monitoring of the
|
||||
* goog.events.Listener instances. Switching on the monitoring is only
|
||||
* recommended for debugging because it has a significant impact on
|
||||
* performance and memory usage. If switched off, the monitoring code
|
||||
* compiles down to 0 bytes.
|
||||
*/
|
||||
goog.define('goog.events.Listener.ENABLE_MONITORING', false);
|
||||
|
||||
|
||||
/**
|
||||
* If monitoring the goog.events.Listener instances is enabled, stores the
|
||||
* creation stack trace of the Disposable instance.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.events.Listener.prototype.creationStack;
|
||||
|
||||
|
||||
/**
|
||||
* Marks this listener as removed. This also remove references held by
|
||||
* this listener object (such as listener and event source).
|
||||
*/
|
||||
goog.events.Listener.prototype.markAsRemoved = function() {
|
||||
this.removed = true;
|
||||
this.listener = null;
|
||||
this.proxy = null;
|
||||
this.src = null;
|
||||
this.handler = null;
|
||||
};
|
306
assets/viz/2/goog/events/listenermap.js
Normal file
306
assets/viz/2/goog/events/listenermap.js
Normal file
@ -0,0 +1,306 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A map of listeners that provides utility functions to
|
||||
* deal with listeners on an event target. Used by
|
||||
* {@code goog.events.EventTarget}.
|
||||
*
|
||||
* WARNING: Do not use this class from outside goog.events package.
|
||||
*
|
||||
* @visibility {//closure/goog/bin/sizetests:__pkg__}
|
||||
* @visibility {//closure/goog/events:__pkg__}
|
||||
* @visibility {//closure/goog/labs/events:__pkg__}
|
||||
*/
|
||||
|
||||
goog.provide('goog.events.ListenerMap');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.events.Listener');
|
||||
goog.require('goog.object');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new listener map.
|
||||
* @param {EventTarget|goog.events.Listenable} src The src object.
|
||||
* @constructor
|
||||
* @final
|
||||
*/
|
||||
goog.events.ListenerMap = function(src) {
|
||||
/** @type {EventTarget|goog.events.Listenable} */
|
||||
this.src = src;
|
||||
|
||||
/**
|
||||
* Maps of event type to an array of listeners.
|
||||
* @type {!Object<string, !Array<!goog.events.Listener>>}
|
||||
*/
|
||||
this.listeners = {};
|
||||
|
||||
/**
|
||||
* The count of types in this map that have registered listeners.
|
||||
* @private {number}
|
||||
*/
|
||||
this.typeCount_ = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The count of event types in this map that actually
|
||||
* have registered listeners.
|
||||
*/
|
||||
goog.events.ListenerMap.prototype.getTypeCount = function() {
|
||||
return this.typeCount_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Total number of registered listeners.
|
||||
*/
|
||||
goog.events.ListenerMap.prototype.getListenerCount = function() {
|
||||
var count = 0;
|
||||
for (var type in this.listeners) {
|
||||
count += this.listeners[type].length;
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds an event listener. A listener can only be added once to an
|
||||
* object and if it is added again the key for the listener is
|
||||
* returned.
|
||||
*
|
||||
* Note that a one-off listener will not change an existing listener,
|
||||
* if any. On the other hand a normal listener will change existing
|
||||
* one-off listener to become a normal listener.
|
||||
*
|
||||
* @param {string|!goog.events.EventId} type The listener event type.
|
||||
* @param {!Function} listener This listener callback method.
|
||||
* @param {boolean} callOnce Whether the listener is a one-off
|
||||
* listener.
|
||||
* @param {boolean=} opt_useCapture The capture mode of the listener.
|
||||
* @param {Object=} opt_listenerScope Object in whose scope to call the
|
||||
* listener.
|
||||
* @return {!goog.events.ListenableKey} Unique key for the listener.
|
||||
*/
|
||||
goog.events.ListenerMap.prototype.add = function(
|
||||
type, listener, callOnce, opt_useCapture, opt_listenerScope) {
|
||||
var typeStr = type.toString();
|
||||
var listenerArray = this.listeners[typeStr];
|
||||
if (!listenerArray) {
|
||||
listenerArray = this.listeners[typeStr] = [];
|
||||
this.typeCount_++;
|
||||
}
|
||||
|
||||
var listenerObj;
|
||||
var index = goog.events.ListenerMap.findListenerIndex_(
|
||||
listenerArray, listener, opt_useCapture, opt_listenerScope);
|
||||
if (index > -1) {
|
||||
listenerObj = listenerArray[index];
|
||||
if (!callOnce) {
|
||||
// Ensure that, if there is an existing callOnce listener, it is no
|
||||
// longer a callOnce listener.
|
||||
listenerObj.callOnce = false;
|
||||
}
|
||||
} else {
|
||||
listenerObj = new goog.events.Listener(
|
||||
listener, null, this.src, typeStr, !!opt_useCapture, opt_listenerScope);
|
||||
listenerObj.callOnce = callOnce;
|
||||
listenerArray.push(listenerObj);
|
||||
}
|
||||
return listenerObj;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes a matching listener.
|
||||
* @param {string|!goog.events.EventId} type The listener event type.
|
||||
* @param {!Function} listener This listener callback method.
|
||||
* @param {boolean=} opt_useCapture The capture mode of the listener.
|
||||
* @param {Object=} opt_listenerScope Object in whose scope to call the
|
||||
* listener.
|
||||
* @return {boolean} Whether any listener was removed.
|
||||
*/
|
||||
goog.events.ListenerMap.prototype.remove = function(
|
||||
type, listener, opt_useCapture, opt_listenerScope) {
|
||||
var typeStr = type.toString();
|
||||
if (!(typeStr in this.listeners)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var listenerArray = this.listeners[typeStr];
|
||||
var index = goog.events.ListenerMap.findListenerIndex_(
|
||||
listenerArray, listener, opt_useCapture, opt_listenerScope);
|
||||
if (index > -1) {
|
||||
var listenerObj = listenerArray[index];
|
||||
listenerObj.markAsRemoved();
|
||||
goog.array.removeAt(listenerArray, index);
|
||||
if (listenerArray.length == 0) {
|
||||
delete this.listeners[typeStr];
|
||||
this.typeCount_--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes the given listener object.
|
||||
* @param {!goog.events.ListenableKey} listener The listener to remove.
|
||||
* @return {boolean} Whether the listener is removed.
|
||||
*/
|
||||
goog.events.ListenerMap.prototype.removeByKey = function(listener) {
|
||||
var type = listener.type;
|
||||
if (!(type in this.listeners)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var removed = goog.array.remove(this.listeners[type], listener);
|
||||
if (removed) {
|
||||
listener.markAsRemoved();
|
||||
if (this.listeners[type].length == 0) {
|
||||
delete this.listeners[type];
|
||||
this.typeCount_--;
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes all listeners from this map. If opt_type is provided, only
|
||||
* listeners that match the given type are removed.
|
||||
* @param {string|!goog.events.EventId=} opt_type Type of event to remove.
|
||||
* @return {number} Number of listeners removed.
|
||||
*/
|
||||
goog.events.ListenerMap.prototype.removeAll = function(opt_type) {
|
||||
var typeStr = opt_type && opt_type.toString();
|
||||
var count = 0;
|
||||
for (var type in this.listeners) {
|
||||
if (!typeStr || type == typeStr) {
|
||||
var listenerArray = this.listeners[type];
|
||||
for (var i = 0; i < listenerArray.length; i++) {
|
||||
++count;
|
||||
listenerArray[i].markAsRemoved();
|
||||
}
|
||||
delete this.listeners[type];
|
||||
this.typeCount_--;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets all listeners that match the given type and capture mode. The
|
||||
* returned array is a copy (but the listener objects are not).
|
||||
* @param {string|!goog.events.EventId} type The type of the listeners
|
||||
* to retrieve.
|
||||
* @param {boolean} capture The capture mode of the listeners to retrieve.
|
||||
* @return {!Array<!goog.events.ListenableKey>} An array of matching
|
||||
* listeners.
|
||||
*/
|
||||
goog.events.ListenerMap.prototype.getListeners = function(type, capture) {
|
||||
var listenerArray = this.listeners[type.toString()];
|
||||
var rv = [];
|
||||
if (listenerArray) {
|
||||
for (var i = 0; i < listenerArray.length; ++i) {
|
||||
var listenerObj = listenerArray[i];
|
||||
if (listenerObj.capture == capture) {
|
||||
rv.push(listenerObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the goog.events.ListenableKey for the event or null if no such
|
||||
* listener is in use.
|
||||
*
|
||||
* @param {string|!goog.events.EventId} type The type of the listener
|
||||
* to retrieve.
|
||||
* @param {!Function} listener The listener function to get.
|
||||
* @param {boolean} capture Whether the listener is a capturing listener.
|
||||
* @param {Object=} opt_listenerScope Object in whose scope to call the
|
||||
* listener.
|
||||
* @return {goog.events.ListenableKey} the found listener or null if not found.
|
||||
*/
|
||||
goog.events.ListenerMap.prototype.getListener = function(
|
||||
type, listener, capture, opt_listenerScope) {
|
||||
var listenerArray = this.listeners[type.toString()];
|
||||
var i = -1;
|
||||
if (listenerArray) {
|
||||
i = goog.events.ListenerMap.findListenerIndex_(
|
||||
listenerArray, listener, capture, opt_listenerScope);
|
||||
}
|
||||
return i > -1 ? listenerArray[i] : null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether there is a matching listener. If either the type or capture
|
||||
* parameters are unspecified, the function will match on the
|
||||
* remaining criteria.
|
||||
*
|
||||
* @param {string|!goog.events.EventId=} opt_type The type of the listener.
|
||||
* @param {boolean=} opt_capture The capture mode of the listener.
|
||||
* @return {boolean} Whether there is an active listener matching
|
||||
* the requested type and/or capture phase.
|
||||
*/
|
||||
goog.events.ListenerMap.prototype.hasListener = function(
|
||||
opt_type, opt_capture) {
|
||||
var hasType = goog.isDef(opt_type);
|
||||
var typeStr = hasType ? opt_type.toString() : '';
|
||||
var hasCapture = goog.isDef(opt_capture);
|
||||
|
||||
return goog.object.some(this.listeners, function(listenerArray, type) {
|
||||
for (var i = 0; i < listenerArray.length; ++i) {
|
||||
if ((!hasType || listenerArray[i].type == typeStr) &&
|
||||
(!hasCapture || listenerArray[i].capture == opt_capture)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Finds the index of a matching goog.events.Listener in the given
|
||||
* listenerArray.
|
||||
* @param {!Array<!goog.events.Listener>} listenerArray Array of listener.
|
||||
* @param {!Function} listener The listener function.
|
||||
* @param {boolean=} opt_useCapture The capture flag for the listener.
|
||||
* @param {Object=} opt_listenerScope The listener scope.
|
||||
* @return {number} The index of the matching listener within the
|
||||
* listenerArray.
|
||||
* @private
|
||||
*/
|
||||
goog.events.ListenerMap.findListenerIndex_ = function(
|
||||
listenerArray, listener, opt_useCapture, opt_listenerScope) {
|
||||
for (var i = 0; i < listenerArray.length; ++i) {
|
||||
var listenerObj = listenerArray[i];
|
||||
if (!listenerObj.removed && listenerObj.listener == listener &&
|
||||
listenerObj.capture == !!opt_useCapture &&
|
||||
listenerObj.handler == opt_listenerScope) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
110
assets/viz/2/goog/fs/url.js
Normal file
110
assets/viz/2/goog/fs/url.js
Normal file
@ -0,0 +1,110 @@
|
||||
// Copyright 2015 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Wrapper for URL and its createObjectUrl and revokeObjectUrl
|
||||
* methods that are part of the HTML5 File API.
|
||||
*/
|
||||
|
||||
goog.provide('goog.fs.url');
|
||||
|
||||
|
||||
/**
|
||||
* Creates a blob URL for a blob object.
|
||||
* Throws an error if the browser does not support Object Urls.
|
||||
*
|
||||
* @param {!Blob} blob The object for which to create the URL.
|
||||
* @return {string} The URL for the object.
|
||||
*/
|
||||
goog.fs.url.createObjectUrl = function(blob) {
|
||||
return goog.fs.url.getUrlObject_().createObjectURL(blob);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Revokes a URL created by {@link goog.fs.url.createObjectUrl}.
|
||||
* Throws an error if the browser does not support Object Urls.
|
||||
*
|
||||
* @param {string} url The URL to revoke.
|
||||
*/
|
||||
goog.fs.url.revokeObjectUrl = function(url) {
|
||||
goog.fs.url.getUrlObject_().revokeObjectURL(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{createObjectURL: (function(!Blob): string),
|
||||
* revokeObjectURL: function(string): void}}
|
||||
*/
|
||||
goog.fs.url.UrlObject_;
|
||||
|
||||
|
||||
/**
|
||||
* Get the object that has the createObjectURL and revokeObjectURL functions for
|
||||
* this browser.
|
||||
*
|
||||
* @return {goog.fs.url.UrlObject_} The object for this browser.
|
||||
* @private
|
||||
*/
|
||||
goog.fs.url.getUrlObject_ = function() {
|
||||
var urlObject = goog.fs.url.findUrlObject_();
|
||||
if (urlObject != null) {
|
||||
return urlObject;
|
||||
} else {
|
||||
throw Error('This browser doesn\'t seem to support blob URLs');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Finds the object that has the createObjectURL and revokeObjectURL functions
|
||||
* for this browser.
|
||||
*
|
||||
* @return {?goog.fs.url.UrlObject_} The object for this browser or null if the
|
||||
* browser does not support Object Urls.
|
||||
* @suppress {unnecessaryCasts} Depending on how the code is compiled, casting
|
||||
* goog.global to UrlObject_ may result in unnecessary cast warning.
|
||||
* However, the cast cannot be removed because with different set of
|
||||
* compiler flags, the cast is indeed necessary. As such, silencing it.
|
||||
* @private
|
||||
*/
|
||||
goog.fs.url.findUrlObject_ = function() {
|
||||
// This is what the spec says to do
|
||||
// http://dev.w3.org/2006/webapi/FileAPI/#dfn-createObjectURL
|
||||
if (goog.isDef(goog.global.URL) &&
|
||||
goog.isDef(goog.global.URL.createObjectURL)) {
|
||||
return /** @type {goog.fs.url.UrlObject_} */ (goog.global.URL);
|
||||
// This is what Chrome does (as of 10.0.648.6 dev)
|
||||
} else if (
|
||||
goog.isDef(goog.global.webkitURL) &&
|
||||
goog.isDef(goog.global.webkitURL.createObjectURL)) {
|
||||
return /** @type {goog.fs.url.UrlObject_} */ (goog.global.webkitURL);
|
||||
// This is what the spec used to say to do
|
||||
} else if (goog.isDef(goog.global.createObjectURL)) {
|
||||
return /** @type {goog.fs.url.UrlObject_} */ (goog.global);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether this browser supports Object Urls. If not, calls to
|
||||
* createObjectUrl and revokeObjectUrl will result in an error.
|
||||
*
|
||||
* @return {boolean} True if this browser supports Object Urls.
|
||||
*/
|
||||
goog.fs.url.browserSupportsObjectUrls = function() {
|
||||
return goog.fs.url.findUrlObject_() != null;
|
||||
};
|
948
assets/viz/2/goog/html/safehtml.js
Normal file
948
assets/viz/2/goog/html/safehtml.js
Normal file
@ -0,0 +1,948 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview The SafeHtml type and its builders.
|
||||
*
|
||||
* TODO(xtof): Link to document stating type contract.
|
||||
*/
|
||||
|
||||
goog.provide('goog.html.SafeHtml');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.dom.tags');
|
||||
goog.require('goog.html.SafeStyle');
|
||||
goog.require('goog.html.SafeStyleSheet');
|
||||
goog.require('goog.html.SafeUrl');
|
||||
goog.require('goog.html.TrustedResourceUrl');
|
||||
goog.require('goog.i18n.bidi.Dir');
|
||||
goog.require('goog.i18n.bidi.DirectionalString');
|
||||
goog.require('goog.labs.userAgent.browser');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.Const');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A string that is safe to use in HTML context in DOM APIs and HTML documents.
|
||||
*
|
||||
* A SafeHtml is a string-like object that carries the security type contract
|
||||
* that its value as a string will not cause untrusted script execution when
|
||||
* evaluated as HTML in a browser.
|
||||
*
|
||||
* Values of this type are guaranteed to be safe to use in HTML contexts,
|
||||
* such as, assignment to the innerHTML DOM property, or interpolation into
|
||||
* a HTML template in HTML PC_DATA context, in the sense that the use will not
|
||||
* result in a Cross-Site-Scripting vulnerability.
|
||||
*
|
||||
* Instances of this type must be created via the factory methods
|
||||
* ({@code goog.html.SafeHtml.create}, {@code goog.html.SafeHtml.htmlEscape}),
|
||||
* etc and not by invoking its constructor. The constructor intentionally
|
||||
* takes no parameters and the type is immutable; hence only a default instance
|
||||
* corresponding to the empty string can be obtained via constructor invocation.
|
||||
*
|
||||
* @see goog.html.SafeHtml#create
|
||||
* @see goog.html.SafeHtml#htmlEscape
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.i18n.bidi.DirectionalString}
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.html.SafeHtml = function() {
|
||||
/**
|
||||
* The contained value of this SafeHtml. The field has a purposely ugly
|
||||
* name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.html.SafeHtml#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.SAFE_HTML_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =
|
||||
goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
|
||||
|
||||
/**
|
||||
* This SafeHtml's directionality, or null if unknown.
|
||||
* @private {?goog.i18n.bidi.Dir}
|
||||
*/
|
||||
this.dir_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeHtml.prototype.implementsGoogI18nBidiDirectionalString = true;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.html.SafeHtml.prototype.getDirection = function() {
|
||||
return this.dir_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeHtml.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Returns this SafeHtml's value as string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security relevant that an object's type is
|
||||
* indeed {@code SafeHtml}, use {@code goog.html.SafeHtml.unwrap} instead of
|
||||
* this method. If in doubt, assume that it's security relevant. In particular,
|
||||
* note that goog.html functions which return a goog.html type do not guarantee
|
||||
* that the returned instance is of the right type. For example:
|
||||
*
|
||||
* <pre>
|
||||
* var fakeSafeHtml = new String('fake');
|
||||
* fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;
|
||||
* var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);
|
||||
* // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by
|
||||
* // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml
|
||||
* // instanceof goog.html.SafeHtml.
|
||||
* </pre>
|
||||
*
|
||||
* @see goog.html.SafeHtml#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeHtml.prototype.getTypedStringValue = function() {
|
||||
return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_;
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a debug string-representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped in a SafeHtml, use
|
||||
* {@code goog.html.SafeHtml.unwrap}.
|
||||
*
|
||||
* @see goog.html.SafeHtml#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeHtml.prototype.toString = function() {
|
||||
return 'SafeHtml{' + this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ +
|
||||
'}';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed a SafeHtml
|
||||
* object, and returns its value.
|
||||
* @param {!goog.html.SafeHtml} safeHtml The object to extract from.
|
||||
* @return {string} The SafeHtml object's contained string, unless the run-time
|
||||
* type check fails. In that case, {@code unwrap} returns an innocuous
|
||||
* string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.html.SafeHtml.unwrap = function(safeHtml) {
|
||||
// Perform additional run-time type-checking to ensure that safeHtml is indeed
|
||||
// an instance of the expected type. This provides some additional protection
|
||||
// against security bugs due to application code that disables type checks.
|
||||
// Specifically, the following checks are performed:
|
||||
// 1. The object is an instance of the expected type.
|
||||
// 2. The object is not an instance of a subclass.
|
||||
// 3. The object carries a type marker for the expected type. "Faking" an
|
||||
// object requires a reference to the type marker, which has names intended
|
||||
// to stand out in code reviews.
|
||||
if (safeHtml instanceof goog.html.SafeHtml &&
|
||||
safeHtml.constructor === goog.html.SafeHtml &&
|
||||
safeHtml.SAFE_HTML_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===
|
||||
goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
|
||||
return safeHtml.privateDoNotAccessOrElseSafeHtmlWrappedValue_;
|
||||
} else {
|
||||
goog.asserts.fail('expected object of type SafeHtml, got \'' +
|
||||
safeHtml + '\' of type ' + goog.typeOf(safeHtml));
|
||||
return 'type_error:SafeHtml';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Shorthand for union of types that can sensibly be converted to strings
|
||||
* or might already be SafeHtml (as SafeHtml is a goog.string.TypedString).
|
||||
* @private
|
||||
* @typedef {string|number|boolean|!goog.string.TypedString|
|
||||
* !goog.i18n.bidi.DirectionalString}
|
||||
*/
|
||||
goog.html.SafeHtml.TextOrHtml_;
|
||||
|
||||
|
||||
/**
|
||||
* Returns HTML-escaped text as a SafeHtml object.
|
||||
*
|
||||
* If text is of a type that implements
|
||||
* {@code goog.i18n.bidi.DirectionalString}, the directionality of the new
|
||||
* {@code SafeHtml} object is set to {@code text}'s directionality, if known.
|
||||
* Otherwise, the directionality of the resulting SafeHtml is unknown (i.e.,
|
||||
* {@code null}).
|
||||
*
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_} textOrHtml The text to escape. If
|
||||
* the parameter is of type SafeHtml it is returned directly (no escaping
|
||||
* is done).
|
||||
* @return {!goog.html.SafeHtml} The escaped text, wrapped as a SafeHtml.
|
||||
*/
|
||||
goog.html.SafeHtml.htmlEscape = function(textOrHtml) {
|
||||
if (textOrHtml instanceof goog.html.SafeHtml) {
|
||||
return textOrHtml;
|
||||
}
|
||||
var dir = null;
|
||||
if (textOrHtml.implementsGoogI18nBidiDirectionalString) {
|
||||
dir = textOrHtml.getDirection();
|
||||
}
|
||||
var textAsString;
|
||||
if (textOrHtml.implementsGoogStringTypedString) {
|
||||
textAsString = textOrHtml.getTypedStringValue();
|
||||
} else {
|
||||
textAsString = String(textOrHtml);
|
||||
}
|
||||
return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
goog.string.htmlEscape(textAsString), dir);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns HTML-escaped text as a SafeHtml object, with newlines changed to
|
||||
* <br>.
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_} textOrHtml The text to escape. If
|
||||
* the parameter is of type SafeHtml it is returned directly (no escaping
|
||||
* is done).
|
||||
* @return {!goog.html.SafeHtml} The escaped text, wrapped as a SafeHtml.
|
||||
*/
|
||||
goog.html.SafeHtml.htmlEscapePreservingNewlines = function(textOrHtml) {
|
||||
if (textOrHtml instanceof goog.html.SafeHtml) {
|
||||
return textOrHtml;
|
||||
}
|
||||
var html = goog.html.SafeHtml.htmlEscape(textOrHtml);
|
||||
return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
goog.string.newLineToBr(goog.html.SafeHtml.unwrap(html)),
|
||||
html.getDirection());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns HTML-escaped text as a SafeHtml object, with newlines changed to
|
||||
* <br> and escaping whitespace to preserve spatial formatting. Character
|
||||
* entity #160 is used to make it safer for XML.
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_} textOrHtml The text to escape. If
|
||||
* the parameter is of type SafeHtml it is returned directly (no escaping
|
||||
* is done).
|
||||
* @return {!goog.html.SafeHtml} The escaped text, wrapped as a SafeHtml.
|
||||
*/
|
||||
goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces = function(
|
||||
textOrHtml) {
|
||||
if (textOrHtml instanceof goog.html.SafeHtml) {
|
||||
return textOrHtml;
|
||||
}
|
||||
var html = goog.html.SafeHtml.htmlEscape(textOrHtml);
|
||||
return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
goog.string.whitespaceEscape(goog.html.SafeHtml.unwrap(html)),
|
||||
html.getDirection());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Coerces an arbitrary object into a SafeHtml object.
|
||||
*
|
||||
* If {@code textOrHtml} is already of type {@code goog.html.SafeHtml}, the same
|
||||
* object is returned. Otherwise, {@code textOrHtml} is coerced to string, and
|
||||
* HTML-escaped. If {@code textOrHtml} is of a type that implements
|
||||
* {@code goog.i18n.bidi.DirectionalString}, its directionality, if known, is
|
||||
* preserved.
|
||||
*
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_} textOrHtml The text or SafeHtml to
|
||||
* coerce.
|
||||
* @return {!goog.html.SafeHtml} The resulting SafeHtml object.
|
||||
* @deprecated Use goog.html.SafeHtml.htmlEscape.
|
||||
*/
|
||||
goog.html.SafeHtml.from = goog.html.SafeHtml.htmlEscape;
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeHtml.VALID_NAMES_IN_TAG_ = /^[a-zA-Z0-9-]+$/;
|
||||
|
||||
|
||||
/**
|
||||
* Set of attributes containing URL as defined at
|
||||
* http://www.w3.org/TR/html5/index.html#attributes-1.
|
||||
* @private @const {!Object<string,boolean>}
|
||||
*/
|
||||
goog.html.SafeHtml.URL_ATTRIBUTES_ = goog.object.createSet(
|
||||
'action', 'cite', 'data', 'formaction', 'href', 'manifest', 'poster',
|
||||
'src');
|
||||
|
||||
|
||||
/**
|
||||
* Tags which are unsupported via create(). They might be supported via a
|
||||
* tag-specific create method. These are tags which might require a
|
||||
* TrustedResourceUrl in one of their attributes or a restricted type for
|
||||
* their content.
|
||||
* @private @const {!Object<string,boolean>}
|
||||
*/
|
||||
goog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_ = goog.object.createSet(
|
||||
goog.dom.TagName.APPLET, goog.dom.TagName.BASE, goog.dom.TagName.EMBED,
|
||||
goog.dom.TagName.IFRAME, goog.dom.TagName.LINK, goog.dom.TagName.MATH,
|
||||
goog.dom.TagName.META, goog.dom.TagName.OBJECT, goog.dom.TagName.SCRIPT,
|
||||
goog.dom.TagName.STYLE, goog.dom.TagName.SVG, goog.dom.TagName.TEMPLATE);
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {string|number|goog.string.TypedString|
|
||||
* goog.html.SafeStyle.PropertyMap}
|
||||
*/
|
||||
goog.html.SafeHtml.AttributeValue;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml content consisting of a tag with optional attributes and
|
||||
* optional content.
|
||||
*
|
||||
* For convenience tag names and attribute names are accepted as regular
|
||||
* strings, instead of goog.string.Const. Nevertheless, you should not pass
|
||||
* user-controlled values to these parameters. Note that these parameters are
|
||||
* syntactically validated at runtime, and invalid values will result in
|
||||
* an exception.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* goog.html.SafeHtml.create('br');
|
||||
* goog.html.SafeHtml.create('div', {'class': 'a'});
|
||||
* goog.html.SafeHtml.create('p', {}, 'a');
|
||||
* goog.html.SafeHtml.create('p', {}, goog.html.SafeHtml.create('br'));
|
||||
*
|
||||
* goog.html.SafeHtml.create('span', {
|
||||
* 'style': {'margin': '0'}
|
||||
* });
|
||||
*
|
||||
* To guarantee SafeHtml's type contract is upheld there are restrictions on
|
||||
* attribute values and tag names.
|
||||
*
|
||||
* - For attributes which contain script code (on*), a goog.string.Const is
|
||||
* required.
|
||||
* - For attributes which contain style (style), a goog.html.SafeStyle or a
|
||||
* goog.html.SafeStyle.PropertyMap is required.
|
||||
* - For attributes which are interpreted as URLs (e.g. src, href) a
|
||||
* goog.html.SafeUrl, goog.string.Const or string is required. If a string
|
||||
* is passed, it will be sanitized with SafeUrl.sanitize().
|
||||
* - For tags which can load code or set security relevant page metadata,
|
||||
* more specific goog.html.SafeHtml.create*() functions must be used. Tags
|
||||
* which are not supported by this function are applet, base, embed, iframe,
|
||||
* link, math, object, script, style, svg, and template.
|
||||
*
|
||||
* @param {string} tagName The name of the tag. Only tag names consisting of
|
||||
* [a-zA-Z0-9-] are allowed. Tag names documented above are disallowed.
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* Mapping from attribute names to their values. Only attribute names
|
||||
* consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes
|
||||
* the attribute to be omitted.
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content Content to
|
||||
* HTML-escape and put inside the tag. This must be empty for void tags
|
||||
* like <br>. Array elements are concatenated.
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
* @throws {Error} If invalid tag name, attribute name, or attribute value is
|
||||
* provided.
|
||||
* @throws {goog.asserts.AssertionError} If content for void tag is provided.
|
||||
*/
|
||||
goog.html.SafeHtml.create = function(tagName, opt_attributes, opt_content) {
|
||||
goog.html.SafeHtml.verifyTagName(tagName);
|
||||
return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(
|
||||
tagName, opt_attributes, opt_content);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Verifies if the tag name is valid and if it doesn't change the context.
|
||||
* E.g. STRONG is fine but SCRIPT throws because it changes context. See
|
||||
* goog.html.SafeHtml.create for an explanation of allowed tags.
|
||||
* @param {string} tagName
|
||||
* @throws {Error} If invalid tag name is provided.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeHtml.verifyTagName = function(tagName) {
|
||||
if (!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(tagName)) {
|
||||
throw Error('Invalid tag name <' + tagName + '>.');
|
||||
}
|
||||
if (tagName.toUpperCase() in goog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_) {
|
||||
throw Error('Tag name <' + tagName + '> is not allowed for SafeHtml.');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml representing an iframe tag.
|
||||
*
|
||||
* This by default restricts the iframe as much as possible by setting the
|
||||
* sandbox attribute to the empty string. If the iframe requires less
|
||||
* restrictions, set the sandbox attribute as tight as possible, but do not rely
|
||||
* on the sandbox as a security feature because it is not supported by older
|
||||
* browsers. If a sandbox is essential to security (e.g. for third-party
|
||||
* frames), use createSandboxIframe which checks for browser support.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe#attr-sandbox
|
||||
*
|
||||
* @param {?goog.html.TrustedResourceUrl=} opt_src The value of the src
|
||||
* attribute. If null or undefined src will not be set.
|
||||
* @param {?goog.html.SafeHtml=} opt_srcdoc The value of the srcdoc attribute.
|
||||
* If null or undefined srcdoc will not be set.
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* Mapping from attribute names to their values. Only attribute names
|
||||
* consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes
|
||||
* the attribute to be omitted.
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content Content to
|
||||
* HTML-escape and put inside the tag. Array elements are concatenated.
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
* @throws {Error} If invalid tag name, attribute name, or attribute value is
|
||||
* provided. If opt_attributes contains the src or srcdoc attributes.
|
||||
*/
|
||||
goog.html.SafeHtml.createIframe = function(
|
||||
opt_src, opt_srcdoc, opt_attributes, opt_content) {
|
||||
if (opt_src) {
|
||||
// Check whether this is really TrustedResourceUrl.
|
||||
goog.html.TrustedResourceUrl.unwrap(opt_src);
|
||||
}
|
||||
|
||||
var fixedAttributes = {};
|
||||
fixedAttributes['src'] = opt_src || null;
|
||||
fixedAttributes['srcdoc'] =
|
||||
opt_srcdoc && goog.html.SafeHtml.unwrap(opt_srcdoc);
|
||||
var defaultAttributes = {'sandbox': ''};
|
||||
var attributes = goog.html.SafeHtml.combineAttributes(
|
||||
fixedAttributes, defaultAttributes, opt_attributes);
|
||||
return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(
|
||||
'iframe', attributes, opt_content);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml representing a sandboxed iframe tag.
|
||||
*
|
||||
* The sandbox attribute is enforced in its most restrictive mode, an empty
|
||||
* string. Consequently, the security requirements for the src and srcdoc
|
||||
* attributes are relaxed compared to SafeHtml.createIframe. This function
|
||||
* will throw on browsers that do not support the sandbox attribute, as
|
||||
* determined by SafeHtml.canUseSandboxIframe.
|
||||
*
|
||||
* The SafeHtml returned by this function can trigger downloads with no
|
||||
* user interaction on Chrome (though only a few, further attempts are blocked).
|
||||
* Firefox and IE will block all downloads from the sandbox.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe#attr-sandbox
|
||||
* @see https://lists.w3.org/Archives/Public/public-whatwg-archive/2013Feb/0112.html
|
||||
*
|
||||
* @param {string|!goog.html.SafeUrl=} opt_src The value of the src
|
||||
* attribute. If null or undefined src will not be set.
|
||||
* @param {string=} opt_srcdoc The value of the srcdoc attribute.
|
||||
* If null or undefined srcdoc will not be set. Will not be sanitized.
|
||||
* @param {!Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* Mapping from attribute names to their values. Only attribute names
|
||||
* consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes
|
||||
* the attribute to be omitted.
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content Content to
|
||||
* HTML-escape and put inside the tag. Array elements are concatenated.
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
* @throws {Error} If invalid tag name, attribute name, or attribute value is
|
||||
* provided. If opt_attributes contains the src, srcdoc or sandbox
|
||||
* attributes. If browser does not support the sandbox attribute on iframe.
|
||||
*/
|
||||
goog.html.SafeHtml.createSandboxIframe = function(
|
||||
opt_src, opt_srcdoc, opt_attributes, opt_content) {
|
||||
if (!goog.html.SafeHtml.canUseSandboxIframe()) {
|
||||
throw new Error('The browser does not support sandboxed iframes.');
|
||||
}
|
||||
|
||||
var fixedAttributes = {};
|
||||
if (opt_src) {
|
||||
// Note that sanitize is a no-op on SafeUrl.
|
||||
fixedAttributes['src'] =
|
||||
goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(opt_src));
|
||||
} else {
|
||||
fixedAttributes['src'] = null;
|
||||
}
|
||||
fixedAttributes['srcdoc'] = opt_srcdoc || null;
|
||||
fixedAttributes['sandbox'] = '';
|
||||
var attributes =
|
||||
goog.html.SafeHtml.combineAttributes(fixedAttributes, {}, opt_attributes);
|
||||
return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(
|
||||
'iframe', attributes, opt_content);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the user agent supports sandboxed iframes.
|
||||
* @return {boolean}
|
||||
*/
|
||||
goog.html.SafeHtml.canUseSandboxIframe = function() {
|
||||
return goog.global['HTMLIFrameElement'] &&
|
||||
('sandbox' in goog.global['HTMLIFrameElement'].prototype);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml representing a script tag with the src attribute.
|
||||
* @param {!goog.html.TrustedResourceUrl} src The value of the src
|
||||
* attribute.
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=}
|
||||
* opt_attributes
|
||||
* Mapping from attribute names to their values. Only attribute names
|
||||
* consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined
|
||||
* causes the attribute to be omitted.
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
* @throws {Error} If invalid attribute name or value is provided. If
|
||||
* opt_attributes contains the src attribute.
|
||||
*/
|
||||
goog.html.SafeHtml.createScriptSrc = function(src, opt_attributes) {
|
||||
// Check whether this is really TrustedResourceUrl.
|
||||
goog.html.TrustedResourceUrl.unwrap(src);
|
||||
|
||||
var fixedAttributes = {'src': src};
|
||||
var defaultAttributes = {};
|
||||
var attributes = goog.html.SafeHtml.combineAttributes(
|
||||
fixedAttributes, defaultAttributes, opt_attributes);
|
||||
return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(
|
||||
'script', attributes);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml representing a style tag. The type attribute is set
|
||||
* to "text/css".
|
||||
* @param {!goog.html.SafeStyleSheet|!Array<!goog.html.SafeStyleSheet>}
|
||||
* styleSheet Content to put inside the tag. Array elements are
|
||||
* concatenated.
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* Mapping from attribute names to their values. Only attribute names
|
||||
* consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes
|
||||
* the attribute to be omitted.
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
* @throws {Error} If invalid attribute name or attribute value is provided. If
|
||||
* opt_attributes contains the type attribute.
|
||||
*/
|
||||
goog.html.SafeHtml.createStyle = function(styleSheet, opt_attributes) {
|
||||
var fixedAttributes = {'type': 'text/css'};
|
||||
var defaultAttributes = {};
|
||||
var attributes = goog.html.SafeHtml.combineAttributes(
|
||||
fixedAttributes, defaultAttributes, opt_attributes);
|
||||
|
||||
var content = '';
|
||||
styleSheet = goog.array.concat(styleSheet);
|
||||
for (var i = 0; i < styleSheet.length; i++) {
|
||||
content += goog.html.SafeStyleSheet.unwrap(styleSheet[i]);
|
||||
}
|
||||
// Convert to SafeHtml so that it's not HTML-escaped. This is safe because
|
||||
// as part of its contract, SafeStyleSheet should have no dangerous '<'.
|
||||
var htmlContent =
|
||||
goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
content, goog.i18n.bidi.Dir.NEUTRAL);
|
||||
return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(
|
||||
'style', attributes, htmlContent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml representing a meta refresh tag.
|
||||
* @param {!goog.html.SafeUrl|string} url Where to redirect. If a string is
|
||||
* passed, it will be sanitized with SafeUrl.sanitize().
|
||||
* @param {number=} opt_secs Number of seconds until the page should be
|
||||
* reloaded. Will be set to 0 if unspecified.
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
*/
|
||||
goog.html.SafeHtml.createMetaRefresh = function(url, opt_secs) {
|
||||
|
||||
// Note that sanitize is a no-op on SafeUrl.
|
||||
var unwrappedUrl = goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(url));
|
||||
|
||||
if (goog.labs.userAgent.browser.isIE() ||
|
||||
goog.labs.userAgent.browser.isEdge()) {
|
||||
// IE/EDGE can't parse the content attribute if the url contains a
|
||||
// semicolon. We can fix this by adding quotes around the url, but then we
|
||||
// can't parse quotes in the URL correctly. Also, it seems that IE/EDGE
|
||||
// did not unescape semicolons in these URLs at some point in the past. We
|
||||
// take a best-effort approach.
|
||||
//
|
||||
// If the URL has semicolons (which may happen in some cases, see
|
||||
// http://www.w3.org/TR/1999/REC-html401-19991224/appendix/notes.html#h-B.2
|
||||
// for instance), wrap it in single quotes to protect the semicolons.
|
||||
// If the URL has semicolons and single quotes, url-encode the single quotes
|
||||
// as well.
|
||||
//
|
||||
// This is imperfect. Notice that both ' and ; are reserved characters in
|
||||
// URIs, so this could do the wrong thing, but at least it will do the wrong
|
||||
// thing in only rare cases.
|
||||
if (goog.string.contains(unwrappedUrl, ';')) {
|
||||
unwrappedUrl = "'" + unwrappedUrl.replace(/'/g, '%27') + "'";
|
||||
}
|
||||
}
|
||||
var attributes = {
|
||||
'http-equiv': 'refresh',
|
||||
'content': (opt_secs || 0) + '; url=' + unwrappedUrl
|
||||
};
|
||||
|
||||
// This function will handle the HTML escaping for attributes.
|
||||
return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(
|
||||
'meta', attributes);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} tagName The tag name.
|
||||
* @param {string} name The attribute name.
|
||||
* @param {!goog.html.SafeHtml.AttributeValue} value The attribute value.
|
||||
* @return {string} A "name=value" string.
|
||||
* @throws {Error} If attribute value is unsafe for the given tag and attribute.
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeHtml.getAttrNameAndValue_ = function(tagName, name, value) {
|
||||
// If it's goog.string.Const, allow any valid attribute name.
|
||||
if (value instanceof goog.string.Const) {
|
||||
value = goog.string.Const.unwrap(value);
|
||||
} else if (name.toLowerCase() == 'style') {
|
||||
value = goog.html.SafeHtml.getStyleValue_(value);
|
||||
} else if (/^on/i.test(name)) {
|
||||
// TODO(jakubvrana): Disallow more attributes with a special meaning.
|
||||
throw Error(
|
||||
'Attribute "' + name + '" requires goog.string.Const value, "' + value +
|
||||
'" given.');
|
||||
// URL attributes handled differently accroding to tag.
|
||||
} else if (name.toLowerCase() in goog.html.SafeHtml.URL_ATTRIBUTES_) {
|
||||
if (value instanceof goog.html.TrustedResourceUrl) {
|
||||
value = goog.html.TrustedResourceUrl.unwrap(value);
|
||||
} else if (value instanceof goog.html.SafeUrl) {
|
||||
value = goog.html.SafeUrl.unwrap(value);
|
||||
} else if (goog.isString(value)) {
|
||||
value = goog.html.SafeUrl.sanitize(value).getTypedStringValue();
|
||||
} else {
|
||||
throw Error(
|
||||
'Attribute "' + name + '" on tag "' + tagName +
|
||||
'" requires goog.html.SafeUrl, goog.string.Const, or string,' +
|
||||
' value "' + value + '" given.');
|
||||
}
|
||||
}
|
||||
|
||||
// Accept SafeUrl, TrustedResourceUrl, etc. for attributes which only require
|
||||
// HTML-escaping.
|
||||
if (value.implementsGoogStringTypedString) {
|
||||
// Ok to call getTypedStringValue() since there's no reliance on the type
|
||||
// contract for security here.
|
||||
value = value.getTypedStringValue();
|
||||
}
|
||||
|
||||
goog.asserts.assert(
|
||||
goog.isString(value) || goog.isNumber(value),
|
||||
'String or number value expected, got ' + (typeof value) +
|
||||
' with value: ' + value);
|
||||
return name + '="' + goog.string.htmlEscape(String(value)) + '"';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets value allowed in "style" attribute.
|
||||
* @param {!goog.html.SafeHtml.AttributeValue} value It could be SafeStyle or a
|
||||
* map which will be passed to goog.html.SafeStyle.create.
|
||||
* @return {string} Unwrapped value.
|
||||
* @throws {Error} If string value is given.
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeHtml.getStyleValue_ = function(value) {
|
||||
if (!goog.isObject(value)) {
|
||||
throw Error(
|
||||
'The "style" attribute requires goog.html.SafeStyle or map ' +
|
||||
'of style properties, ' + (typeof value) + ' given: ' + value);
|
||||
}
|
||||
if (!(value instanceof goog.html.SafeStyle)) {
|
||||
// Process the property bag into a style object.
|
||||
value = goog.html.SafeStyle.create(value);
|
||||
}
|
||||
return goog.html.SafeStyle.unwrap(value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml content with known directionality consisting of a tag with
|
||||
* optional attributes and optional content.
|
||||
* @param {!goog.i18n.bidi.Dir} dir Directionality.
|
||||
* @param {string} tagName
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
*/
|
||||
goog.html.SafeHtml.createWithDir = function(
|
||||
dir, tagName, opt_attributes, opt_content) {
|
||||
var html = goog.html.SafeHtml.create(tagName, opt_attributes, opt_content);
|
||||
html.dir_ = dir;
|
||||
return html;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new SafeHtml object by concatenating values.
|
||||
* @param {...(!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>)} var_args Values to concatenate.
|
||||
* @return {!goog.html.SafeHtml}
|
||||
*/
|
||||
goog.html.SafeHtml.concat = function(var_args) {
|
||||
var dir = goog.i18n.bidi.Dir.NEUTRAL;
|
||||
var content = '';
|
||||
|
||||
/**
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>} argument
|
||||
*/
|
||||
var addArgument = function(argument) {
|
||||
if (goog.isArray(argument)) {
|
||||
goog.array.forEach(argument, addArgument);
|
||||
} else {
|
||||
var html = goog.html.SafeHtml.htmlEscape(argument);
|
||||
content += goog.html.SafeHtml.unwrap(html);
|
||||
var htmlDir = html.getDirection();
|
||||
if (dir == goog.i18n.bidi.Dir.NEUTRAL) {
|
||||
dir = htmlDir;
|
||||
} else if (htmlDir != goog.i18n.bidi.Dir.NEUTRAL && dir != htmlDir) {
|
||||
dir = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
goog.array.forEach(arguments, addArgument);
|
||||
return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
content, dir);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new SafeHtml object with known directionality by concatenating the
|
||||
* values.
|
||||
* @param {!goog.i18n.bidi.Dir} dir Directionality.
|
||||
* @param {...(!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>)} var_args Elements of array
|
||||
* arguments would be processed recursively.
|
||||
* @return {!goog.html.SafeHtml}
|
||||
*/
|
||||
goog.html.SafeHtml.concatWithDir = function(dir, var_args) {
|
||||
var html = goog.html.SafeHtml.concat(goog.array.slice(arguments, 1));
|
||||
html.dir_ = dir;
|
||||
return html;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the SafeHtml type, used to implement additional run-time
|
||||
* type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Package-internal utility method to create SafeHtml instances.
|
||||
*
|
||||
* @param {string} html The string to initialize the SafeHtml object with.
|
||||
* @param {?goog.i18n.bidi.Dir} dir The directionality of the SafeHtml to be
|
||||
* constructed, or null if unknown.
|
||||
* @return {!goog.html.SafeHtml} The initialized SafeHtml object.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse = function(
|
||||
html, dir) {
|
||||
return new goog.html.SafeHtml().initSecurityPrivateDoNotAccessOrElse_(
|
||||
html, dir);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called from createSafeHtmlSecurityPrivateDoNotAccessOrElse(). This
|
||||
* method exists only so that the compiler can dead code eliminate static
|
||||
* fields (like EMPTY) when they're not accessed.
|
||||
* @param {string} html
|
||||
* @param {?goog.i18n.bidi.Dir} dir
|
||||
* @return {!goog.html.SafeHtml}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeHtml.prototype.initSecurityPrivateDoNotAccessOrElse_ = function(
|
||||
html, dir) {
|
||||
this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = html;
|
||||
this.dir_ = dir;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Like create() but does not restrict which tags can be constructed.
|
||||
*
|
||||
* @param {string} tagName Tag name. Set or validated by caller.
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* @param {(!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>)=} opt_content
|
||||
* @return {!goog.html.SafeHtml}
|
||||
* @throws {Error} If invalid or unsafe attribute name or value is provided.
|
||||
* @throws {goog.asserts.AssertionError} If content for void tag is provided.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse = function(
|
||||
tagName, opt_attributes, opt_content) {
|
||||
var dir = null;
|
||||
var result = '<' + tagName;
|
||||
result += goog.html.SafeHtml.stringifyAttributes(tagName, opt_attributes);
|
||||
|
||||
var content = opt_content;
|
||||
if (!goog.isDefAndNotNull(content)) {
|
||||
content = [];
|
||||
} else if (!goog.isArray(content)) {
|
||||
content = [content];
|
||||
}
|
||||
|
||||
if (goog.dom.tags.isVoidTag(tagName.toLowerCase())) {
|
||||
goog.asserts.assert(
|
||||
!content.length, 'Void tag <' + tagName + '> does not allow content.');
|
||||
result += '>';
|
||||
} else {
|
||||
var html = goog.html.SafeHtml.concat(content);
|
||||
result += '>' + goog.html.SafeHtml.unwrap(html) + '</' + tagName + '>';
|
||||
dir = html.getDirection();
|
||||
}
|
||||
|
||||
var dirAttribute = opt_attributes && opt_attributes['dir'];
|
||||
if (dirAttribute) {
|
||||
if (/^(ltr|rtl|auto)$/i.test(dirAttribute)) {
|
||||
// If the tag has the "dir" attribute specified then its direction is
|
||||
// neutral because it can be safely used in any context.
|
||||
dir = goog.i18n.bidi.Dir.NEUTRAL;
|
||||
} else {
|
||||
dir = null;
|
||||
}
|
||||
}
|
||||
|
||||
return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
result, dir);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a string with attributes to insert after tagName.
|
||||
* @param {string} tagName
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* @return {string} Returns an empty string if there are no attributes, returns
|
||||
* a string starting with a space otherwise.
|
||||
* @throws {Error} If attribute value is unsafe for the given tag and attribute.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeHtml.stringifyAttributes = function(tagName, opt_attributes) {
|
||||
var result = '';
|
||||
if (opt_attributes) {
|
||||
for (var name in opt_attributes) {
|
||||
if (!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(name)) {
|
||||
throw Error('Invalid attribute name "' + name + '".');
|
||||
}
|
||||
var value = opt_attributes[name];
|
||||
if (!goog.isDefAndNotNull(value)) {
|
||||
continue;
|
||||
}
|
||||
result +=
|
||||
' ' + goog.html.SafeHtml.getAttrNameAndValue_(tagName, name, value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!Object<string, string>} fixedAttributes
|
||||
* @param {!Object<string, string>} defaultAttributes
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* Optional attributes passed to create*().
|
||||
* @return {!Object<string, ?goog.html.SafeHtml.AttributeValue>}
|
||||
* @throws {Error} If opt_attributes contains an attribute with the same name
|
||||
* as an attribute in fixedAttributes.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeHtml.combineAttributes = function(
|
||||
fixedAttributes, defaultAttributes, opt_attributes) {
|
||||
var combinedAttributes = {};
|
||||
var name;
|
||||
|
||||
for (name in fixedAttributes) {
|
||||
goog.asserts.assert(name.toLowerCase() == name, 'Must be lower case');
|
||||
combinedAttributes[name] = fixedAttributes[name];
|
||||
}
|
||||
for (name in defaultAttributes) {
|
||||
goog.asserts.assert(name.toLowerCase() == name, 'Must be lower case');
|
||||
combinedAttributes[name] = defaultAttributes[name];
|
||||
}
|
||||
|
||||
for (name in opt_attributes) {
|
||||
var nameLower = name.toLowerCase();
|
||||
if (nameLower in fixedAttributes) {
|
||||
throw Error(
|
||||
'Cannot override "' + nameLower + '" attribute, got "' + name +
|
||||
'" with value "' + opt_attributes[name] + '"');
|
||||
}
|
||||
if (nameLower in defaultAttributes) {
|
||||
delete combinedAttributes[nameLower];
|
||||
}
|
||||
combinedAttributes[name] = opt_attributes[name];
|
||||
}
|
||||
|
||||
return combinedAttributes;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A SafeHtml instance corresponding to the HTML doctype: "<!DOCTYPE html>".
|
||||
* @const {!goog.html.SafeHtml}
|
||||
*/
|
||||
goog.html.SafeHtml.DOCTYPE_HTML =
|
||||
goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
'<!DOCTYPE html>', goog.i18n.bidi.Dir.NEUTRAL);
|
||||
|
||||
|
||||
/**
|
||||
* A SafeHtml instance corresponding to the empty string.
|
||||
* @const {!goog.html.SafeHtml}
|
||||
*/
|
||||
goog.html.SafeHtml.EMPTY =
|
||||
goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
'', goog.i18n.bidi.Dir.NEUTRAL);
|
||||
|
||||
|
||||
/**
|
||||
* A SafeHtml instance corresponding to the <br> tag.
|
||||
* @const {!goog.html.SafeHtml}
|
||||
*/
|
||||
goog.html.SafeHtml.BR =
|
||||
goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
'<br>', goog.i18n.bidi.Dir.NEUTRAL);
|
234
assets/viz/2/goog/html/safescript.js
Normal file
234
assets/viz/2/goog/html/safescript.js
Normal file
@ -0,0 +1,234 @@
|
||||
// Copyright 2014 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview The SafeScript type and its builders.
|
||||
*
|
||||
* TODO(xtof): Link to document stating type contract.
|
||||
*/
|
||||
|
||||
goog.provide('goog.html.SafeScript');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.string.Const');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A string-like object which represents JavaScript code and that carries the
|
||||
* security type contract that its value, as a string, will not cause execution
|
||||
* of unconstrained attacker controlled code (XSS) when evaluated as JavaScript
|
||||
* in a browser.
|
||||
*
|
||||
* Instances of this type must be created via the factory method
|
||||
* {@code goog.html.SafeScript.fromConstant} and not by invoking its
|
||||
* constructor. The constructor intentionally takes no parameters and the type
|
||||
* is immutable; hence only a default instance corresponding to the empty string
|
||||
* can be obtained via constructor invocation.
|
||||
*
|
||||
* A SafeScript's string representation can safely be interpolated as the
|
||||
* content of a script element within HTML. The SafeScript string should not be
|
||||
* escaped before interpolation.
|
||||
*
|
||||
* Note that the SafeScript might contain text that is attacker-controlled but
|
||||
* that text should have been interpolated with appropriate escaping,
|
||||
* sanitization and/or validation into the right location in the script, such
|
||||
* that it is highly constrained in its effect (for example, it had to match a
|
||||
* set of whitelisted words).
|
||||
*
|
||||
* A SafeScript can be constructed via security-reviewed unchecked
|
||||
* conversions. In this case producers of SafeScript must ensure themselves that
|
||||
* the SafeScript does not contain unsafe script. Note in particular that
|
||||
* {@code <} is dangerous, even when inside JavaScript strings, and so should
|
||||
* always be forbidden or JavaScript escaped in user controlled input. For
|
||||
* example, if {@code </script><script>evil</script>"} were
|
||||
* interpolated inside a JavaScript string, it would break out of the context
|
||||
* of the original script element and {@code evil} would execute. Also note
|
||||
* that within an HTML script (raw text) element, HTML character references,
|
||||
* such as "<" are not allowed. See
|
||||
* http://www.w3.org/TR/html5/scripting-1.html#restrictions-for-contents-of-script-elements.
|
||||
*
|
||||
* @see goog.html.SafeScript#fromConstant
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.html.SafeScript = function() {
|
||||
/**
|
||||
* The contained value of this SafeScript. The field has a purposely
|
||||
* ugly name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.privateDoNotAccessOrElseSafeScriptWrappedValue_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.html.SafeScript#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =
|
||||
goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeScript.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the SafeScript type, used to implement additional
|
||||
* run-time type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeScript object from a compile-time constant string.
|
||||
*
|
||||
* @param {!goog.string.Const} script A compile-time-constant string from which
|
||||
* to create a SafeScript.
|
||||
* @return {!goog.html.SafeScript} A SafeScript object initialized to
|
||||
* {@code script}.
|
||||
*/
|
||||
goog.html.SafeScript.fromConstant = function(script) {
|
||||
var scriptString = goog.string.Const.unwrap(script);
|
||||
if (scriptString.length === 0) {
|
||||
return goog.html.SafeScript.EMPTY;
|
||||
}
|
||||
return goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse(
|
||||
scriptString);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this SafeScript's value as a string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security relevant that an object's type is
|
||||
* indeed {@code SafeScript}, use {@code goog.html.SafeScript.unwrap} instead of
|
||||
* this method. If in doubt, assume that it's security relevant. In particular,
|
||||
* note that goog.html functions which return a goog.html type do not guarantee
|
||||
* the returned instance is of the right type. For example:
|
||||
*
|
||||
* <pre>
|
||||
* var fakeSafeHtml = new String('fake');
|
||||
* fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;
|
||||
* var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);
|
||||
* // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by
|
||||
* // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml
|
||||
* // instanceof goog.html.SafeHtml.
|
||||
* </pre>
|
||||
*
|
||||
* @see goog.html.SafeScript#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeScript.prototype.getTypedStringValue = function() {
|
||||
return this.privateDoNotAccessOrElseSafeScriptWrappedValue_;
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a debug string-representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped in a SafeScript, use
|
||||
* {@code goog.html.SafeScript.unwrap}.
|
||||
*
|
||||
* @see goog.html.SafeScript#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeScript.prototype.toString = function() {
|
||||
return 'SafeScript{' +
|
||||
this.privateDoNotAccessOrElseSafeScriptWrappedValue_ + '}';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed a
|
||||
* SafeScript object, and returns its value.
|
||||
*
|
||||
* @param {!goog.html.SafeScript} safeScript The object to extract from.
|
||||
* @return {string} The safeScript object's contained string, unless
|
||||
* the run-time type check fails. In that case, {@code unwrap} returns an
|
||||
* innocuous string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.html.SafeScript.unwrap = function(safeScript) {
|
||||
// Perform additional Run-time type-checking to ensure that
|
||||
// safeScript is indeed an instance of the expected type. This
|
||||
// provides some additional protection against security bugs due to
|
||||
// application code that disables type checks.
|
||||
// Specifically, the following checks are performed:
|
||||
// 1. The object is an instance of the expected type.
|
||||
// 2. The object is not an instance of a subclass.
|
||||
// 3. The object carries a type marker for the expected type. "Faking" an
|
||||
// object requires a reference to the type marker, which has names intended
|
||||
// to stand out in code reviews.
|
||||
if (safeScript instanceof goog.html.SafeScript &&
|
||||
safeScript.constructor === goog.html.SafeScript &&
|
||||
safeScript.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===
|
||||
goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
|
||||
return safeScript.privateDoNotAccessOrElseSafeScriptWrappedValue_;
|
||||
} else {
|
||||
goog.asserts.fail('expected object of type SafeScript, got \'' +
|
||||
safeScript + '\' of type ' + goog.typeOf(safeScript));
|
||||
return 'type_error:SafeScript';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Package-internal utility method to create SafeScript instances.
|
||||
*
|
||||
* @param {string} script The string to initialize the SafeScript object with.
|
||||
* @return {!goog.html.SafeScript} The initialized SafeScript object.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse =
|
||||
function(script) {
|
||||
return new goog.html.SafeScript().initSecurityPrivateDoNotAccessOrElse_(
|
||||
script);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called from createSafeScriptSecurityPrivateDoNotAccessOrElse(). This
|
||||
* method exists only so that the compiler can dead code eliminate static
|
||||
* fields (like EMPTY) when they're not accessed.
|
||||
* @param {string} script
|
||||
* @return {!goog.html.SafeScript}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeScript.prototype.initSecurityPrivateDoNotAccessOrElse_ = function(
|
||||
script) {
|
||||
this.privateDoNotAccessOrElseSafeScriptWrappedValue_ = script;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A SafeScript instance corresponding to the empty string.
|
||||
* @const {!goog.html.SafeScript}
|
||||
*/
|
||||
goog.html.SafeScript.EMPTY =
|
||||
goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse('');
|
449
assets/viz/2/goog/html/safestyle.js
Normal file
449
assets/viz/2/goog/html/safestyle.js
Normal file
@ -0,0 +1,449 @@
|
||||
// Copyright 2014 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview The SafeStyle type and its builders.
|
||||
*
|
||||
* TODO(xtof): Link to document stating type contract.
|
||||
*/
|
||||
|
||||
goog.provide('goog.html.SafeStyle');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.Const');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A string-like object which represents a sequence of CSS declarations
|
||||
* ({@code propertyName1: propertyvalue1; propertyName2: propertyValue2; ...})
|
||||
* and that carries the security type contract that its value, as a string,
|
||||
* will not cause untrusted script execution (XSS) when evaluated as CSS in a
|
||||
* browser.
|
||||
*
|
||||
* Instances of this type must be created via the factory methods
|
||||
* ({@code goog.html.SafeStyle.create} or
|
||||
* {@code goog.html.SafeStyle.fromConstant}) and not by invoking its
|
||||
* constructor. The constructor intentionally takes no parameters and the type
|
||||
* is immutable; hence only a default instance corresponding to the empty string
|
||||
* can be obtained via constructor invocation.
|
||||
*
|
||||
* A SafeStyle's string representation ({@link #getTypedStringValue()}) can
|
||||
* safely:
|
||||
* <ul>
|
||||
* <li>Be interpolated as the entire content of a *quoted* HTML style
|
||||
* attribute, or before already existing properties. The SafeStyle string
|
||||
* *must be HTML-attribute-escaped* (where " and ' are escaped) before
|
||||
* interpolation.
|
||||
* <li>Be interpolated as the entire content of a {}-wrapped block within a
|
||||
* stylesheet, or before already existing properties. The SafeStyle string
|
||||
* should not be escaped before interpolation. SafeStyle's contract also
|
||||
* guarantees that the string will not be able to introduce new properties
|
||||
* or elide existing ones.
|
||||
* <li>Be assigned to the style property of a DOM node. The SafeStyle string
|
||||
* should not be escaped before being assigned to the property.
|
||||
* </ul>
|
||||
*
|
||||
* A SafeStyle may never contain literal angle brackets. Otherwise, it could
|
||||
* be unsafe to place a SafeStyle into a <style> tag (where it can't
|
||||
* be HTML escaped). For example, if the SafeStyle containing
|
||||
* "{@code font: 'foo <style/><script>evil</script>'}" were
|
||||
* interpolated within a <style> tag, this would then break out of the
|
||||
* style context into HTML.
|
||||
*
|
||||
* A SafeStyle may contain literal single or double quotes, and as such the
|
||||
* entire style string must be escaped when used in a style attribute (if
|
||||
* this were not the case, the string could contain a matching quote that
|
||||
* would escape from the style attribute).
|
||||
*
|
||||
* Values of this type must be composable, i.e. for any two values
|
||||
* {@code style1} and {@code style2} of this type,
|
||||
* {@code goog.html.SafeStyle.unwrap(style1) +
|
||||
* goog.html.SafeStyle.unwrap(style2)} must itself be a value that satisfies
|
||||
* the SafeStyle type constraint. This requirement implies that for any value
|
||||
* {@code style} of this type, {@code goog.html.SafeStyle.unwrap(style)} must
|
||||
* not end in a "property value" or "property name" context. For example,
|
||||
* a value of {@code background:url("} or {@code font-} would not satisfy the
|
||||
* SafeStyle contract. This is because concatenating such strings with a
|
||||
* second value that itself does not contain unsafe CSS can result in an
|
||||
* overall string that does. For example, if {@code javascript:evil())"} is
|
||||
* appended to {@code background:url("}, the resulting string may result in
|
||||
* the execution of a malicious script.
|
||||
*
|
||||
* TODO(user): Consider whether we should implement UTF-8 interchange
|
||||
* validity checks and blacklisting of newlines (including Unicode ones) and
|
||||
* other whitespace characters (\t, \f). Document here if so and also update
|
||||
* SafeStyle.fromConstant().
|
||||
*
|
||||
* The following example values comply with this type's contract:
|
||||
* <ul>
|
||||
* <li><pre>width: 1em;</pre>
|
||||
* <li><pre>height:1em;</pre>
|
||||
* <li><pre>width: 1em;height: 1em;</pre>
|
||||
* <li><pre>background:url('http://url');</pre>
|
||||
* </ul>
|
||||
* In addition, the empty string is safe for use in a CSS attribute.
|
||||
*
|
||||
* The following example values do NOT comply with this type's contract:
|
||||
* <ul>
|
||||
* <li><pre>background: red</pre> (missing a trailing semi-colon)
|
||||
* <li><pre>background:</pre> (missing a value and a trailing semi-colon)
|
||||
* <li><pre>1em</pre> (missing an attribute name, which provides context for
|
||||
* the value)
|
||||
* </ul>
|
||||
*
|
||||
* @see goog.html.SafeStyle#create
|
||||
* @see goog.html.SafeStyle#fromConstant
|
||||
* @see http://www.w3.org/TR/css3-syntax/
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.html.SafeStyle = function() {
|
||||
/**
|
||||
* The contained value of this SafeStyle. The field has a purposely
|
||||
* ugly name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.privateDoNotAccessOrElseSafeStyleWrappedValue_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.html.SafeStyle#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.SAFE_STYLE_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =
|
||||
goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeStyle.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the SafeStyle type, used to implement additional
|
||||
* run-time type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeStyle object from a compile-time constant string.
|
||||
*
|
||||
* {@code style} should be in the format
|
||||
* {@code name: value; [name: value; ...]} and must not have any < or >
|
||||
* characters in it. This is so that SafeStyle's contract is preserved,
|
||||
* allowing the SafeStyle to correctly be interpreted as a sequence of CSS
|
||||
* declarations and without affecting the syntactic structure of any
|
||||
* surrounding CSS and HTML.
|
||||
*
|
||||
* This method performs basic sanity checks on the format of {@code style}
|
||||
* but does not constrain the format of {@code name} and {@code value}, except
|
||||
* for disallowing tag characters.
|
||||
*
|
||||
* @param {!goog.string.Const} style A compile-time-constant string from which
|
||||
* to create a SafeStyle.
|
||||
* @return {!goog.html.SafeStyle} A SafeStyle object initialized to
|
||||
* {@code style}.
|
||||
*/
|
||||
goog.html.SafeStyle.fromConstant = function(style) {
|
||||
var styleString = goog.string.Const.unwrap(style);
|
||||
if (styleString.length === 0) {
|
||||
return goog.html.SafeStyle.EMPTY;
|
||||
}
|
||||
goog.html.SafeStyle.checkStyle_(styleString);
|
||||
goog.asserts.assert(
|
||||
goog.string.endsWith(styleString, ';'),
|
||||
'Last character of style string is not \';\': ' + styleString);
|
||||
goog.asserts.assert(
|
||||
goog.string.contains(styleString, ':'),
|
||||
'Style string must contain at least one \':\', to ' +
|
||||
'specify a "name: value" pair: ' + styleString);
|
||||
return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(
|
||||
styleString);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the style definition is valid.
|
||||
* @param {string} style
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyle.checkStyle_ = function(style) {
|
||||
goog.asserts.assert(
|
||||
!/[<>]/.test(style), 'Forbidden characters in style string: ' + style);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this SafeStyle's value as a string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security relevant that an object's type is
|
||||
* indeed {@code SafeStyle}, use {@code goog.html.SafeStyle.unwrap} instead of
|
||||
* this method. If in doubt, assume that it's security relevant. In particular,
|
||||
* note that goog.html functions which return a goog.html type do not guarantee
|
||||
* the returned instance is of the right type. For example:
|
||||
*
|
||||
* <pre>
|
||||
* var fakeSafeHtml = new String('fake');
|
||||
* fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;
|
||||
* var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);
|
||||
* // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by
|
||||
* // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml
|
||||
* // instanceof goog.html.SafeHtml.
|
||||
* </pre>
|
||||
*
|
||||
* @see goog.html.SafeStyle#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeStyle.prototype.getTypedStringValue = function() {
|
||||
return this.privateDoNotAccessOrElseSafeStyleWrappedValue_;
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a debug string-representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped in a SafeStyle, use
|
||||
* {@code goog.html.SafeStyle.unwrap}.
|
||||
*
|
||||
* @see goog.html.SafeStyle#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeStyle.prototype.toString = function() {
|
||||
return 'SafeStyle{' + this.privateDoNotAccessOrElseSafeStyleWrappedValue_ +
|
||||
'}';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed a
|
||||
* SafeStyle object, and returns its value.
|
||||
*
|
||||
* @param {!goog.html.SafeStyle} safeStyle The object to extract from.
|
||||
* @return {string} The safeStyle object's contained string, unless
|
||||
* the run-time type check fails. In that case, {@code unwrap} returns an
|
||||
* innocuous string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.html.SafeStyle.unwrap = function(safeStyle) {
|
||||
// Perform additional Run-time type-checking to ensure that
|
||||
// safeStyle is indeed an instance of the expected type. This
|
||||
// provides some additional protection against security bugs due to
|
||||
// application code that disables type checks.
|
||||
// Specifically, the following checks are performed:
|
||||
// 1. The object is an instance of the expected type.
|
||||
// 2. The object is not an instance of a subclass.
|
||||
// 3. The object carries a type marker for the expected type. "Faking" an
|
||||
// object requires a reference to the type marker, which has names intended
|
||||
// to stand out in code reviews.
|
||||
if (safeStyle instanceof goog.html.SafeStyle &&
|
||||
safeStyle.constructor === goog.html.SafeStyle &&
|
||||
safeStyle.SAFE_STYLE_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===
|
||||
goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
|
||||
return safeStyle.privateDoNotAccessOrElseSafeStyleWrappedValue_;
|
||||
} else {
|
||||
goog.asserts.fail('expected object of type SafeStyle, got \'' +
|
||||
safeStyle + '\' of type ' + goog.typeOf(safeStyle));
|
||||
return 'type_error:SafeStyle';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Package-internal utility method to create SafeStyle instances.
|
||||
*
|
||||
* @param {string} style The string to initialize the SafeStyle object with.
|
||||
* @return {!goog.html.SafeStyle} The initialized SafeStyle object.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse = function(
|
||||
style) {
|
||||
return new goog.html.SafeStyle().initSecurityPrivateDoNotAccessOrElse_(style);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called from createSafeStyleSecurityPrivateDoNotAccessOrElse(). This
|
||||
* method exists only so that the compiler can dead code eliminate static
|
||||
* fields (like EMPTY) when they're not accessed.
|
||||
* @param {string} style
|
||||
* @return {!goog.html.SafeStyle}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyle.prototype.initSecurityPrivateDoNotAccessOrElse_ = function(
|
||||
style) {
|
||||
this.privateDoNotAccessOrElseSafeStyleWrappedValue_ = style;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A SafeStyle instance corresponding to the empty string.
|
||||
* @const {!goog.html.SafeStyle}
|
||||
*/
|
||||
goog.html.SafeStyle.EMPTY =
|
||||
goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse('');
|
||||
|
||||
|
||||
/**
|
||||
* The innocuous string generated by goog.html.SafeUrl.create when passed
|
||||
* an unsafe value.
|
||||
* @const {string}
|
||||
*/
|
||||
goog.html.SafeStyle.INNOCUOUS_STRING = 'zClosurez';
|
||||
|
||||
|
||||
/**
|
||||
* Mapping of property names to their values.
|
||||
* @typedef {!Object<string, goog.string.Const|string>}
|
||||
*/
|
||||
goog.html.SafeStyle.PropertyMap;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new SafeStyle object from the properties specified in the map.
|
||||
* @param {goog.html.SafeStyle.PropertyMap} map Mapping of property names to
|
||||
* their values, for example {'margin': '1px'}. Names must consist of
|
||||
* [-_a-zA-Z0-9]. Values might be strings consisting of
|
||||
* [-,.'"%_!# a-zA-Z0-9], where " and ' must be properly balanced.
|
||||
* Other values must be wrapped in goog.string.Const. Null value causes
|
||||
* skipping the property.
|
||||
* @return {!goog.html.SafeStyle}
|
||||
* @throws {Error} If invalid name is provided.
|
||||
* @throws {goog.asserts.AssertionError} If invalid value is provided. With
|
||||
* disabled assertions, invalid value is replaced by
|
||||
* goog.html.SafeStyle.INNOCUOUS_STRING.
|
||||
*/
|
||||
goog.html.SafeStyle.create = function(map) {
|
||||
var style = '';
|
||||
for (var name in map) {
|
||||
if (!/^[-_a-zA-Z0-9]+$/.test(name)) {
|
||||
throw Error('Name allows only [-_a-zA-Z0-9], got: ' + name);
|
||||
}
|
||||
var value = map[name];
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
if (value instanceof goog.string.Const) {
|
||||
value = goog.string.Const.unwrap(value);
|
||||
// These characters can be used to change context and we don't want that
|
||||
// even with const values.
|
||||
goog.asserts.assert(!/[{;}]/.test(value), 'Value does not allow [{;}].');
|
||||
} else if (!goog.html.SafeStyle.VALUE_RE_.test(value)) {
|
||||
goog.asserts.fail(
|
||||
'String value allows only [-,."\'%_!# a-zA-Z0-9], rgb() and ' +
|
||||
'rgba(), got: ' + value);
|
||||
value = goog.html.SafeStyle.INNOCUOUS_STRING;
|
||||
} else if (!goog.html.SafeStyle.hasBalancedQuotes_(value)) {
|
||||
goog.asserts.fail('String value requires balanced quotes, got: ' + value);
|
||||
value = goog.html.SafeStyle.INNOCUOUS_STRING;
|
||||
}
|
||||
style += name + ':' + value + ';';
|
||||
}
|
||||
if (!style) {
|
||||
return goog.html.SafeStyle.EMPTY;
|
||||
}
|
||||
goog.html.SafeStyle.checkStyle_(style);
|
||||
return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(
|
||||
style);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks that quotes (" and ') are properly balanced inside a string. Assumes
|
||||
* that neither escape (\) nor any other character that could result in
|
||||
* breaking out of a string parsing context are allowed;
|
||||
* see http://www.w3.org/TR/css3-syntax/#string-token-diagram.
|
||||
* @param {string} value Untrusted CSS property value.
|
||||
* @return {boolean} True if property value is safe with respect to quote
|
||||
* balancedness.
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyle.hasBalancedQuotes_ = function(value) {
|
||||
var outsideSingle = true;
|
||||
var outsideDouble = true;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
var c = value.charAt(i);
|
||||
if (c == "'" && outsideDouble) {
|
||||
outsideSingle = !outsideSingle;
|
||||
} else if (c == '"' && outsideSingle) {
|
||||
outsideDouble = !outsideDouble;
|
||||
}
|
||||
}
|
||||
return outsideSingle && outsideDouble;
|
||||
};
|
||||
|
||||
|
||||
// Keep in sync with the error string in create().
|
||||
/**
|
||||
* Regular expression for safe values.
|
||||
*
|
||||
* Quotes (" and ') are allowed, but a check must be done elsewhere to ensure
|
||||
* they're balanced.
|
||||
*
|
||||
* ',' allows multiple values to be assigned to the same property
|
||||
* (e.g. background-attachment or font-family) and hence could allow
|
||||
* multiple values to get injected, but that should pose no risk of XSS.
|
||||
*
|
||||
* The rgb() and rgba() expression checks only for XSS safety, not for CSS
|
||||
* validity.
|
||||
* @const {!RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyle.VALUE_RE_ =
|
||||
/^([-,."'%_!# a-zA-Z0-9]+|(?:rgb|hsl)a?\([0-9.%, ]+\))$/;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new SafeStyle object by concatenating the values.
|
||||
* @param {...(!goog.html.SafeStyle|!Array<!goog.html.SafeStyle>)} var_args
|
||||
* SafeStyles to concatenate.
|
||||
* @return {!goog.html.SafeStyle}
|
||||
*/
|
||||
goog.html.SafeStyle.concat = function(var_args) {
|
||||
var style = '';
|
||||
|
||||
/**
|
||||
* @param {!goog.html.SafeStyle|!Array<!goog.html.SafeStyle>} argument
|
||||
*/
|
||||
var addArgument = function(argument) {
|
||||
if (goog.isArray(argument)) {
|
||||
goog.array.forEach(argument, addArgument);
|
||||
} else {
|
||||
style += goog.html.SafeStyle.unwrap(argument);
|
||||
}
|
||||
};
|
||||
|
||||
goog.array.forEach(arguments, addArgument);
|
||||
if (!style) {
|
||||
return goog.html.SafeStyle.EMPTY;
|
||||
}
|
||||
return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(
|
||||
style);
|
||||
};
|
278
assets/viz/2/goog/html/safestylesheet.js
Normal file
278
assets/viz/2/goog/html/safestylesheet.js
Normal file
@ -0,0 +1,278 @@
|
||||
// Copyright 2014 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview The SafeStyleSheet type and its builders.
|
||||
*
|
||||
* TODO(xtof): Link to document stating type contract.
|
||||
*/
|
||||
|
||||
goog.provide('goog.html.SafeStyleSheet');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.Const');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A string-like object which represents a CSS style sheet and that carries the
|
||||
* security type contract that its value, as a string, will not cause untrusted
|
||||
* script execution (XSS) when evaluated as CSS in a browser.
|
||||
*
|
||||
* Instances of this type must be created via the factory method
|
||||
* {@code goog.html.SafeStyleSheet.fromConstant} and not by invoking its
|
||||
* constructor. The constructor intentionally takes no parameters and the type
|
||||
* is immutable; hence only a default instance corresponding to the empty string
|
||||
* can be obtained via constructor invocation.
|
||||
*
|
||||
* A SafeStyleSheet's string representation can safely be interpolated as the
|
||||
* content of a style element within HTML. The SafeStyleSheet string should
|
||||
* not be escaped before interpolation.
|
||||
*
|
||||
* Values of this type must be composable, i.e. for any two values
|
||||
* {@code styleSheet1} and {@code styleSheet2} of this type,
|
||||
* {@code goog.html.SafeStyleSheet.unwrap(styleSheet1) +
|
||||
* goog.html.SafeStyleSheet.unwrap(styleSheet2)} must itself be a value that
|
||||
* satisfies the SafeStyleSheet type constraint. This requirement implies that
|
||||
* for any value {@code styleSheet} of this type,
|
||||
* {@code goog.html.SafeStyleSheet.unwrap(styleSheet1)} must end in
|
||||
* "beginning of rule" context.
|
||||
|
||||
* A SafeStyleSheet can be constructed via security-reviewed unchecked
|
||||
* conversions. In this case producers of SafeStyleSheet must ensure themselves
|
||||
* that the SafeStyleSheet does not contain unsafe script. Note in particular
|
||||
* that {@code <} is dangerous, even when inside CSS strings, and so should
|
||||
* always be forbidden or CSS-escaped in user controlled input. For example, if
|
||||
* {@code </style><script>evil</script>"} were interpolated
|
||||
* inside a CSS string, it would break out of the context of the original
|
||||
* style element and {@code evil} would execute. Also note that within an HTML
|
||||
* style (raw text) element, HTML character references, such as
|
||||
* {@code &lt;}, are not allowed. See
|
||||
*
|
||||
http://www.w3.org/TR/html5/scripting-1.html#restrictions-for-contents-of-script-elements
|
||||
* (similar considerations apply to the style element).
|
||||
*
|
||||
* @see goog.html.SafeStyleSheet#fromConstant
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.html.SafeStyleSheet = function() {
|
||||
/**
|
||||
* The contained value of this SafeStyleSheet. The field has a purposely
|
||||
* ugly name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.html.SafeStyleSheet#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.SAFE_STYLE_SHEET_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =
|
||||
goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeStyleSheet.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the SafeStyleSheet type, used to implement additional
|
||||
* run-time type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new SafeStyleSheet object by concatenating values.
|
||||
* @param {...(!goog.html.SafeStyleSheet|!Array<!goog.html.SafeStyleSheet>)}
|
||||
* var_args Values to concatenate.
|
||||
* @return {!goog.html.SafeStyleSheet}
|
||||
*/
|
||||
goog.html.SafeStyleSheet.concat = function(var_args) {
|
||||
var result = '';
|
||||
|
||||
/**
|
||||
* @param {!goog.html.SafeStyleSheet|!Array<!goog.html.SafeStyleSheet>}
|
||||
* argument
|
||||
*/
|
||||
var addArgument = function(argument) {
|
||||
if (goog.isArray(argument)) {
|
||||
goog.array.forEach(argument, addArgument);
|
||||
} else {
|
||||
result += goog.html.SafeStyleSheet.unwrap(argument);
|
||||
}
|
||||
};
|
||||
|
||||
goog.array.forEach(arguments, addArgument);
|
||||
return goog.html.SafeStyleSheet
|
||||
.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(result);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeStyleSheet object from a compile-time constant string.
|
||||
*
|
||||
* {@code styleSheet} must not have any < characters in it, so that
|
||||
* the syntactic structure of the surrounding HTML is not affected.
|
||||
*
|
||||
* @param {!goog.string.Const} styleSheet A compile-time-constant string from
|
||||
* which to create a SafeStyleSheet.
|
||||
* @return {!goog.html.SafeStyleSheet} A SafeStyleSheet object initialized to
|
||||
* {@code styleSheet}.
|
||||
*/
|
||||
goog.html.SafeStyleSheet.fromConstant = function(styleSheet) {
|
||||
var styleSheetString = goog.string.Const.unwrap(styleSheet);
|
||||
if (styleSheetString.length === 0) {
|
||||
return goog.html.SafeStyleSheet.EMPTY;
|
||||
}
|
||||
// > is a valid character in CSS selectors and there's no strict need to
|
||||
// block it if we already block <.
|
||||
goog.asserts.assert(
|
||||
!goog.string.contains(styleSheetString, '<'),
|
||||
"Forbidden '<' character in style sheet string: " + styleSheetString);
|
||||
return goog.html.SafeStyleSheet
|
||||
.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheetString);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this SafeStyleSheet's value as a string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security relevant that an object's type is
|
||||
* indeed {@code SafeStyleSheet}, use {@code goog.html.SafeStyleSheet.unwrap}
|
||||
* instead of this method. If in doubt, assume that it's security relevant. In
|
||||
* particular, note that goog.html functions which return a goog.html type do
|
||||
* not guarantee the returned instance is of the right type. For example:
|
||||
*
|
||||
* <pre>
|
||||
* var fakeSafeHtml = new String('fake');
|
||||
* fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;
|
||||
* var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);
|
||||
* // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by
|
||||
* // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml
|
||||
* // instanceof goog.html.SafeHtml.
|
||||
* </pre>
|
||||
*
|
||||
* @see goog.html.SafeStyleSheet#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeStyleSheet.prototype.getTypedStringValue = function() {
|
||||
return this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_;
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a debug string-representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped in a SafeStyleSheet, use
|
||||
* {@code goog.html.SafeStyleSheet.unwrap}.
|
||||
*
|
||||
* @see goog.html.SafeStyleSheet#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeStyleSheet.prototype.toString = function() {
|
||||
return 'SafeStyleSheet{' +
|
||||
this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_ + '}';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed a
|
||||
* SafeStyleSheet object, and returns its value.
|
||||
*
|
||||
* @param {!goog.html.SafeStyleSheet} safeStyleSheet The object to extract from.
|
||||
* @return {string} The safeStyleSheet object's contained string, unless
|
||||
* the run-time type check fails. In that case, {@code unwrap} returns an
|
||||
* innocuous string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.html.SafeStyleSheet.unwrap = function(safeStyleSheet) {
|
||||
// Perform additional Run-time type-checking to ensure that
|
||||
// safeStyleSheet is indeed an instance of the expected type. This
|
||||
// provides some additional protection against security bugs due to
|
||||
// application code that disables type checks.
|
||||
// Specifically, the following checks are performed:
|
||||
// 1. The object is an instance of the expected type.
|
||||
// 2. The object is not an instance of a subclass.
|
||||
// 3. The object carries a type marker for the expected type. "Faking" an
|
||||
// object requires a reference to the type marker, which has names intended
|
||||
// to stand out in code reviews.
|
||||
if (safeStyleSheet instanceof goog.html.SafeStyleSheet &&
|
||||
safeStyleSheet.constructor === goog.html.SafeStyleSheet &&
|
||||
safeStyleSheet
|
||||
.SAFE_STYLE_SHEET_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===
|
||||
goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
|
||||
return safeStyleSheet.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_;
|
||||
} else {
|
||||
goog.asserts.fail('expected object of type SafeStyleSheet, got \'' +
|
||||
safeStyleSheet + '\' of type ' + goog.typeOf(safeStyleSheet));
|
||||
return 'type_error:SafeStyleSheet';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Package-internal utility method to create SafeStyleSheet instances.
|
||||
*
|
||||
* @param {string} styleSheet The string to initialize the SafeStyleSheet
|
||||
* object with.
|
||||
* @return {!goog.html.SafeStyleSheet} The initialized SafeStyleSheet object.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse =
|
||||
function(styleSheet) {
|
||||
return new goog.html.SafeStyleSheet().initSecurityPrivateDoNotAccessOrElse_(
|
||||
styleSheet);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called from createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(). This
|
||||
* method exists only so that the compiler can dead code eliminate static
|
||||
* fields (like EMPTY) when they're not accessed.
|
||||
* @param {string} styleSheet
|
||||
* @return {!goog.html.SafeStyleSheet}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyleSheet.prototype.initSecurityPrivateDoNotAccessOrElse_ =
|
||||
function(styleSheet) {
|
||||
this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_ = styleSheet;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A SafeStyleSheet instance corresponding to the empty string.
|
||||
* @const {!goog.html.SafeStyleSheet}
|
||||
*/
|
||||
goog.html.SafeStyleSheet.EMPTY =
|
||||
goog.html.SafeStyleSheet
|
||||
.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse('');
|
412
assets/viz/2/goog/html/safeurl.js
Normal file
412
assets/viz/2/goog/html/safeurl.js
Normal file
@ -0,0 +1,412 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview The SafeUrl type and its builders.
|
||||
*
|
||||
* TODO(xtof): Link to document stating type contract.
|
||||
*/
|
||||
|
||||
goog.provide('goog.html.SafeUrl');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.fs.url');
|
||||
goog.require('goog.i18n.bidi.Dir');
|
||||
goog.require('goog.i18n.bidi.DirectionalString');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.Const');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A string that is safe to use in URL context in DOM APIs and HTML documents.
|
||||
*
|
||||
* A SafeUrl is a string-like object that carries the security type contract
|
||||
* that its value as a string will not cause untrusted script execution
|
||||
* when evaluated as a hyperlink URL in a browser.
|
||||
*
|
||||
* Values of this type are guaranteed to be safe to use in URL/hyperlink
|
||||
* contexts, such as, assignment to URL-valued DOM properties, or
|
||||
* interpolation into a HTML template in URL context (e.g., inside a href
|
||||
* attribute), in the sense that the use will not result in a
|
||||
* Cross-Site-Scripting vulnerability.
|
||||
*
|
||||
* Note that, as documented in {@code goog.html.SafeUrl.unwrap}, this type's
|
||||
* contract does not guarantee that instances are safe to interpolate into HTML
|
||||
* without appropriate escaping.
|
||||
*
|
||||
* Note also that this type's contract does not imply any guarantees regarding
|
||||
* the resource the URL refers to. In particular, SafeUrls are <b>not</b>
|
||||
* safe to use in a context where the referred-to resource is interpreted as
|
||||
* trusted code, e.g., as the src of a script tag.
|
||||
*
|
||||
* Instances of this type must be created via the factory methods
|
||||
* ({@code goog.html.SafeUrl.fromConstant}, {@code goog.html.SafeUrl.sanitize}),
|
||||
* etc and not by invoking its constructor. The constructor intentionally
|
||||
* takes no parameters and the type is immutable; hence only a default instance
|
||||
* corresponding to the empty string can be obtained via constructor invocation.
|
||||
*
|
||||
* @see goog.html.SafeUrl#fromConstant
|
||||
* @see goog.html.SafeUrl#from
|
||||
* @see goog.html.SafeUrl#sanitize
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.i18n.bidi.DirectionalString}
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.html.SafeUrl = function() {
|
||||
/**
|
||||
* The contained value of this SafeUrl. The field has a purposely ugly
|
||||
* name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.html.SafeUrl#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =
|
||||
goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The innocuous string generated by goog.html.SafeUrl.sanitize when passed
|
||||
* an unsafe URL.
|
||||
*
|
||||
* about:invalid is registered in
|
||||
* http://www.w3.org/TR/css3-values/#about-invalid.
|
||||
* http://tools.ietf.org/html/rfc6694#section-2.2.1 permits about URLs to
|
||||
* contain a fragment, which is not to be considered when determining if an
|
||||
* about URL is well-known.
|
||||
*
|
||||
* Using about:invalid seems preferable to using a fixed data URL, since
|
||||
* browsers might choose to not report CSP violations on it, as legitimate
|
||||
* CSS function calls to attr() can result in this URL being produced. It is
|
||||
* also a standard URL which matches exactly the semantics we need:
|
||||
* "The about:invalid URI references a non-existent document with a generic
|
||||
* error condition. It can be used when a URI is necessary, but the default
|
||||
* value shouldn't be resolveable as any type of document".
|
||||
*
|
||||
* @const {string}
|
||||
*/
|
||||
goog.html.SafeUrl.INNOCUOUS_STRING = 'about:invalid#zClosurez';
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeUrl.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Returns this SafeUrl's value a string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security relevant that an object's type is
|
||||
* indeed {@code SafeUrl}, use {@code goog.html.SafeUrl.unwrap} instead of this
|
||||
* method. If in doubt, assume that it's security relevant. In particular, note
|
||||
* that goog.html functions which return a goog.html type do not guarantee that
|
||||
* the returned instance is of the right type. For example:
|
||||
*
|
||||
* <pre>
|
||||
* var fakeSafeHtml = new String('fake');
|
||||
* fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;
|
||||
* var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);
|
||||
* // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by
|
||||
* // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml instanceof
|
||||
* // goog.html.SafeHtml.
|
||||
* </pre>
|
||||
*
|
||||
* IMPORTANT: The guarantees of the SafeUrl type contract only extend to the
|
||||
* behavior of browsers when interpreting URLs. Values of SafeUrl objects MUST
|
||||
* be appropriately escaped before embedding in a HTML document. Note that the
|
||||
* required escaping is context-sensitive (e.g. a different escaping is
|
||||
* required for embedding a URL in a style property within a style
|
||||
* attribute, as opposed to embedding in a href attribute).
|
||||
*
|
||||
* @see goog.html.SafeUrl#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeUrl.prototype.getTypedStringValue = function() {
|
||||
return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeUrl.prototype.implementsGoogI18nBidiDirectionalString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Returns this URLs directionality, which is always {@code LTR}.
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeUrl.prototype.getDirection = function() {
|
||||
return goog.i18n.bidi.Dir.LTR;
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a debug string-representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped in a SafeUrl, use
|
||||
* {@code goog.html.SafeUrl.unwrap}.
|
||||
*
|
||||
* @see goog.html.SafeUrl#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeUrl.prototype.toString = function() {
|
||||
return 'SafeUrl{' + this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ +
|
||||
'}';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed a SafeUrl
|
||||
* object, and returns its value.
|
||||
*
|
||||
* IMPORTANT: The guarantees of the SafeUrl type contract only extend to the
|
||||
* behavior of browsers when interpreting URLs. Values of SafeUrl objects MUST
|
||||
* be appropriately escaped before embedding in a HTML document. Note that the
|
||||
* required escaping is context-sensitive (e.g. a different escaping is
|
||||
* required for embedding a URL in a style property within a style
|
||||
* attribute, as opposed to embedding in a href attribute).
|
||||
*
|
||||
* @param {!goog.html.SafeUrl} safeUrl The object to extract from.
|
||||
* @return {string} The SafeUrl object's contained string, unless the run-time
|
||||
* type check fails. In that case, {@code unwrap} returns an innocuous
|
||||
* string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.html.SafeUrl.unwrap = function(safeUrl) {
|
||||
// Perform additional Run-time type-checking to ensure that safeUrl is indeed
|
||||
// an instance of the expected type. This provides some additional protection
|
||||
// against security bugs due to application code that disables type checks.
|
||||
// Specifically, the following checks are performed:
|
||||
// 1. The object is an instance of the expected type.
|
||||
// 2. The object is not an instance of a subclass.
|
||||
// 3. The object carries a type marker for the expected type. "Faking" an
|
||||
// object requires a reference to the type marker, which has names intended
|
||||
// to stand out in code reviews.
|
||||
if (safeUrl instanceof goog.html.SafeUrl &&
|
||||
safeUrl.constructor === goog.html.SafeUrl &&
|
||||
safeUrl.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===
|
||||
goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
|
||||
return safeUrl.privateDoNotAccessOrElseSafeHtmlWrappedValue_;
|
||||
} else {
|
||||
goog.asserts.fail('expected object of type SafeUrl, got \'' +
|
||||
safeUrl + '\' of type ' + goog.typeOf(safeUrl));
|
||||
return 'type_error:SafeUrl';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeUrl object from a compile-time constant string.
|
||||
*
|
||||
* Compile-time constant strings are inherently program-controlled and hence
|
||||
* trusted.
|
||||
*
|
||||
* @param {!goog.string.Const} url A compile-time-constant string from which to
|
||||
* create a SafeUrl.
|
||||
* @return {!goog.html.SafeUrl} A SafeUrl object initialized to {@code url}.
|
||||
*/
|
||||
goog.html.SafeUrl.fromConstant = function(url) {
|
||||
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(
|
||||
goog.string.Const.unwrap(url));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A pattern that matches Blob or data types that can have SafeUrls created
|
||||
* from URL.createObjectURL(blob) or via a data: URI. Only matches image and
|
||||
* video types, currently.
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
goog.html.SAFE_MIME_TYPE_PATTERN_ =
|
||||
/^(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm))$/i;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeUrl wrapping a blob URL for the given {@code blob}.
|
||||
*
|
||||
* The blob URL is created with {@code URL.createObjectURL}. If the MIME type
|
||||
* for {@code blob} is not of a known safe image or video MIME type, then the
|
||||
* SafeUrl will wrap {@link #INNOCUOUS_STRING}.
|
||||
*
|
||||
* @see http://www.w3.org/TR/FileAPI/#url
|
||||
* @param {!Blob} blob
|
||||
* @return {!goog.html.SafeUrl} The blob URL, or an innocuous string wrapped
|
||||
* as a SafeUrl.
|
||||
*/
|
||||
goog.html.SafeUrl.fromBlob = function(blob) {
|
||||
var url = goog.html.SAFE_MIME_TYPE_PATTERN_.test(blob.type) ?
|
||||
goog.fs.url.createObjectUrl(blob) :
|
||||
goog.html.SafeUrl.INNOCUOUS_STRING;
|
||||
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Matches a base-64 data URL, with the first match group being the MIME type.
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
goog.html.DATA_URL_PATTERN_ = /^data:([^;,]*);base64,[a-z0-9+\/]+=*$/i;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeUrl wrapping a data: URL, after validating it matches a
|
||||
* known-safe image or video MIME type.
|
||||
*
|
||||
* @param {string} dataUrl A valid base64 data URL with one of the whitelisted
|
||||
* image or video MIME types.
|
||||
* @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}
|
||||
* wrapped as a SafeUrl if it does not pass.
|
||||
*/
|
||||
goog.html.SafeUrl.fromDataUrl = function(dataUrl) {
|
||||
// There's a slight risk here that a browser sniffs the content type if it
|
||||
// doesn't know the MIME type and executes HTML within the data: URL. For this
|
||||
// to cause XSS it would also have to execute the HTML in the same origin
|
||||
// of the page with the link. It seems unlikely that both of these will
|
||||
// happen, particularly in not really old IEs.
|
||||
var match = dataUrl.match(goog.html.DATA_URL_PATTERN_);
|
||||
var valid = match && goog.html.SAFE_MIME_TYPE_PATTERN_.test(match[1]);
|
||||
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(
|
||||
valid ? dataUrl : goog.html.SafeUrl.INNOCUOUS_STRING);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeUrl wrapping a tel: URL.
|
||||
*
|
||||
* @param {string} telUrl A tel URL.
|
||||
* @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}
|
||||
* wrapped as a SafeUrl if it does not pass.
|
||||
*/
|
||||
goog.html.SafeUrl.fromTelUrl = function(telUrl) {
|
||||
// There's a risk that a tel: URL could immediately place a call once
|
||||
// clicked, without requiring user confirmation. For that reason it is
|
||||
// handled in this separate function.
|
||||
if (!goog.string.caseInsensitiveStartsWith(telUrl, 'tel:')) {
|
||||
telUrl = goog.html.SafeUrl.INNOCUOUS_STRING;
|
||||
}
|
||||
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(
|
||||
telUrl);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A pattern that recognizes a commonly useful subset of URLs that satisfy
|
||||
* the SafeUrl contract.
|
||||
*
|
||||
* This regular expression matches a subset of URLs that will not cause script
|
||||
* execution if used in URL context within a HTML document. Specifically, this
|
||||
* regular expression matches if (comment from here on and regex copied from
|
||||
* Soy's EscapingConventions):
|
||||
* (1) Either a protocol in a whitelist (http, https, mailto or ftp).
|
||||
* (2) or no protocol. A protocol must be followed by a colon. The below
|
||||
* allows that by allowing colons only after one of the characters [/?#].
|
||||
* A colon after a hash (#) must be in the fragment.
|
||||
* Otherwise, a colon after a (?) must be in a query.
|
||||
* Otherwise, a colon after a single solidus (/) must be in a path.
|
||||
* Otherwise, a colon after a double solidus (//) must be in the authority
|
||||
* (before port).
|
||||
*
|
||||
* The pattern disallows &, used in HTML entity declarations before
|
||||
* one of the characters in [/?#]. This disallows HTML entities used in the
|
||||
* protocol name, which should never happen, e.g. "http" for "http".
|
||||
* It also disallows HTML entities in the first path part of a relative path,
|
||||
* e.g. "foo<bar/baz". Our existing escaping functions should not produce
|
||||
* that. More importantly, it disallows masking of a colon,
|
||||
* e.g. "javascript:...".
|
||||
*
|
||||
* @private
|
||||
* @const {!RegExp}
|
||||
*/
|
||||
goog.html.SAFE_URL_PATTERN_ =
|
||||
/^(?:(?:https?|mailto|ftp):|[^&:/?#]*(?:[/?#]|$))/i;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeUrl object from {@code url}. If {@code url} is a
|
||||
* goog.html.SafeUrl then it is simply returned. Otherwise the input string is
|
||||
* validated to match a pattern of commonly used safe URLs.
|
||||
*
|
||||
* {@code url} may be a URL with the http, https, mailto or ftp scheme,
|
||||
* or a relative URL (i.e., a URL without a scheme; specifically, a
|
||||
* scheme-relative, absolute-path-relative, or path-relative URL).
|
||||
*
|
||||
* @see http://url.spec.whatwg.org/#concept-relative-url
|
||||
* @param {string|!goog.string.TypedString} url The URL to validate.
|
||||
* @return {!goog.html.SafeUrl} The validated URL, wrapped as a SafeUrl.
|
||||
*/
|
||||
goog.html.SafeUrl.sanitize = function(url) {
|
||||
if (url instanceof goog.html.SafeUrl) {
|
||||
return url;
|
||||
} else if (url.implementsGoogStringTypedString) {
|
||||
url = url.getTypedStringValue();
|
||||
} else {
|
||||
url = String(url);
|
||||
}
|
||||
if (!goog.html.SAFE_URL_PATTERN_.test(url)) {
|
||||
url = goog.html.SafeUrl.INNOCUOUS_STRING;
|
||||
}
|
||||
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the SafeUrl type, used to implement additional run-time
|
||||
* type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Package-internal utility method to create SafeUrl instances.
|
||||
*
|
||||
* @param {string} url The string to initialize the SafeUrl object with.
|
||||
* @return {!goog.html.SafeUrl} The initialized SafeUrl object.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse = function(
|
||||
url) {
|
||||
var safeUrl = new goog.html.SafeUrl();
|
||||
safeUrl.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = url;
|
||||
return safeUrl;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A SafeUrl corresponding to the special about:blank url.
|
||||
* @const {!goog.html.SafeUrl}
|
||||
*/
|
||||
goog.html.SafeUrl.ABOUT_BLANK =
|
||||
goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(
|
||||
'about:blank');
|
244
assets/viz/2/goog/html/trustedresourceurl.js
Normal file
244
assets/viz/2/goog/html/trustedresourceurl.js
Normal file
@ -0,0 +1,244 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview The TrustedResourceUrl type and its builders.
|
||||
*
|
||||
* TODO(xtof): Link to document stating type contract.
|
||||
*/
|
||||
|
||||
goog.provide('goog.html.TrustedResourceUrl');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.i18n.bidi.Dir');
|
||||
goog.require('goog.i18n.bidi.DirectionalString');
|
||||
goog.require('goog.string.Const');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A URL which is under application control and from which script, CSS, and
|
||||
* other resources that represent executable code, can be fetched.
|
||||
*
|
||||
* Given that the URL can only be constructed from strings under application
|
||||
* control and is used to load resources, bugs resulting in a malformed URL
|
||||
* should not have a security impact and are likely to be easily detectable
|
||||
* during testing. Given the wide number of non-RFC compliant URLs in use,
|
||||
* stricter validation could prevent some applications from being able to use
|
||||
* this type.
|
||||
*
|
||||
* Instances of this type must be created via the factory method,
|
||||
* ({@code goog.html.TrustedResourceUrl.fromConstant}), and not by invoking its
|
||||
* constructor. The constructor intentionally takes no parameters and the type
|
||||
* is immutable; hence only a default instance corresponding to the empty
|
||||
* string can be obtained via constructor invocation.
|
||||
*
|
||||
* @see goog.html.TrustedResourceUrl#fromConstant
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.i18n.bidi.DirectionalString}
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.html.TrustedResourceUrl = function() {
|
||||
/**
|
||||
* The contained value of this TrustedResourceUrl. The field has a purposely
|
||||
* ugly name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.html.TrustedResourceUrl#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =
|
||||
goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Returns this TrustedResourceUrl's value as a string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security relevant that an object's type is
|
||||
* indeed {@code TrustedResourceUrl}, use
|
||||
* {@code goog.html.TrustedResourceUrl.unwrap} instead of this method. If in
|
||||
* doubt, assume that it's security relevant. In particular, note that
|
||||
* goog.html functions which return a goog.html type do not guarantee that
|
||||
* the returned instance is of the right type. For example:
|
||||
*
|
||||
* <pre>
|
||||
* var fakeSafeHtml = new String('fake');
|
||||
* fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;
|
||||
* var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);
|
||||
* // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by
|
||||
* // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml instanceof
|
||||
* // goog.html.SafeHtml.
|
||||
* </pre>
|
||||
*
|
||||
* @see goog.html.TrustedResourceUrl#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.prototype.getTypedStringValue = function() {
|
||||
return this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.prototype.implementsGoogI18nBidiDirectionalString =
|
||||
true;
|
||||
|
||||
|
||||
/**
|
||||
* Returns this URLs directionality, which is always {@code LTR}.
|
||||
* @override
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.prototype.getDirection = function() {
|
||||
return goog.i18n.bidi.Dir.LTR;
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a debug string-representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped in a TrustedResourceUrl, use
|
||||
* {@code goog.html.TrustedResourceUrl.unwrap}.
|
||||
*
|
||||
* @see goog.html.TrustedResourceUrl#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.prototype.toString = function() {
|
||||
return 'TrustedResourceUrl{' +
|
||||
this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ + '}';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed a
|
||||
* TrustedResourceUrl object, and returns its value.
|
||||
*
|
||||
* @param {!goog.html.TrustedResourceUrl} trustedResourceUrl The object to
|
||||
* extract from.
|
||||
* @return {string} The trustedResourceUrl object's contained string, unless
|
||||
* the run-time type check fails. In that case, {@code unwrap} returns an
|
||||
* innocuous string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.unwrap = function(trustedResourceUrl) {
|
||||
// Perform additional Run-time type-checking to ensure that
|
||||
// trustedResourceUrl is indeed an instance of the expected type. This
|
||||
// provides some additional protection against security bugs due to
|
||||
// application code that disables type checks.
|
||||
// Specifically, the following checks are performed:
|
||||
// 1. The object is an instance of the expected type.
|
||||
// 2. The object is not an instance of a subclass.
|
||||
// 3. The object carries a type marker for the expected type. "Faking" an
|
||||
// object requires a reference to the type marker, which has names intended
|
||||
// to stand out in code reviews.
|
||||
if (trustedResourceUrl instanceof goog.html.TrustedResourceUrl &&
|
||||
trustedResourceUrl.constructor === goog.html.TrustedResourceUrl &&
|
||||
trustedResourceUrl
|
||||
.TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===
|
||||
goog.html.TrustedResourceUrl
|
||||
.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
|
||||
return trustedResourceUrl
|
||||
.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_;
|
||||
} else {
|
||||
goog.asserts.fail('expected object of type TrustedResourceUrl, got \'' +
|
||||
trustedResourceUrl + '\' of type ' + goog.typeOf(trustedResourceUrl));
|
||||
return 'type_error:TrustedResourceUrl';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a TrustedResourceUrl object from a compile-time constant string.
|
||||
*
|
||||
* Compile-time constant strings are inherently program-controlled and hence
|
||||
* trusted.
|
||||
*
|
||||
* @param {!goog.string.Const} url A compile-time-constant string from which to
|
||||
* create a TrustedResourceUrl.
|
||||
* @return {!goog.html.TrustedResourceUrl} A TrustedResourceUrl object
|
||||
* initialized to {@code url}.
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.fromConstant = function(url) {
|
||||
return goog.html.TrustedResourceUrl
|
||||
.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(
|
||||
goog.string.Const.unwrap(url));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a TrustedResourceUrl object from a compile-time constant strings.
|
||||
*
|
||||
* Compile-time constant strings are inherently program-controlled and hence
|
||||
* trusted.
|
||||
*
|
||||
* @param {!Array<!goog.string.Const>} parts Compile-time-constant strings from
|
||||
* which to create a TrustedResourceUrl.
|
||||
* @return {!goog.html.TrustedResourceUrl} A TrustedResourceUrl object
|
||||
* initialized to concatenation of {@code parts}.
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.fromConstants = function(parts) {
|
||||
var unwrapped = '';
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
unwrapped += goog.string.Const.unwrap(parts[i]);
|
||||
}
|
||||
return goog.html.TrustedResourceUrl
|
||||
.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(unwrapped);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the TrustedResourceUrl type, used to implement additional
|
||||
* run-time type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Package-internal utility method to create TrustedResourceUrl instances.
|
||||
*
|
||||
* @param {string} url The string to initialize the TrustedResourceUrl object
|
||||
* with.
|
||||
* @return {!goog.html.TrustedResourceUrl} The initialized TrustedResourceUrl
|
||||
* object.
|
||||
* @package
|
||||
*/
|
||||
goog.html.TrustedResourceUrl
|
||||
.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse = function(url) {
|
||||
var trustedResourceUrl = new goog.html.TrustedResourceUrl();
|
||||
trustedResourceUrl.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ =
|
||||
url;
|
||||
return trustedResourceUrl;
|
||||
};
|
232
assets/viz/2/goog/html/uncheckedconversions.js
Normal file
232
assets/viz/2/goog/html/uncheckedconversions.js
Normal file
@ -0,0 +1,232 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Unchecked conversions to create values of goog.html types from
|
||||
* plain strings. Use of these functions could potentially result in instances
|
||||
* of goog.html types that violate their type contracts, and hence result in
|
||||
* security vulnerabilties.
|
||||
*
|
||||
* Therefore, all uses of the methods herein must be carefully security
|
||||
* reviewed. Avoid use of the methods in this file whenever possible; instead
|
||||
* prefer to create instances of goog.html types using inherently safe builders
|
||||
* or template systems.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @visibility {//closure/goog/html:approved_for_unchecked_conversion}
|
||||
* @visibility {//closure/goog/bin/sizetests:__pkg__}
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.html.uncheckedconversions');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.html.SafeHtml');
|
||||
goog.require('goog.html.SafeScript');
|
||||
goog.require('goog.html.SafeStyle');
|
||||
goog.require('goog.html.SafeStyleSheet');
|
||||
goog.require('goog.html.SafeUrl');
|
||||
goog.require('goog.html.TrustedResourceUrl');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.Const');
|
||||
|
||||
|
||||
/**
|
||||
* Performs an "unchecked conversion" to SafeHtml from a plain string that is
|
||||
* known to satisfy the SafeHtml type contract.
|
||||
*
|
||||
* IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
|
||||
* that the value of {@code html} satisfies the SafeHtml type contract in all
|
||||
* possible program states.
|
||||
*
|
||||
*
|
||||
* @param {!goog.string.Const} justification A constant string explaining why
|
||||
* this use of this method is safe. May include a security review ticket
|
||||
* number.
|
||||
* @param {string} html A string that is claimed to adhere to the SafeHtml
|
||||
* contract.
|
||||
* @param {?goog.i18n.bidi.Dir=} opt_dir The optional directionality of the
|
||||
* SafeHtml to be constructed. A null or undefined value signifies an
|
||||
* unknown directionality.
|
||||
* @return {!goog.html.SafeHtml} The value of html, wrapped in a SafeHtml
|
||||
* object.
|
||||
* @suppress {visibility} For access to SafeHtml.create... Note that this
|
||||
* use is appropriate since this method is intended to be "package private"
|
||||
* within goog.html. DO NOT call SafeHtml.create... from outside this
|
||||
* package; use appropriate wrappers instead.
|
||||
*/
|
||||
goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract =
|
||||
function(justification, html, opt_dir) {
|
||||
// unwrap() called inside an assert so that justification can be optimized
|
||||
// away in production code.
|
||||
goog.asserts.assertString(
|
||||
goog.string.Const.unwrap(justification), 'must provide justification');
|
||||
goog.asserts.assert(
|
||||
!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
|
||||
'must provide non-empty justification');
|
||||
return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
html, opt_dir || null);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs an "unchecked conversion" to SafeScript from a plain string that is
|
||||
* known to satisfy the SafeScript type contract.
|
||||
*
|
||||
* IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
|
||||
* that the value of {@code script} satisfies the SafeScript type contract in
|
||||
* all possible program states.
|
||||
*
|
||||
*
|
||||
* @param {!goog.string.Const} justification A constant string explaining why
|
||||
* this use of this method is safe. May include a security review ticket
|
||||
* number.
|
||||
* @param {string} script The string to wrap as a SafeScript.
|
||||
* @return {!goog.html.SafeScript} The value of {@code script}, wrapped in a
|
||||
* SafeScript object.
|
||||
*/
|
||||
goog.html.uncheckedconversions.safeScriptFromStringKnownToSatisfyTypeContract =
|
||||
function(justification, script) {
|
||||
// unwrap() called inside an assert so that justification can be optimized
|
||||
// away in production code.
|
||||
goog.asserts.assertString(
|
||||
goog.string.Const.unwrap(justification), 'must provide justification');
|
||||
goog.asserts.assert(
|
||||
!goog.string.isEmpty(goog.string.Const.unwrap(justification)),
|
||||
'must provide non-empty justification');
|
||||
return goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse(
|
||||
script);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs an "unchecked conversion" to SafeStyle from a plain string that is
|
||||
* known to satisfy the SafeStyle type contract.
|
||||
*
|
||||
* IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
|
||||
* that the value of {@code style} satisfies the SafeUrl type contract in all
|
||||
* possible program states.
|
||||
*
|
||||
*
|
||||
* @param {!goog.string.Const} justification A constant string explaining why
|
||||
* this use of this method is safe. May include a security review ticket
|
||||
* number.
|
||||
* @param {string} style The string to wrap as a SafeStyle.
|
||||
* @return {!goog.html.SafeStyle} The value of {@code style}, wrapped in a
|
||||
* SafeStyle object.
|
||||
*/
|
||||
goog.html.uncheckedconversions.safeStyleFromStringKnownToSatisfyTypeContract =
|
||||
function(justification, style) {
|
||||
// unwrap() called inside an assert so that justification can be optimized
|
||||
// away in production code.
|
||||
goog.asserts.assertString(
|
||||
goog.string.Const.unwrap(justification), 'must provide justification');
|
||||
goog.asserts.assert(
|
||||
!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
|
||||
'must provide non-empty justification');
|
||||
return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(
|
||||
style);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs an "unchecked conversion" to SafeStyleSheet from a plain string
|
||||
* that is known to satisfy the SafeStyleSheet type contract.
|
||||
*
|
||||
* IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
|
||||
* that the value of {@code styleSheet} satisfies the SafeUrl type contract in
|
||||
* all possible program states.
|
||||
*
|
||||
*
|
||||
* @param {!goog.string.Const} justification A constant string explaining why
|
||||
* this use of this method is safe. May include a security review ticket
|
||||
* number.
|
||||
* @param {string} styleSheet The string to wrap as a SafeStyleSheet.
|
||||
* @return {!goog.html.SafeStyleSheet} The value of {@code styleSheet}, wrapped
|
||||
* in a SafeStyleSheet object.
|
||||
*/
|
||||
goog.html.uncheckedconversions
|
||||
.safeStyleSheetFromStringKnownToSatisfyTypeContract = function(
|
||||
justification, styleSheet) {
|
||||
// unwrap() called inside an assert so that justification can be optimized
|
||||
// away in production code.
|
||||
goog.asserts.assertString(
|
||||
goog.string.Const.unwrap(justification), 'must provide justification');
|
||||
goog.asserts.assert(
|
||||
!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
|
||||
'must provide non-empty justification');
|
||||
return goog.html.SafeStyleSheet
|
||||
.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheet);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs an "unchecked conversion" to SafeUrl from a plain string that is
|
||||
* known to satisfy the SafeUrl type contract.
|
||||
*
|
||||
* IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
|
||||
* that the value of {@code url} satisfies the SafeUrl type contract in all
|
||||
* possible program states.
|
||||
*
|
||||
*
|
||||
* @param {!goog.string.Const} justification A constant string explaining why
|
||||
* this use of this method is safe. May include a security review ticket
|
||||
* number.
|
||||
* @param {string} url The string to wrap as a SafeUrl.
|
||||
* @return {!goog.html.SafeUrl} The value of {@code url}, wrapped in a SafeUrl
|
||||
* object.
|
||||
*/
|
||||
goog.html.uncheckedconversions.safeUrlFromStringKnownToSatisfyTypeContract =
|
||||
function(justification, url) {
|
||||
// unwrap() called inside an assert so that justification can be optimized
|
||||
// away in production code.
|
||||
goog.asserts.assertString(
|
||||
goog.string.Const.unwrap(justification), 'must provide justification');
|
||||
goog.asserts.assert(
|
||||
!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
|
||||
'must provide non-empty justification');
|
||||
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs an "unchecked conversion" to TrustedResourceUrl from a plain string
|
||||
* that is known to satisfy the TrustedResourceUrl type contract.
|
||||
*
|
||||
* IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
|
||||
* that the value of {@code url} satisfies the TrustedResourceUrl type contract
|
||||
* in all possible program states.
|
||||
*
|
||||
*
|
||||
* @param {!goog.string.Const} justification A constant string explaining why
|
||||
* this use of this method is safe. May include a security review ticket
|
||||
* number.
|
||||
* @param {string} url The string to wrap as a TrustedResourceUrl.
|
||||
* @return {!goog.html.TrustedResourceUrl} The value of {@code url}, wrapped in
|
||||
* a TrustedResourceUrl object.
|
||||
*/
|
||||
goog.html.uncheckedconversions
|
||||
.trustedResourceUrlFromStringKnownToSatisfyTypeContract = function(
|
||||
justification, url) {
|
||||
// unwrap() called inside an assert so that justification can be optimized
|
||||
// away in production code.
|
||||
goog.asserts.assertString(
|
||||
goog.string.Const.unwrap(justification), 'must provide justification');
|
||||
goog.asserts.assert(
|
||||
!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
|
||||
'must provide non-empty justification');
|
||||
return goog.html.TrustedResourceUrl
|
||||
.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(url);
|
||||
};
|
876
assets/viz/2/goog/i18n/bidi.js
Normal file
876
assets/viz/2/goog/i18n/bidi.js
Normal file
@ -0,0 +1,876 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utility functions for supporting Bidi issues.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Namespace for bidi supporting functions.
|
||||
*/
|
||||
goog.provide('goog.i18n.bidi');
|
||||
goog.provide('goog.i18n.bidi.Dir');
|
||||
goog.provide('goog.i18n.bidi.DirectionalString');
|
||||
goog.provide('goog.i18n.bidi.Format');
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} FORCE_RTL forces the {@link goog.i18n.bidi.IS_RTL} constant
|
||||
* to say that the current locale is a RTL locale. This should only be used
|
||||
* if you want to override the default behavior for deciding whether the
|
||||
* current locale is RTL or not.
|
||||
*
|
||||
* {@see goog.i18n.bidi.IS_RTL}
|
||||
*/
|
||||
goog.define('goog.i18n.bidi.FORCE_RTL', false);
|
||||
|
||||
|
||||
/**
|
||||
* Constant that defines whether or not the current locale is a RTL locale.
|
||||
* If {@link goog.i18n.bidi.FORCE_RTL} is not true, this constant will default
|
||||
* to check that {@link goog.LOCALE} is one of a few major RTL locales.
|
||||
*
|
||||
* <p>This is designed to be a maximally efficient compile-time constant. For
|
||||
* example, for the default goog.LOCALE, compiling
|
||||
* "if (goog.i18n.bidi.IS_RTL) alert('rtl') else {}" should produce no code. It
|
||||
* is this design consideration that limits the implementation to only
|
||||
* supporting a few major RTL locales, as opposed to the broader repertoire of
|
||||
* something like goog.i18n.bidi.isRtlLanguage.
|
||||
*
|
||||
* <p>Since this constant refers to the directionality of the locale, it is up
|
||||
* to the caller to determine if this constant should also be used for the
|
||||
* direction of the UI.
|
||||
*
|
||||
* {@see goog.LOCALE}
|
||||
*
|
||||
* @type {boolean}
|
||||
*
|
||||
* TODO(user): write a test that checks that this is a compile-time constant.
|
||||
*/
|
||||
goog.i18n.bidi.IS_RTL = goog.i18n.bidi.FORCE_RTL ||
|
||||
((goog.LOCALE.substring(0, 2).toLowerCase() == 'ar' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'fa' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'he' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'iw' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'ps' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'sd' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'ug' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'ur' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'yi') &&
|
||||
(goog.LOCALE.length == 2 || goog.LOCALE.substring(2, 3) == '-' ||
|
||||
goog.LOCALE.substring(2, 3) == '_')) ||
|
||||
(goog.LOCALE.length >= 3 &&
|
||||
goog.LOCALE.substring(0, 3).toLowerCase() == 'ckb' &&
|
||||
(goog.LOCALE.length == 3 || goog.LOCALE.substring(3, 4) == '-' ||
|
||||
goog.LOCALE.substring(3, 4) == '_'));
|
||||
|
||||
|
||||
/**
|
||||
* Unicode formatting characters and directionality string constants.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.i18n.bidi.Format = {
|
||||
/** Unicode "Left-To-Right Embedding" (LRE) character. */
|
||||
LRE: '\u202A',
|
||||
/** Unicode "Right-To-Left Embedding" (RLE) character. */
|
||||
RLE: '\u202B',
|
||||
/** Unicode "Pop Directional Formatting" (PDF) character. */
|
||||
PDF: '\u202C',
|
||||
/** Unicode "Left-To-Right Mark" (LRM) character. */
|
||||
LRM: '\u200E',
|
||||
/** Unicode "Right-To-Left Mark" (RLM) character. */
|
||||
RLM: '\u200F'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Directionality enum.
|
||||
* @enum {number}
|
||||
*/
|
||||
goog.i18n.bidi.Dir = {
|
||||
/**
|
||||
* Left-to-right.
|
||||
*/
|
||||
LTR: 1,
|
||||
|
||||
/**
|
||||
* Right-to-left.
|
||||
*/
|
||||
RTL: -1,
|
||||
|
||||
/**
|
||||
* Neither left-to-right nor right-to-left.
|
||||
*/
|
||||
NEUTRAL: 0
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 'right' string constant.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.i18n.bidi.RIGHT = 'right';
|
||||
|
||||
|
||||
/**
|
||||
* 'left' string constant.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.i18n.bidi.LEFT = 'left';
|
||||
|
||||
|
||||
/**
|
||||
* 'left' if locale is RTL, 'right' if not.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.i18n.bidi.I18N_RIGHT =
|
||||
goog.i18n.bidi.IS_RTL ? goog.i18n.bidi.LEFT : goog.i18n.bidi.RIGHT;
|
||||
|
||||
|
||||
/**
|
||||
* 'right' if locale is RTL, 'left' if not.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.i18n.bidi.I18N_LEFT =
|
||||
goog.i18n.bidi.IS_RTL ? goog.i18n.bidi.RIGHT : goog.i18n.bidi.LEFT;
|
||||
|
||||
|
||||
/**
|
||||
* Convert a directionality given in various formats to a goog.i18n.bidi.Dir
|
||||
* constant. Useful for interaction with different standards of directionality
|
||||
* representation.
|
||||
*
|
||||
* @param {goog.i18n.bidi.Dir|number|boolean|null} givenDir Directionality given
|
||||
* in one of the following formats:
|
||||
* 1. A goog.i18n.bidi.Dir constant.
|
||||
* 2. A number (positive = LTR, negative = RTL, 0 = neutral).
|
||||
* 3. A boolean (true = RTL, false = LTR).
|
||||
* 4. A null for unknown directionality.
|
||||
* @param {boolean=} opt_noNeutral Whether a givenDir of zero or
|
||||
* goog.i18n.bidi.Dir.NEUTRAL should be treated as null, i.e. unknown, in
|
||||
* order to preserve legacy behavior.
|
||||
* @return {?goog.i18n.bidi.Dir} A goog.i18n.bidi.Dir constant matching the
|
||||
* given directionality. If given null, returns null (i.e. unknown).
|
||||
*/
|
||||
goog.i18n.bidi.toDir = function(givenDir, opt_noNeutral) {
|
||||
if (typeof givenDir == 'number') {
|
||||
// This includes the non-null goog.i18n.bidi.Dir case.
|
||||
return givenDir > 0 ? goog.i18n.bidi.Dir.LTR : givenDir < 0 ?
|
||||
goog.i18n.bidi.Dir.RTL :
|
||||
opt_noNeutral ? null : goog.i18n.bidi.Dir.NEUTRAL;
|
||||
} else if (givenDir == null) {
|
||||
return null;
|
||||
} else {
|
||||
// Must be typeof givenDir == 'boolean'.
|
||||
return givenDir ? goog.i18n.bidi.Dir.RTL : goog.i18n.bidi.Dir.LTR;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A practical pattern to identify strong LTR characters. This pattern is not
|
||||
* theoretically correct according to the Unicode standard. It is simplified for
|
||||
* performance and small code size.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.ltrChars_ =
|
||||
'A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF' +
|
||||
'\u200E\u2C00-\uFB1C\uFE00-\uFE6F\uFEFD-\uFFFF';
|
||||
|
||||
|
||||
/**
|
||||
* A practical pattern to identify strong RTL character. This pattern is not
|
||||
* theoretically correct according to the Unicode standard. It is simplified
|
||||
* for performance and small code size.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlChars_ =
|
||||
'\u0591-\u06EF\u06FA-\u07FF\u200F\uFB1D-\uFDFF\uFE70-\uFEFC';
|
||||
|
||||
|
||||
/**
|
||||
* Simplified regular expression for an HTML tag (opening or closing) or an HTML
|
||||
* escape. We might want to skip over such expressions when estimating the text
|
||||
* directionality.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.htmlSkipReg_ = /<[^>]*>|&[^;]+;/g;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the input text with spaces instead of HTML tags or HTML escapes, if
|
||||
* opt_isStripNeeded is true. Else returns the input as is.
|
||||
* Useful for text directionality estimation.
|
||||
* Note: the function should not be used in other contexts; it is not 100%
|
||||
* correct, but rather a good-enough implementation for directionality
|
||||
* estimation purposes.
|
||||
* @param {string} str The given string.
|
||||
* @param {boolean=} opt_isStripNeeded Whether to perform the stripping.
|
||||
* Default: false (to retain consistency with calling functions).
|
||||
* @return {string} The given string cleaned of HTML tags / escapes.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_ = function(str, opt_isStripNeeded) {
|
||||
return opt_isStripNeeded ? str.replace(goog.i18n.bidi.htmlSkipReg_, '') : str;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression to check for RTL characters.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlCharReg_ = new RegExp('[' + goog.i18n.bidi.rtlChars_ + ']');
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression to check for LTR characters.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.ltrCharReg_ = new RegExp('[' + goog.i18n.bidi.ltrChars_ + ']');
|
||||
|
||||
|
||||
/**
|
||||
* Test whether the given string has any RTL characters in it.
|
||||
* @param {string} str The given string that need to be tested.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether the string contains RTL characters.
|
||||
*/
|
||||
goog.i18n.bidi.hasAnyRtl = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.rtlCharReg_.test(
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Test whether the given string has any RTL characters in it.
|
||||
* @param {string} str The given string that need to be tested.
|
||||
* @return {boolean} Whether the string contains RTL characters.
|
||||
* @deprecated Use hasAnyRtl.
|
||||
*/
|
||||
goog.i18n.bidi.hasRtlChar = goog.i18n.bidi.hasAnyRtl;
|
||||
|
||||
|
||||
/**
|
||||
* Test whether the given string has any LTR characters in it.
|
||||
* @param {string} str The given string that need to be tested.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether the string contains LTR characters.
|
||||
*/
|
||||
goog.i18n.bidi.hasAnyLtr = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.ltrCharReg_.test(
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression pattern to check if the first character in the string
|
||||
* is LTR.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.ltrRe_ = new RegExp('^[' + goog.i18n.bidi.ltrChars_ + ']');
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression pattern to check if the first character in the string
|
||||
* is RTL.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlRe_ = new RegExp('^[' + goog.i18n.bidi.rtlChars_ + ']');
|
||||
|
||||
|
||||
/**
|
||||
* Check if the first character in the string is RTL or not.
|
||||
* @param {string} str The given string that need to be tested.
|
||||
* @return {boolean} Whether the first character in str is an RTL char.
|
||||
*/
|
||||
goog.i18n.bidi.isRtlChar = function(str) {
|
||||
return goog.i18n.bidi.rtlRe_.test(str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if the first character in the string is LTR or not.
|
||||
* @param {string} str The given string that need to be tested.
|
||||
* @return {boolean} Whether the first character in str is an LTR char.
|
||||
*/
|
||||
goog.i18n.bidi.isLtrChar = function(str) {
|
||||
return goog.i18n.bidi.ltrRe_.test(str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if the first character in the string is neutral or not.
|
||||
* @param {string} str The given string that need to be tested.
|
||||
* @return {boolean} Whether the first character in str is a neutral char.
|
||||
*/
|
||||
goog.i18n.bidi.isNeutralChar = function(str) {
|
||||
return !goog.i18n.bidi.isLtrChar(str) && !goog.i18n.bidi.isRtlChar(str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expressions to check if a piece of text is of LTR directionality
|
||||
* on first character with strong directionality.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.ltrDirCheckRe_ = new RegExp(
|
||||
'^[^' + goog.i18n.bidi.rtlChars_ + ']*[' + goog.i18n.bidi.ltrChars_ + ']');
|
||||
|
||||
|
||||
/**
|
||||
* Regular expressions to check if a piece of text is of RTL directionality
|
||||
* on first character with strong directionality.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlDirCheckRe_ = new RegExp(
|
||||
'^[^' + goog.i18n.bidi.ltrChars_ + ']*[' + goog.i18n.bidi.rtlChars_ + ']');
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the first strongly directional character (if any) is RTL.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether RTL directionality is detected using the first
|
||||
* strongly-directional character method.
|
||||
*/
|
||||
goog.i18n.bidi.startsWithRtl = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.rtlDirCheckRe_.test(
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the first strongly directional character (if any) is RTL.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether RTL directionality is detected using the first
|
||||
* strongly-directional character method.
|
||||
* @deprecated Use startsWithRtl.
|
||||
*/
|
||||
goog.i18n.bidi.isRtlText = goog.i18n.bidi.startsWithRtl;
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the first strongly directional character (if any) is LTR.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether LTR directionality is detected using the first
|
||||
* strongly-directional character method.
|
||||
*/
|
||||
goog.i18n.bidi.startsWithLtr = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.ltrDirCheckRe_.test(
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the first strongly directional character (if any) is LTR.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether LTR directionality is detected using the first
|
||||
* strongly-directional character method.
|
||||
* @deprecated Use startsWithLtr.
|
||||
*/
|
||||
goog.i18n.bidi.isLtrText = goog.i18n.bidi.startsWithLtr;
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression to check if a string looks like something that must
|
||||
* always be LTR even in RTL text, e.g. a URL. When estimating the
|
||||
* directionality of text containing these, we treat these as weakly LTR,
|
||||
* like numbers.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.isRequiredLtrRe_ = /^http:\/\/.*/;
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the input string either contains no strongly directional
|
||||
* characters or looks like a url.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether neutral directionality is detected.
|
||||
*/
|
||||
goog.i18n.bidi.isNeutralText = function(str, opt_isHtml) {
|
||||
str = goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml);
|
||||
return goog.i18n.bidi.isRequiredLtrRe_.test(str) ||
|
||||
!goog.i18n.bidi.hasAnyLtr(str) && !goog.i18n.bidi.hasAnyRtl(str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expressions to check if the last strongly-directional character in a
|
||||
* piece of text is LTR.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.ltrExitDirCheckRe_ = new RegExp(
|
||||
'[' + goog.i18n.bidi.ltrChars_ + '][^' + goog.i18n.bidi.rtlChars_ + ']*$');
|
||||
|
||||
|
||||
/**
|
||||
* Regular expressions to check if the last strongly-directional character in a
|
||||
* piece of text is RTL.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlExitDirCheckRe_ = new RegExp(
|
||||
'[' + goog.i18n.bidi.rtlChars_ + '][^' + goog.i18n.bidi.ltrChars_ + ']*$');
|
||||
|
||||
|
||||
/**
|
||||
* Check if the exit directionality a piece of text is LTR, i.e. if the last
|
||||
* strongly-directional character in the string is LTR.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether LTR exit directionality was detected.
|
||||
*/
|
||||
goog.i18n.bidi.endsWithLtr = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.ltrExitDirCheckRe_.test(
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if the exit directionality a piece of text is LTR, i.e. if the last
|
||||
* strongly-directional character in the string is LTR.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether LTR exit directionality was detected.
|
||||
* @deprecated Use endsWithLtr.
|
||||
*/
|
||||
goog.i18n.bidi.isLtrExitText = goog.i18n.bidi.endsWithLtr;
|
||||
|
||||
|
||||
/**
|
||||
* Check if the exit directionality a piece of text is RTL, i.e. if the last
|
||||
* strongly-directional character in the string is RTL.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether RTL exit directionality was detected.
|
||||
*/
|
||||
goog.i18n.bidi.endsWithRtl = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.rtlExitDirCheckRe_.test(
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if the exit directionality a piece of text is RTL, i.e. if the last
|
||||
* strongly-directional character in the string is RTL.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether RTL exit directionality was detected.
|
||||
* @deprecated Use endsWithRtl.
|
||||
*/
|
||||
goog.i18n.bidi.isRtlExitText = goog.i18n.bidi.endsWithRtl;
|
||||
|
||||
|
||||
/**
|
||||
* A regular expression for matching right-to-left language codes.
|
||||
* See {@link #isRtlLanguage} for the design.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlLocalesRe_ = new RegExp(
|
||||
'^(ar|ckb|dv|he|iw|fa|nqo|ps|sd|ug|ur|yi|' +
|
||||
'.*[-_](Arab|Hebr|Thaa|Nkoo|Tfng))' +
|
||||
'(?!.*[-_](Latn|Cyrl)($|-|_))($|-|_)',
|
||||
'i');
|
||||
|
||||
|
||||
/**
|
||||
* Check if a BCP 47 / III language code indicates an RTL language, i.e. either:
|
||||
* - a language code explicitly specifying one of the right-to-left scripts,
|
||||
* e.g. "az-Arab", or<p>
|
||||
* - a language code specifying one of the languages normally written in a
|
||||
* right-to-left script, e.g. "fa" (Farsi), except ones explicitly specifying
|
||||
* Latin or Cyrillic script (which are the usual LTR alternatives).<p>
|
||||
* The list of right-to-left scripts appears in the 100-199 range in
|
||||
* http://www.unicode.org/iso15924/iso15924-num.html, of which Arabic and
|
||||
* Hebrew are by far the most widely used. We also recognize Thaana, N'Ko, and
|
||||
* Tifinagh, which also have significant modern usage. The rest (Syriac,
|
||||
* Samaritan, Mandaic, etc.) seem to have extremely limited or no modern usage
|
||||
* and are not recognized to save on code size.
|
||||
* The languages usually written in a right-to-left script are taken as those
|
||||
* with Suppress-Script: Hebr|Arab|Thaa|Nkoo|Tfng in
|
||||
* http://www.iana.org/assignments/language-subtag-registry,
|
||||
* as well as Central (or Sorani) Kurdish (ckb), Sindhi (sd) and Uyghur (ug).
|
||||
* Other subtags of the language code, e.g. regions like EG (Egypt), are
|
||||
* ignored.
|
||||
* @param {string} lang BCP 47 (a.k.a III) language code.
|
||||
* @return {boolean} Whether the language code is an RTL language.
|
||||
*/
|
||||
goog.i18n.bidi.isRtlLanguage = function(lang) {
|
||||
return goog.i18n.bidi.rtlLocalesRe_.test(lang);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for bracket guard replacement in text.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.bracketGuardTextRe_ =
|
||||
/(\(.*?\)+)|(\[.*?\]+)|(\{.*?\}+)|(<.*?>+)/g;
|
||||
|
||||
|
||||
/**
|
||||
* Apply bracket guard using LRM and RLM. This is to address the problem of
|
||||
* messy bracket display frequently happens in RTL layout.
|
||||
* This function works for plain text, not for HTML. In HTML, the opening
|
||||
* bracket might be in a different context than the closing bracket (such as
|
||||
* an attribute value).
|
||||
* @param {string} s The string that need to be processed.
|
||||
* @param {boolean=} opt_isRtlContext specifies default direction (usually
|
||||
* direction of the UI).
|
||||
* @return {string} The processed string, with all bracket guarded.
|
||||
*/
|
||||
goog.i18n.bidi.guardBracketInText = function(s, opt_isRtlContext) {
|
||||
var useRtl = opt_isRtlContext === undefined ? goog.i18n.bidi.hasAnyRtl(s) :
|
||||
opt_isRtlContext;
|
||||
var mark = useRtl ? goog.i18n.bidi.Format.RLM : goog.i18n.bidi.Format.LRM;
|
||||
return s.replace(goog.i18n.bidi.bracketGuardTextRe_, mark + '$&' + mark);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enforce the html snippet in RTL directionality regardless overall context.
|
||||
* If the html piece was enclosed by tag, dir will be applied to existing
|
||||
* tag, otherwise a span tag will be added as wrapper. For this reason, if
|
||||
* html snippet start with with tag, this tag must enclose the whole piece. If
|
||||
* the tag already has a dir specified, this new one will override existing
|
||||
* one in behavior (tested on FF and IE).
|
||||
* @param {string} html The string that need to be processed.
|
||||
* @return {string} The processed string, with directionality enforced to RTL.
|
||||
*/
|
||||
goog.i18n.bidi.enforceRtlInHtml = function(html) {
|
||||
if (html.charAt(0) == '<') {
|
||||
return html.replace(/<\w+/, '$& dir=rtl');
|
||||
}
|
||||
// '\n' is important for FF so that it won't incorrectly merge span groups
|
||||
return '\n<span dir=rtl>' + html + '</span>';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enforce RTL on both end of the given text piece using unicode BiDi formatting
|
||||
* characters RLE and PDF.
|
||||
* @param {string} text The piece of text that need to be wrapped.
|
||||
* @return {string} The wrapped string after process.
|
||||
*/
|
||||
goog.i18n.bidi.enforceRtlInText = function(text) {
|
||||
return goog.i18n.bidi.Format.RLE + text + goog.i18n.bidi.Format.PDF;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enforce the html snippet in RTL directionality regardless overall context.
|
||||
* If the html piece was enclosed by tag, dir will be applied to existing
|
||||
* tag, otherwise a span tag will be added as wrapper. For this reason, if
|
||||
* html snippet start with with tag, this tag must enclose the whole piece. If
|
||||
* the tag already has a dir specified, this new one will override existing
|
||||
* one in behavior (tested on FF and IE).
|
||||
* @param {string} html The string that need to be processed.
|
||||
* @return {string} The processed string, with directionality enforced to RTL.
|
||||
*/
|
||||
goog.i18n.bidi.enforceLtrInHtml = function(html) {
|
||||
if (html.charAt(0) == '<') {
|
||||
return html.replace(/<\w+/, '$& dir=ltr');
|
||||
}
|
||||
// '\n' is important for FF so that it won't incorrectly merge span groups
|
||||
return '\n<span dir=ltr>' + html + '</span>';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enforce LTR on both end of the given text piece using unicode BiDi formatting
|
||||
* characters LRE and PDF.
|
||||
* @param {string} text The piece of text that need to be wrapped.
|
||||
* @return {string} The wrapped string after process.
|
||||
*/
|
||||
goog.i18n.bidi.enforceLtrInText = function(text) {
|
||||
return goog.i18n.bidi.Format.LRE + text + goog.i18n.bidi.Format.PDF;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression to find dimensions such as "padding: .3 0.4ex 5px 6;"
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.dimensionsRe_ =
|
||||
/:\s*([.\d][.\w]*)\s+([.\d][.\w]*)\s+([.\d][.\w]*)\s+([.\d][.\w]*)/g;
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for left.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.leftRe_ = /left/gi;
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for right.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rightRe_ = /right/gi;
|
||||
|
||||
|
||||
/**
|
||||
* Placeholder regular expression for swapping.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.tempRe_ = /%%%%/g;
|
||||
|
||||
|
||||
/**
|
||||
* Swap location parameters and 'left'/'right' in CSS specification. The
|
||||
* processed string will be suited for RTL layout. Though this function can
|
||||
* cover most cases, there are always exceptions. It is suggested to put
|
||||
* those exceptions in separate group of CSS string.
|
||||
* @param {string} cssStr CSS spefication string.
|
||||
* @return {string} Processed CSS specification string.
|
||||
*/
|
||||
goog.i18n.bidi.mirrorCSS = function(cssStr) {
|
||||
return cssStr
|
||||
.
|
||||
// reverse dimensions
|
||||
replace(goog.i18n.bidi.dimensionsRe_, ':$1 $4 $3 $2')
|
||||
.replace(goog.i18n.bidi.leftRe_, '%%%%')
|
||||
. // swap left and right
|
||||
replace(goog.i18n.bidi.rightRe_, goog.i18n.bidi.LEFT)
|
||||
.replace(goog.i18n.bidi.tempRe_, goog.i18n.bidi.RIGHT);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for hebrew double quote substitution, finding quote
|
||||
* directly after hebrew characters.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.doubleQuoteSubstituteRe_ = /([\u0591-\u05f2])"/g;
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for hebrew single quote substitution, finding quote
|
||||
* directly after hebrew characters.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.singleQuoteSubstituteRe_ = /([\u0591-\u05f2])'/g;
|
||||
|
||||
|
||||
/**
|
||||
* Replace the double and single quote directly after a Hebrew character with
|
||||
* GERESH and GERSHAYIM. In such case, most likely that's user intention.
|
||||
* @param {string} str String that need to be processed.
|
||||
* @return {string} Processed string with double/single quote replaced.
|
||||
*/
|
||||
goog.i18n.bidi.normalizeHebrewQuote = function(str) {
|
||||
return str.replace(goog.i18n.bidi.doubleQuoteSubstituteRe_, '$1\u05f4')
|
||||
.replace(goog.i18n.bidi.singleQuoteSubstituteRe_, '$1\u05f3');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression to split a string into "words" for directionality
|
||||
* estimation based on relative word counts.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.wordSeparatorRe_ = /\s+/;
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression to check if a string contains any numerals. Used to
|
||||
* differentiate between completely neutral strings and those containing
|
||||
* numbers, which are weakly LTR.
|
||||
*
|
||||
* Native Arabic digits (\u0660 - \u0669) are not included because although they
|
||||
* do flow left-to-right inside a number, this is the case even if the overall
|
||||
* directionality is RTL, and a mathematical expression using these digits is
|
||||
* supposed to flow right-to-left overall, including unary plus and minus
|
||||
* appearing to the right of a number, and this does depend on the overall
|
||||
* directionality being RTL. The digits used in Farsi (\u06F0 - \u06F9), on the
|
||||
* other hand, are included, since Farsi math (including unary plus and minus)
|
||||
* does flow left-to-right.
|
||||
*
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.hasNumeralsRe_ = /[\d\u06f0-\u06f9]/;
|
||||
|
||||
|
||||
/**
|
||||
* This constant controls threshold of RTL directionality.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlDetectionThreshold_ = 0.40;
|
||||
|
||||
|
||||
/**
|
||||
* Estimates the directionality of a string based on relative word counts.
|
||||
* If the number of RTL words is above a certain percentage of the total number
|
||||
* of strongly directional words, returns RTL.
|
||||
* Otherwise, if any words are strongly or weakly LTR, returns LTR.
|
||||
* Otherwise, returns UNKNOWN, which is used to mean "neutral".
|
||||
* Numbers are counted as weakly LTR.
|
||||
* @param {string} str The string to be checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {goog.i18n.bidi.Dir} Estimated overall directionality of {@code str}.
|
||||
*/
|
||||
goog.i18n.bidi.estimateDirection = function(str, opt_isHtml) {
|
||||
var rtlCount = 0;
|
||||
var totalCount = 0;
|
||||
var hasWeaklyLtr = false;
|
||||
var tokens = goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml)
|
||||
.split(goog.i18n.bidi.wordSeparatorRe_);
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
var token = tokens[i];
|
||||
if (goog.i18n.bidi.startsWithRtl(token)) {
|
||||
rtlCount++;
|
||||
totalCount++;
|
||||
} else if (goog.i18n.bidi.isRequiredLtrRe_.test(token)) {
|
||||
hasWeaklyLtr = true;
|
||||
} else if (goog.i18n.bidi.hasAnyLtr(token)) {
|
||||
totalCount++;
|
||||
} else if (goog.i18n.bidi.hasNumeralsRe_.test(token)) {
|
||||
hasWeaklyLtr = true;
|
||||
}
|
||||
}
|
||||
|
||||
return totalCount == 0 ?
|
||||
(hasWeaklyLtr ? goog.i18n.bidi.Dir.LTR : goog.i18n.bidi.Dir.NEUTRAL) :
|
||||
(rtlCount / totalCount > goog.i18n.bidi.rtlDetectionThreshold_ ?
|
||||
goog.i18n.bidi.Dir.RTL :
|
||||
goog.i18n.bidi.Dir.LTR);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check the directionality of a piece of text, return true if the piece of
|
||||
* text should be laid out in RTL direction.
|
||||
* @param {string} str The piece of text that need to be detected.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether this piece of text should be laid out in RTL.
|
||||
*/
|
||||
goog.i18n.bidi.detectRtlDirectionality = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.estimateDirection(str, opt_isHtml) ==
|
||||
goog.i18n.bidi.Dir.RTL;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets text input element's directionality and text alignment based on a
|
||||
* given directionality. Does nothing if the given directionality is unknown or
|
||||
* neutral.
|
||||
* @param {Element} element Input field element to set directionality to.
|
||||
* @param {goog.i18n.bidi.Dir|number|boolean|null} dir Desired directionality,
|
||||
* given in one of the following formats:
|
||||
* 1. A goog.i18n.bidi.Dir constant.
|
||||
* 2. A number (positive = LRT, negative = RTL, 0 = neutral).
|
||||
* 3. A boolean (true = RTL, false = LTR).
|
||||
* 4. A null for unknown directionality.
|
||||
*/
|
||||
goog.i18n.bidi.setElementDirAndAlign = function(element, dir) {
|
||||
if (element) {
|
||||
dir = goog.i18n.bidi.toDir(dir);
|
||||
if (dir) {
|
||||
element.style.textAlign = dir == goog.i18n.bidi.Dir.RTL ?
|
||||
goog.i18n.bidi.RIGHT :
|
||||
goog.i18n.bidi.LEFT;
|
||||
element.dir = dir == goog.i18n.bidi.Dir.RTL ? 'rtl' : 'ltr';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets element dir based on estimated directionality of the given text.
|
||||
* @param {!Element} element
|
||||
* @param {string} text
|
||||
*/
|
||||
goog.i18n.bidi.setElementDirByTextDirectionality = function(element, text) {
|
||||
switch (goog.i18n.bidi.estimateDirection(text)) {
|
||||
case (goog.i18n.bidi.Dir.LTR):
|
||||
element.dir = 'ltr';
|
||||
break;
|
||||
case (goog.i18n.bidi.Dir.RTL):
|
||||
element.dir = 'rtl';
|
||||
break;
|
||||
default:
|
||||
// Default for no direction, inherit from document.
|
||||
element.removeAttribute('dir');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Strings that have an (optional) known direction.
|
||||
*
|
||||
* Implementations of this interface are string-like objects that carry an
|
||||
* attached direction, if known.
|
||||
* @interface
|
||||
*/
|
||||
goog.i18n.bidi.DirectionalString = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Interface marker of the DirectionalString interface.
|
||||
*
|
||||
* This property can be used to determine at runtime whether or not an object
|
||||
* implements this interface. All implementations of this interface set this
|
||||
* property to {@code true}.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.i18n.bidi.DirectionalString.prototype
|
||||
.implementsGoogI18nBidiDirectionalString;
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves this object's known direction (if any).
|
||||
* @return {?goog.i18n.bidi.Dir} The known direction. Null if unknown.
|
||||
*/
|
||||
goog.i18n.bidi.DirectionalString.prototype.getDirection;
|
338
assets/viz/2/goog/labs/useragent/browser.js
Normal file
338
assets/viz/2/goog/labs/useragent/browser.js
Normal file
@ -0,0 +1,338 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Closure user agent detection (Browser).
|
||||
* @see <a href="http://www.useragentstring.com/">User agent strings</a>
|
||||
* For more information on rendering engine, platform, or device see the other
|
||||
* sub-namespaces in goog.labs.userAgent, goog.labs.userAgent.platform,
|
||||
* goog.labs.userAgent.device respectively.)
|
||||
*
|
||||
* @author martone@google.com (Andy Martone)
|
||||
*/
|
||||
|
||||
goog.provide('goog.labs.userAgent.browser');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.labs.userAgent.util');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
// TODO(nnaze): Refactor to remove excessive exclusion logic in matching
|
||||
// functions.
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Opera. Note: Chromium
|
||||
* based Opera (Opera 15+) is detected as Chrome to avoid unnecessary
|
||||
* special casing.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchOpera_ = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Opera');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is IE.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchIE_ = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Trident') ||
|
||||
goog.labs.userAgent.util.matchUserAgent('MSIE');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Edge.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchEdge_ = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Edge');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Firefox.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchFirefox_ = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Firefox');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Safari.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchSafari_ = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Safari') &&
|
||||
!(goog.labs.userAgent.browser.matchChrome_() ||
|
||||
goog.labs.userAgent.browser.matchCoast_() ||
|
||||
goog.labs.userAgent.browser.matchOpera_() ||
|
||||
goog.labs.userAgent.browser.matchEdge_() ||
|
||||
goog.labs.userAgent.browser.isSilk() ||
|
||||
goog.labs.userAgent.util.matchUserAgent('Android'));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based
|
||||
* iOS browser).
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchCoast_ = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Coast');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is iOS Webview.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchIosWebview_ = function() {
|
||||
// iOS Webview does not show up as Chrome or Safari. Also check for Opera's
|
||||
// WebKit-based iOS browser, Coast.
|
||||
return (goog.labs.userAgent.util.matchUserAgent('iPad') ||
|
||||
goog.labs.userAgent.util.matchUserAgent('iPhone')) &&
|
||||
!goog.labs.userAgent.browser.matchSafari_() &&
|
||||
!goog.labs.userAgent.browser.matchChrome_() &&
|
||||
!goog.labs.userAgent.browser.matchCoast_() &&
|
||||
goog.labs.userAgent.util.matchUserAgent('AppleWebKit');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Chrome.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchChrome_ = function() {
|
||||
return (goog.labs.userAgent.util.matchUserAgent('Chrome') ||
|
||||
goog.labs.userAgent.util.matchUserAgent('CriOS')) &&
|
||||
!goog.labs.userAgent.browser.matchEdge_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is the Android browser.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchAndroidBrowser_ = function() {
|
||||
// Android can appear in the user agent string for Chrome on Android.
|
||||
// This is not the Android standalone browser if it does.
|
||||
return goog.labs.userAgent.util.matchUserAgent('Android') &&
|
||||
!(goog.labs.userAgent.browser.isChrome() ||
|
||||
goog.labs.userAgent.browser.isFirefox() ||
|
||||
goog.labs.userAgent.browser.isOpera() ||
|
||||
goog.labs.userAgent.browser.isSilk());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Opera.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isOpera = goog.labs.userAgent.browser.matchOpera_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is IE.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isIE = goog.labs.userAgent.browser.matchIE_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Edge.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isEdge = goog.labs.userAgent.browser.matchEdge_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Firefox.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isFirefox =
|
||||
goog.labs.userAgent.browser.matchFirefox_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Safari.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isSafari = goog.labs.userAgent.browser.matchSafari_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based
|
||||
* iOS browser).
|
||||
*/
|
||||
goog.labs.userAgent.browser.isCoast = goog.labs.userAgent.browser.matchCoast_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is iOS Webview.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isIosWebview =
|
||||
goog.labs.userAgent.browser.matchIosWebview_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Chrome.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isChrome = goog.labs.userAgent.browser.matchChrome_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is the Android browser.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isAndroidBrowser =
|
||||
goog.labs.userAgent.browser.matchAndroidBrowser_;
|
||||
|
||||
|
||||
/**
|
||||
* For more information, see:
|
||||
* http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html
|
||||
* @return {boolean} Whether the user's browser is Silk.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isSilk = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Silk');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The browser version or empty string if version cannot be
|
||||
* determined. Note that for Internet Explorer, this returns the version of
|
||||
* the browser, not the version of the rendering engine. (IE 8 in
|
||||
* compatibility mode will return 8.0 rather than 7.0. To determine the
|
||||
* rendering engine version, look at document.documentMode instead. See
|
||||
* http://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx for more
|
||||
* details.)
|
||||
*/
|
||||
goog.labs.userAgent.browser.getVersion = function() {
|
||||
var userAgentString = goog.labs.userAgent.util.getUserAgent();
|
||||
// Special case IE since IE's version is inside the parenthesis and
|
||||
// without the '/'.
|
||||
if (goog.labs.userAgent.browser.isIE()) {
|
||||
return goog.labs.userAgent.browser.getIEVersion_(userAgentString);
|
||||
}
|
||||
|
||||
var versionTuples =
|
||||
goog.labs.userAgent.util.extractVersionTuples(userAgentString);
|
||||
|
||||
// Construct a map for easy lookup.
|
||||
var versionMap = {};
|
||||
goog.array.forEach(versionTuples, function(tuple) {
|
||||
// Note that the tuple is of length three, but we only care about the
|
||||
// first two.
|
||||
var key = tuple[0];
|
||||
var value = tuple[1];
|
||||
versionMap[key] = value;
|
||||
});
|
||||
|
||||
var versionMapHasKey = goog.partial(goog.object.containsKey, versionMap);
|
||||
|
||||
// Gives the value with the first key it finds, otherwise empty string.
|
||||
function lookUpValueWithKeys(keys) {
|
||||
var key = goog.array.find(keys, versionMapHasKey);
|
||||
return versionMap[key] || '';
|
||||
}
|
||||
|
||||
// Check Opera before Chrome since Opera 15+ has "Chrome" in the string.
|
||||
// See
|
||||
// http://my.opera.com/ODIN/blog/2013/07/15/opera-user-agent-strings-opera-15-and-beyond
|
||||
if (goog.labs.userAgent.browser.isOpera()) {
|
||||
// Opera 10 has Version/10.0 but Opera/9.8, so look for "Version" first.
|
||||
// Opera uses 'OPR' for more recent UAs.
|
||||
return lookUpValueWithKeys(['Version', 'Opera']);
|
||||
}
|
||||
|
||||
// Check Edge before Chrome since it has Chrome in the string.
|
||||
if (goog.labs.userAgent.browser.isEdge()) {
|
||||
return lookUpValueWithKeys(['Edge']);
|
||||
}
|
||||
|
||||
if (goog.labs.userAgent.browser.isChrome()) {
|
||||
return lookUpValueWithKeys(['Chrome', 'CriOS']);
|
||||
}
|
||||
|
||||
// Usually products browser versions are in the third tuple after "Mozilla"
|
||||
// and the engine.
|
||||
var tuple = versionTuples[2];
|
||||
return tuple && tuple[1] || '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string|number} version The version to check.
|
||||
* @return {boolean} Whether the browser version is higher or the same as the
|
||||
* given version.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isVersionOrHigher = function(version) {
|
||||
return goog.string.compareVersions(
|
||||
goog.labs.userAgent.browser.getVersion(), version) >= 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determines IE version. More information:
|
||||
* http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx#uaString
|
||||
* http://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx
|
||||
* http://blogs.msdn.com/b/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx
|
||||
* http://blogs.msdn.com/b/ie/archive/2009/01/09/the-internet-explorer-8-user-agent-string-updated-edition.aspx
|
||||
*
|
||||
* @param {string} userAgent the User-Agent.
|
||||
* @return {string}
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.getIEVersion_ = function(userAgent) {
|
||||
// IE11 may identify itself as MSIE 9.0 or MSIE 10.0 due to an IE 11 upgrade
|
||||
// bug. Example UA:
|
||||
// Mozilla/5.0 (MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0; rv:11.0)
|
||||
// like Gecko.
|
||||
// See http://www.whatismybrowser.com/developers/unknown-user-agent-fragments.
|
||||
var rv = /rv: *([\d\.]*)/.exec(userAgent);
|
||||
if (rv && rv[1]) {
|
||||
return rv[1];
|
||||
}
|
||||
|
||||
var version = '';
|
||||
var msie = /MSIE +([\d\.]+)/.exec(userAgent);
|
||||
if (msie && msie[1]) {
|
||||
// IE in compatibility mode usually identifies itself as MSIE 7.0; in this
|
||||
// case, use the Trident version to determine the version of IE. For more
|
||||
// details, see the links above.
|
||||
var tridentVersion = /Trident\/(\d.\d)/.exec(userAgent);
|
||||
if (msie[1] == '7.0') {
|
||||
if (tridentVersion && tridentVersion[1]) {
|
||||
switch (tridentVersion[1]) {
|
||||
case '4.0':
|
||||
version = '8.0';
|
||||
break;
|
||||
case '5.0':
|
||||
version = '9.0';
|
||||
break;
|
||||
case '6.0':
|
||||
version = '10.0';
|
||||
break;
|
||||
case '7.0':
|
||||
version = '11.0';
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
version = '7.0';
|
||||
}
|
||||
} else {
|
||||
version = msie[1];
|
||||
}
|
||||
}
|
||||
return version;
|
||||
};
|
156
assets/viz/2/goog/labs/useragent/engine.js
Normal file
156
assets/viz/2/goog/labs/useragent/engine.js
Normal file
@ -0,0 +1,156 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Closure user agent detection.
|
||||
* @see http://en.wikipedia.org/wiki/User_agent
|
||||
* For more information on browser brand, platform, or device see the other
|
||||
* sub-namespaces in goog.labs.userAgent (browser, platform, and device).
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.labs.userAgent.engine');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.labs.userAgent.util');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the rendering engine is Presto.
|
||||
*/
|
||||
goog.labs.userAgent.engine.isPresto = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Presto');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the rendering engine is Trident.
|
||||
*/
|
||||
goog.labs.userAgent.engine.isTrident = function() {
|
||||
// IE only started including the Trident token in IE8.
|
||||
return goog.labs.userAgent.util.matchUserAgent('Trident') ||
|
||||
goog.labs.userAgent.util.matchUserAgent('MSIE');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the rendering engine is Edge.
|
||||
*/
|
||||
goog.labs.userAgent.engine.isEdge = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Edge');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the rendering engine is WebKit.
|
||||
*/
|
||||
goog.labs.userAgent.engine.isWebKit = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgentIgnoreCase('WebKit') &&
|
||||
!goog.labs.userAgent.engine.isEdge();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the rendering engine is Gecko.
|
||||
*/
|
||||
goog.labs.userAgent.engine.isGecko = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Gecko') &&
|
||||
!goog.labs.userAgent.engine.isWebKit() &&
|
||||
!goog.labs.userAgent.engine.isTrident() &&
|
||||
!goog.labs.userAgent.engine.isEdge();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The rendering engine's version or empty string if version
|
||||
* can't be determined.
|
||||
*/
|
||||
goog.labs.userAgent.engine.getVersion = function() {
|
||||
var userAgentString = goog.labs.userAgent.util.getUserAgent();
|
||||
if (userAgentString) {
|
||||
var tuples = goog.labs.userAgent.util.extractVersionTuples(userAgentString);
|
||||
|
||||
var engineTuple = goog.labs.userAgent.engine.getEngineTuple_(tuples);
|
||||
if (engineTuple) {
|
||||
// In Gecko, the version string is either in the browser info or the
|
||||
// Firefox version. See Gecko user agent string reference:
|
||||
// http://goo.gl/mULqa
|
||||
if (engineTuple[0] == 'Gecko') {
|
||||
return goog.labs.userAgent.engine.getVersionForKey_(tuples, 'Firefox');
|
||||
}
|
||||
|
||||
return engineTuple[1];
|
||||
}
|
||||
|
||||
// MSIE has only one version identifier, and the Trident version is
|
||||
// specified in the parenthetical. IE Edge is covered in the engine tuple
|
||||
// detection.
|
||||
var browserTuple = tuples[0];
|
||||
var info;
|
||||
if (browserTuple && (info = browserTuple[2])) {
|
||||
var match = /Trident\/([^\s;]+)/.exec(info);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!Array<!Array<string>>} tuples Extracted version tuples.
|
||||
* @return {!Array<string>|undefined} The engine tuple or undefined if not
|
||||
* found.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.engine.getEngineTuple_ = function(tuples) {
|
||||
if (!goog.labs.userAgent.engine.isEdge()) {
|
||||
return tuples[1];
|
||||
}
|
||||
for (var i = 0; i < tuples.length; i++) {
|
||||
var tuple = tuples[i];
|
||||
if (tuple[0] == 'Edge') {
|
||||
return tuple;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string|number} version The version to check.
|
||||
* @return {boolean} Whether the rendering engine version is higher or the same
|
||||
* as the given version.
|
||||
*/
|
||||
goog.labs.userAgent.engine.isVersionOrHigher = function(version) {
|
||||
return goog.string.compareVersions(
|
||||
goog.labs.userAgent.engine.getVersion(), version) >= 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!Array<!Array<string>>} tuples Version tuples.
|
||||
* @param {string} key The key to look for.
|
||||
* @return {string} The version string of the given key, if present.
|
||||
* Otherwise, the empty string.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.engine.getVersionForKey_ = function(tuples, key) {
|
||||
// TODO(nnaze): Move to util if useful elsewhere.
|
||||
|
||||
var pair = goog.array.find(tuples, function(pair) { return key == pair[0]; });
|
||||
|
||||
return pair && pair[1] || '';
|
||||
};
|
160
assets/viz/2/goog/labs/useragent/platform.js
Normal file
160
assets/viz/2/goog/labs/useragent/platform.js
Normal file
@ -0,0 +1,160 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Closure user agent platform detection.
|
||||
* @see <a href="http://www.useragentstring.com/">User agent strings</a>
|
||||
* For more information on browser brand, rendering engine, or device see the
|
||||
* other sub-namespaces in goog.labs.userAgent (browser, engine, and device
|
||||
* respectively).
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.labs.userAgent.platform');
|
||||
|
||||
goog.require('goog.labs.userAgent.util');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is Android.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isAndroid = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Android');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is iPod.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isIpod = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('iPod');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is iPhone.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isIphone = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('iPhone') &&
|
||||
!goog.labs.userAgent.util.matchUserAgent('iPod') &&
|
||||
!goog.labs.userAgent.util.matchUserAgent('iPad');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is iPad.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isIpad = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('iPad');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is iOS.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isIos = function() {
|
||||
return goog.labs.userAgent.platform.isIphone() ||
|
||||
goog.labs.userAgent.platform.isIpad() ||
|
||||
goog.labs.userAgent.platform.isIpod();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is Mac.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isMacintosh = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Macintosh');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Note: ChromeOS is not considered to be Linux as it does not report itself
|
||||
* as Linux in the user agent string.
|
||||
* @return {boolean} Whether the platform is Linux.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isLinux = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Linux');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is Windows.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isWindows = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Windows');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is ChromeOS.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isChromeOS = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('CrOS');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The version of the platform. We only determine the version for Windows,
|
||||
* Mac, and Chrome OS. It doesn't make much sense on Linux. For Windows, we only
|
||||
* look at the NT version. Non-NT-based versions (e.g. 95, 98, etc.) are given
|
||||
* version 0.0.
|
||||
*
|
||||
* @return {string} The platform version or empty string if version cannot be
|
||||
* determined.
|
||||
*/
|
||||
goog.labs.userAgent.platform.getVersion = function() {
|
||||
var userAgentString = goog.labs.userAgent.util.getUserAgent();
|
||||
var version = '', re;
|
||||
if (goog.labs.userAgent.platform.isWindows()) {
|
||||
re = /Windows (?:NT|Phone) ([0-9.]+)/;
|
||||
var match = re.exec(userAgentString);
|
||||
if (match) {
|
||||
version = match[1];
|
||||
} else {
|
||||
version = '0.0';
|
||||
}
|
||||
} else if (goog.labs.userAgent.platform.isIos()) {
|
||||
re = /(?:iPhone|iPod|iPad|CPU)\s+OS\s+(\S+)/;
|
||||
var match = re.exec(userAgentString);
|
||||
// Report the version as x.y.z and not x_y_z
|
||||
version = match && match[1].replace(/_/g, '.');
|
||||
} else if (goog.labs.userAgent.platform.isMacintosh()) {
|
||||
re = /Mac OS X ([0-9_.]+)/;
|
||||
var match = re.exec(userAgentString);
|
||||
// Note: some old versions of Camino do not report an OSX version.
|
||||
// Default to 10.
|
||||
version = match ? match[1].replace(/_/g, '.') : '10';
|
||||
} else if (goog.labs.userAgent.platform.isAndroid()) {
|
||||
re = /Android\s+([^\);]+)(\)|;)/;
|
||||
var match = re.exec(userAgentString);
|
||||
version = match && match[1];
|
||||
} else if (goog.labs.userAgent.platform.isChromeOS()) {
|
||||
re = /(?:CrOS\s+(?:i686|x86_64)\s+([0-9.]+))/;
|
||||
var match = re.exec(userAgentString);
|
||||
version = match && match[1];
|
||||
}
|
||||
return version || '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string|number} version The version to check.
|
||||
* @return {boolean} Whether the browser version is higher or the same as the
|
||||
* given version.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isVersionOrHigher = function(version) {
|
||||
return goog.string.compareVersions(
|
||||
goog.labs.userAgent.platform.getVersion(), version) >= 0;
|
||||
};
|
147
assets/viz/2/goog/labs/useragent/util.js
Normal file
147
assets/viz/2/goog/labs/useragent/util.js
Normal file
@ -0,0 +1,147 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities used by goog.labs.userAgent tools. These functions
|
||||
* should not be used outside of goog.labs.userAgent.*.
|
||||
*
|
||||
*
|
||||
* @author nnaze@google.com (Nathan Naze)
|
||||
*/
|
||||
|
||||
goog.provide('goog.labs.userAgent.util');
|
||||
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* Gets the native userAgent string from navigator if it exists.
|
||||
* If navigator or navigator.userAgent string is missing, returns an empty
|
||||
* string.
|
||||
* @return {string}
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.util.getNativeUserAgentString_ = function() {
|
||||
var navigator = goog.labs.userAgent.util.getNavigator_();
|
||||
if (navigator) {
|
||||
var userAgent = navigator.userAgent;
|
||||
if (userAgent) {
|
||||
return userAgent;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Getter for the native navigator.
|
||||
* This is a separate function so it can be stubbed out in testing.
|
||||
* @return {Navigator}
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.util.getNavigator_ = function() {
|
||||
return goog.global.navigator;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A possible override for applications which wish to not check
|
||||
* navigator.userAgent but use a specified value for detection instead.
|
||||
* @private {string}
|
||||
*/
|
||||
goog.labs.userAgent.util.userAgent_ =
|
||||
goog.labs.userAgent.util.getNativeUserAgentString_();
|
||||
|
||||
|
||||
/**
|
||||
* Applications may override browser detection on the built in
|
||||
* navigator.userAgent object by setting this string. Set to null to use the
|
||||
* browser object instead.
|
||||
* @param {?string=} opt_userAgent The User-Agent override.
|
||||
*/
|
||||
goog.labs.userAgent.util.setUserAgent = function(opt_userAgent) {
|
||||
goog.labs.userAgent.util.userAgent_ =
|
||||
opt_userAgent || goog.labs.userAgent.util.getNativeUserAgentString_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The user agent string.
|
||||
*/
|
||||
goog.labs.userAgent.util.getUserAgent = function() {
|
||||
return goog.labs.userAgent.util.userAgent_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @return {boolean} Whether the user agent contains the given string, ignoring
|
||||
* case.
|
||||
*/
|
||||
goog.labs.userAgent.util.matchUserAgent = function(str) {
|
||||
var userAgent = goog.labs.userAgent.util.getUserAgent();
|
||||
return goog.string.contains(userAgent, str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @return {boolean} Whether the user agent contains the given string.
|
||||
*/
|
||||
goog.labs.userAgent.util.matchUserAgentIgnoreCase = function(str) {
|
||||
var userAgent = goog.labs.userAgent.util.getUserAgent();
|
||||
return goog.string.caseInsensitiveContains(userAgent, str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parses the user agent into tuples for each section.
|
||||
* @param {string} userAgent
|
||||
* @return {!Array<!Array<string>>} Tuples of key, version, and the contents
|
||||
* of the parenthetical.
|
||||
*/
|
||||
goog.labs.userAgent.util.extractVersionTuples = function(userAgent) {
|
||||
// Matches each section of a user agent string.
|
||||
// Example UA:
|
||||
// Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us)
|
||||
// AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405
|
||||
// This has three version tuples: Mozilla, AppleWebKit, and Mobile.
|
||||
|
||||
var versionRegExp = new RegExp(
|
||||
// Key. Note that a key may have a space.
|
||||
// (i.e. 'Mobile Safari' in 'Mobile Safari/5.0')
|
||||
'(\\w[\\w ]+)' +
|
||||
|
||||
'/' + // slash
|
||||
'([^\\s]+)' + // version (i.e. '5.0b')
|
||||
'\\s*' + // whitespace
|
||||
'(?:\\((.*?)\\))?', // parenthetical info. parentheses not matched.
|
||||
'g');
|
||||
|
||||
var data = [];
|
||||
var match;
|
||||
|
||||
// Iterate and collect the version tuples. Each iteration will be the
|
||||
// next regex match.
|
||||
while (match = versionRegExp.exec(userAgent)) {
|
||||
data.push([
|
||||
match[1], // key
|
||||
match[2], // value
|
||||
// || undefined as this is not undefined in IE7 and IE8
|
||||
match[3] || undefined // info
|
||||
]);
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
268
assets/viz/2/goog/math/coordinate.js
Normal file
268
assets/viz/2/goog/math/coordinate.js
Normal file
@ -0,0 +1,268 @@
|
||||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A utility class for representing two-dimensional positions.
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.math.Coordinate');
|
||||
|
||||
goog.require('goog.math');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class for representing coordinates and positions.
|
||||
* @param {number=} opt_x Left, defaults to 0.
|
||||
* @param {number=} opt_y Top, defaults to 0.
|
||||
* @struct
|
||||
* @constructor
|
||||
*/
|
||||
goog.math.Coordinate = function(opt_x, opt_y) {
|
||||
/**
|
||||
* X-value
|
||||
* @type {number}
|
||||
*/
|
||||
this.x = goog.isDef(opt_x) ? opt_x : 0;
|
||||
|
||||
/**
|
||||
* Y-value
|
||||
* @type {number}
|
||||
*/
|
||||
this.y = goog.isDef(opt_y) ? opt_y : 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new copy of the coordinate.
|
||||
* @return {!goog.math.Coordinate} A clone of this coordinate.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.clone = function() {
|
||||
return new goog.math.Coordinate(this.x, this.y);
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a nice string representing the coordinate.
|
||||
* @return {string} In the form (50, 73).
|
||||
* @override
|
||||
*/
|
||||
goog.math.Coordinate.prototype.toString = function() {
|
||||
return '(' + this.x + ', ' + this.y + ')';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compares coordinates for equality.
|
||||
* @param {goog.math.Coordinate} a A Coordinate.
|
||||
* @param {goog.math.Coordinate} b A Coordinate.
|
||||
* @return {boolean} True iff the coordinates are equal, or if both are null.
|
||||
*/
|
||||
goog.math.Coordinate.equals = function(a, b) {
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
if (!a || !b) {
|
||||
return false;
|
||||
}
|
||||
return a.x == b.x && a.y == b.y;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the distance between two coordinates.
|
||||
* @param {!goog.math.Coordinate} a A Coordinate.
|
||||
* @param {!goog.math.Coordinate} b A Coordinate.
|
||||
* @return {number} The distance between {@code a} and {@code b}.
|
||||
*/
|
||||
goog.math.Coordinate.distance = function(a, b) {
|
||||
var dx = a.x - b.x;
|
||||
var dy = a.y - b.y;
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the magnitude of a coordinate.
|
||||
* @param {!goog.math.Coordinate} a A Coordinate.
|
||||
* @return {number} The distance between the origin and {@code a}.
|
||||
*/
|
||||
goog.math.Coordinate.magnitude = function(a) {
|
||||
return Math.sqrt(a.x * a.x + a.y * a.y);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the angle from the origin to a coordinate.
|
||||
* @param {!goog.math.Coordinate} a A Coordinate.
|
||||
* @return {number} The angle, in degrees, clockwise from the positive X
|
||||
* axis to {@code a}.
|
||||
*/
|
||||
goog.math.Coordinate.azimuth = function(a) {
|
||||
return goog.math.angle(0, 0, a.x, a.y);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the squared distance between two coordinates. Squared distances can
|
||||
* be used for comparisons when the actual value is not required.
|
||||
*
|
||||
* Performance note: eliminating the square root is an optimization often used
|
||||
* in lower-level languages, but the speed difference is not nearly as
|
||||
* pronounced in JavaScript (only a few percent.)
|
||||
*
|
||||
* @param {!goog.math.Coordinate} a A Coordinate.
|
||||
* @param {!goog.math.Coordinate} b A Coordinate.
|
||||
* @return {number} The squared distance between {@code a} and {@code b}.
|
||||
*/
|
||||
goog.math.Coordinate.squaredDistance = function(a, b) {
|
||||
var dx = a.x - b.x;
|
||||
var dy = a.y - b.y;
|
||||
return dx * dx + dy * dy;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the difference between two coordinates as a new
|
||||
* goog.math.Coordinate.
|
||||
* @param {!goog.math.Coordinate} a A Coordinate.
|
||||
* @param {!goog.math.Coordinate} b A Coordinate.
|
||||
* @return {!goog.math.Coordinate} A Coordinate representing the difference
|
||||
* between {@code a} and {@code b}.
|
||||
*/
|
||||
goog.math.Coordinate.difference = function(a, b) {
|
||||
return new goog.math.Coordinate(a.x - b.x, a.y - b.y);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the sum of two coordinates as a new goog.math.Coordinate.
|
||||
* @param {!goog.math.Coordinate} a A Coordinate.
|
||||
* @param {!goog.math.Coordinate} b A Coordinate.
|
||||
* @return {!goog.math.Coordinate} A Coordinate representing the sum of the two
|
||||
* coordinates.
|
||||
*/
|
||||
goog.math.Coordinate.sum = function(a, b) {
|
||||
return new goog.math.Coordinate(a.x + b.x, a.y + b.y);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rounds the x and y fields to the next larger integer values.
|
||||
* @return {!goog.math.Coordinate} This coordinate with ceil'd fields.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.ceil = function() {
|
||||
this.x = Math.ceil(this.x);
|
||||
this.y = Math.ceil(this.y);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rounds the x and y fields to the next smaller integer values.
|
||||
* @return {!goog.math.Coordinate} This coordinate with floored fields.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.floor = function() {
|
||||
this.x = Math.floor(this.x);
|
||||
this.y = Math.floor(this.y);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rounds the x and y fields to the nearest integer values.
|
||||
* @return {!goog.math.Coordinate} This coordinate with rounded fields.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.round = function() {
|
||||
this.x = Math.round(this.x);
|
||||
this.y = Math.round(this.y);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Translates this box by the given offsets. If a {@code goog.math.Coordinate}
|
||||
* is given, then the x and y values are translated by the coordinate's x and y.
|
||||
* Otherwise, x and y are translated by {@code tx} and {@code opt_ty}
|
||||
* respectively.
|
||||
* @param {number|goog.math.Coordinate} tx The value to translate x by or the
|
||||
* the coordinate to translate this coordinate by.
|
||||
* @param {number=} opt_ty The value to translate y by.
|
||||
* @return {!goog.math.Coordinate} This coordinate after translating.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.translate = function(tx, opt_ty) {
|
||||
if (tx instanceof goog.math.Coordinate) {
|
||||
this.x += tx.x;
|
||||
this.y += tx.y;
|
||||
} else {
|
||||
this.x += Number(tx);
|
||||
if (goog.isNumber(opt_ty)) {
|
||||
this.y += opt_ty;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Scales this coordinate by the given scale factors. The x and y values are
|
||||
* scaled by {@code sx} and {@code opt_sy} respectively. If {@code opt_sy}
|
||||
* is not given, then {@code sx} is used for both x and y.
|
||||
* @param {number} sx The scale factor to use for the x dimension.
|
||||
* @param {number=} opt_sy The scale factor to use for the y dimension.
|
||||
* @return {!goog.math.Coordinate} This coordinate after scaling.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.scale = function(sx, opt_sy) {
|
||||
var sy = goog.isNumber(opt_sy) ? opt_sy : sx;
|
||||
this.x *= sx;
|
||||
this.y *= sy;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rotates this coordinate clockwise about the origin (or, optionally, the given
|
||||
* center) by the given angle, in radians.
|
||||
* @param {number} radians The angle by which to rotate this coordinate
|
||||
* clockwise about the given center, in radians.
|
||||
* @param {!goog.math.Coordinate=} opt_center The center of rotation. Defaults
|
||||
* to (0, 0) if not given.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.rotateRadians = function(radians, opt_center) {
|
||||
var center = opt_center || new goog.math.Coordinate(0, 0);
|
||||
|
||||
var x = this.x;
|
||||
var y = this.y;
|
||||
var cos = Math.cos(radians);
|
||||
var sin = Math.sin(radians);
|
||||
|
||||
this.x = (x - center.x) * cos - (y - center.y) * sin + center.x;
|
||||
this.y = (x - center.x) * sin + (y - center.y) * cos + center.y;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rotates this coordinate clockwise about the origin (or, optionally, the given
|
||||
* center) by the given angle, in degrees.
|
||||
* @param {number} degrees The angle by which to rotate this coordinate
|
||||
* clockwise about the given center, in degrees.
|
||||
* @param {!goog.math.Coordinate=} opt_center The center of rotation. Defaults
|
||||
* to (0, 0) if not given.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.rotateDegrees = function(degrees, opt_center) {
|
||||
this.rotateRadians(goog.math.toRadians(degrees), opt_center);
|
||||
};
|
807
assets/viz/2/goog/math/integer.js
Normal file
807
assets/viz/2/goog/math/integer.js
Normal file
@ -0,0 +1,807 @@
|
||||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Defines an Integer class for representing (potentially)
|
||||
* infinite length two's-complement integer values.
|
||||
*
|
||||
* For the specific case of 64-bit integers, use goog.math.Long, which is more
|
||||
* efficient.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.math.Integer');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a two's-complement integer an array containing bits of the
|
||||
* integer in 32-bit (signed) pieces, given in little-endian order (i.e.,
|
||||
* lowest-order bits in the first piece), and the sign of -1 or 0.
|
||||
*
|
||||
* See the from* functions below for other convenient ways of constructing
|
||||
* Integers.
|
||||
*
|
||||
* The internal representation of an integer is an array of 32-bit signed
|
||||
* pieces, along with a sign (0 or -1) that indicates the contents of all the
|
||||
* other 32-bit pieces out to infinity. We use 32-bit pieces because these are
|
||||
* the size of integers on which Javascript performs bit-operations. For
|
||||
* operations like addition and multiplication, we split each number into 16-bit
|
||||
* pieces, which can easily be multiplied within Javascript's floating-point
|
||||
* representation without overflow or change in sign.
|
||||
*
|
||||
* @struct
|
||||
* @constructor
|
||||
* @param {Array<number>} bits Array containing the bits of the number.
|
||||
* @param {number} sign The sign of the number: -1 for negative and 0 positive.
|
||||
* @final
|
||||
*/
|
||||
goog.math.Integer = function(bits, sign) {
|
||||
/**
|
||||
* @type {!Array<number>}
|
||||
* @private
|
||||
*/
|
||||
this.bits_ = [];
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.sign_ = sign;
|
||||
|
||||
// Copy the 32-bit signed integer values passed in. We prune out those at the
|
||||
// top that equal the sign since they are redundant.
|
||||
var top = true;
|
||||
for (var i = bits.length - 1; i >= 0; i--) {
|
||||
var val = bits[i] | 0;
|
||||
if (!top || val != sign) {
|
||||
this.bits_[i] = val;
|
||||
top = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the
|
||||
// from* methods on which they depend.
|
||||
|
||||
|
||||
/**
|
||||
* A cache of the Integer representations of small integer values.
|
||||
* @type {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Integer.IntCache_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an Integer representing the given (32-bit) integer value.
|
||||
* @param {number} value A 32-bit integer value.
|
||||
* @return {!goog.math.Integer} The corresponding Integer value.
|
||||
*/
|
||||
goog.math.Integer.fromInt = function(value) {
|
||||
if (-128 <= value && value < 128) {
|
||||
var cachedObj = goog.math.Integer.IntCache_[value];
|
||||
if (cachedObj) {
|
||||
return cachedObj;
|
||||
}
|
||||
}
|
||||
|
||||
var obj = new goog.math.Integer([value | 0], value < 0 ? -1 : 0);
|
||||
if (-128 <= value && value < 128) {
|
||||
goog.math.Integer.IntCache_[value] = obj;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an Integer representing the given value, provided that it is a finite
|
||||
* number. Otherwise, zero is returned.
|
||||
* @param {number} value The value in question.
|
||||
* @return {!goog.math.Integer} The corresponding Integer value.
|
||||
*/
|
||||
goog.math.Integer.fromNumber = function(value) {
|
||||
if (isNaN(value) || !isFinite(value)) {
|
||||
return goog.math.Integer.ZERO;
|
||||
} else if (value < 0) {
|
||||
return goog.math.Integer.fromNumber(-value).negate();
|
||||
} else {
|
||||
var bits = [];
|
||||
var pow = 1;
|
||||
for (var i = 0; value >= pow; i++) {
|
||||
bits[i] = (value / pow) | 0;
|
||||
pow *= goog.math.Integer.TWO_PWR_32_DBL_;
|
||||
}
|
||||
return new goog.math.Integer(bits, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Integer representing the value that comes by concatenating the
|
||||
* given entries, each is assumed to be 32 signed bits, given in little-endian
|
||||
* order (lowest order bits in the lowest index), and sign-extending the highest
|
||||
* order 32-bit value.
|
||||
* @param {Array<number>} bits The bits of the number, in 32-bit signed pieces,
|
||||
* in little-endian order.
|
||||
* @return {!goog.math.Integer} The corresponding Integer value.
|
||||
*/
|
||||
goog.math.Integer.fromBits = function(bits) {
|
||||
var high = bits[bits.length - 1];
|
||||
return new goog.math.Integer(bits, high & (1 << 31) ? -1 : 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an Integer representation of the given string, written using the
|
||||
* given radix.
|
||||
* @param {string} str The textual representation of the Integer.
|
||||
* @param {number=} opt_radix The radix in which the text is written.
|
||||
* @return {!goog.math.Integer} The corresponding Integer value.
|
||||
*/
|
||||
goog.math.Integer.fromString = function(str, opt_radix) {
|
||||
if (str.length == 0) {
|
||||
throw Error('number format error: empty string');
|
||||
}
|
||||
|
||||
var radix = opt_radix || 10;
|
||||
if (radix < 2 || 36 < radix) {
|
||||
throw Error('radix out of range: ' + radix);
|
||||
}
|
||||
|
||||
if (str.charAt(0) == '-') {
|
||||
return goog.math.Integer.fromString(str.substring(1), radix).negate();
|
||||
} else if (str.indexOf('-') >= 0) {
|
||||
throw Error('number format error: interior "-" character');
|
||||
}
|
||||
|
||||
// Do several (8) digits each time through the loop, so as to
|
||||
// minimize the calls to the very expensive emulated div.
|
||||
var radixToPower = goog.math.Integer.fromNumber(Math.pow(radix, 8));
|
||||
|
||||
var result = goog.math.Integer.ZERO;
|
||||
for (var i = 0; i < str.length; i += 8) {
|
||||
var size = Math.min(8, str.length - i);
|
||||
var value = parseInt(str.substring(i, i + size), radix);
|
||||
if (size < 8) {
|
||||
var power = goog.math.Integer.fromNumber(Math.pow(radix, size));
|
||||
result = result.multiply(power).add(goog.math.Integer.fromNumber(value));
|
||||
} else {
|
||||
result = result.multiply(radixToPower);
|
||||
result = result.add(goog.math.Integer.fromNumber(value));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A number used repeatedly in calculations. This must appear before the first
|
||||
* call to the from* functions below.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Integer.TWO_PWR_32_DBL_ = (1 << 16) * (1 << 16);
|
||||
|
||||
|
||||
/** @type {!goog.math.Integer} */
|
||||
goog.math.Integer.ZERO = goog.math.Integer.fromInt(0);
|
||||
|
||||
|
||||
/** @type {!goog.math.Integer} */
|
||||
goog.math.Integer.ONE = goog.math.Integer.fromInt(1);
|
||||
|
||||
|
||||
/**
|
||||
* @type {!goog.math.Integer}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Integer.TWO_PWR_24_ = goog.math.Integer.fromInt(1 << 24);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value, assuming it is a 32-bit integer.
|
||||
* @return {number} The corresponding int value.
|
||||
*/
|
||||
goog.math.Integer.prototype.toInt = function() {
|
||||
return this.bits_.length > 0 ? this.bits_[0] : this.sign_;
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The closest floating-point representation to this value. */
|
||||
goog.math.Integer.prototype.toNumber = function() {
|
||||
if (this.isNegative()) {
|
||||
return -this.negate().toNumber();
|
||||
} else {
|
||||
var val = 0;
|
||||
var pow = 1;
|
||||
for (var i = 0; i < this.bits_.length; i++) {
|
||||
val += this.getBitsUnsigned(i) * pow;
|
||||
pow *= goog.math.Integer.TWO_PWR_32_DBL_;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number=} opt_radix The radix in which the text should be written.
|
||||
* @return {string} The textual representation of this value.
|
||||
* @override
|
||||
*/
|
||||
goog.math.Integer.prototype.toString = function(opt_radix) {
|
||||
var radix = opt_radix || 10;
|
||||
if (radix < 2 || 36 < radix) {
|
||||
throw Error('radix out of range: ' + radix);
|
||||
}
|
||||
|
||||
if (this.isZero()) {
|
||||
return '0';
|
||||
} else if (this.isNegative()) {
|
||||
return '-' + this.negate().toString(radix);
|
||||
}
|
||||
|
||||
// Do several (6) digits each time through the loop, so as to
|
||||
// minimize the calls to the very expensive emulated div.
|
||||
var radixToPower = goog.math.Integer.fromNumber(Math.pow(radix, 6));
|
||||
|
||||
var rem = this;
|
||||
var result = '';
|
||||
while (true) {
|
||||
var remDiv = rem.divide(radixToPower);
|
||||
// The right shifting fixes negative values in the case when
|
||||
// intval >= 2^31; for more details see
|
||||
// https://github.com/google/closure-library/pull/498
|
||||
var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt() >>> 0;
|
||||
var digits = intval.toString(radix);
|
||||
|
||||
rem = remDiv;
|
||||
if (rem.isZero()) {
|
||||
return digits + result;
|
||||
} else {
|
||||
while (digits.length < 6) {
|
||||
digits = '0' + digits;
|
||||
}
|
||||
result = '' + digits + result;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the index-th 32-bit (signed) piece of the Integer according to
|
||||
* little-endian order (i.e., index 0 contains the smallest bits).
|
||||
* @param {number} index The index in question.
|
||||
* @return {number} The requested 32-bits as a signed number.
|
||||
*/
|
||||
goog.math.Integer.prototype.getBits = function(index) {
|
||||
if (index < 0) {
|
||||
return 0; // Allowing this simplifies bit shifting operations below...
|
||||
} else if (index < this.bits_.length) {
|
||||
return this.bits_[index];
|
||||
} else {
|
||||
return this.sign_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the index-th 32-bit piece as an unsigned number.
|
||||
* @param {number} index The index in question.
|
||||
* @return {number} The requested 32-bits as an unsigned number.
|
||||
*/
|
||||
goog.math.Integer.prototype.getBitsUnsigned = function(index) {
|
||||
var val = this.getBits(index);
|
||||
return val >= 0 ? val : goog.math.Integer.TWO_PWR_32_DBL_ + val;
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The sign bit of this number, -1 or 0. */
|
||||
goog.math.Integer.prototype.getSign = function() {
|
||||
return this.sign_;
|
||||
};
|
||||
|
||||
|
||||
/** @return {boolean} Whether this value is zero. */
|
||||
goog.math.Integer.prototype.isZero = function() {
|
||||
if (this.sign_ != 0) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < this.bits_.length; i++) {
|
||||
if (this.bits_[i] != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/** @return {boolean} Whether this value is negative. */
|
||||
goog.math.Integer.prototype.isNegative = function() {
|
||||
return this.sign_ == -1;
|
||||
};
|
||||
|
||||
|
||||
/** @return {boolean} Whether this value is odd. */
|
||||
goog.math.Integer.prototype.isOdd = function() {
|
||||
return (this.bits_.length == 0) && (this.sign_ == -1) ||
|
||||
(this.bits_.length > 0) && ((this.bits_[0] & 1) != 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {boolean} Whether this Integer equals the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.equals = function(other) {
|
||||
if (this.sign_ != other.sign_) {
|
||||
return false;
|
||||
}
|
||||
var len = Math.max(this.bits_.length, other.bits_.length);
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (this.getBits(i) != other.getBits(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {boolean} Whether this Integer does not equal the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.notEquals = function(other) {
|
||||
return !this.equals(other);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {boolean} Whether this Integer is greater than the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.greaterThan = function(other) {
|
||||
return this.compare(other) > 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {boolean} Whether this Integer is greater than or equal to the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.greaterThanOrEqual = function(other) {
|
||||
return this.compare(other) >= 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {boolean} Whether this Integer is less than the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.lessThan = function(other) {
|
||||
return this.compare(other) < 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {boolean} Whether this Integer is less than or equal to the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.lessThanOrEqual = function(other) {
|
||||
return this.compare(other) <= 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compares this Integer with the given one.
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {number} 0 if they are the same, 1 if the this is greater, and -1
|
||||
* if the given one is greater.
|
||||
*/
|
||||
goog.math.Integer.prototype.compare = function(other) {
|
||||
var diff = this.subtract(other);
|
||||
if (diff.isNegative()) {
|
||||
return -1;
|
||||
} else if (diff.isZero()) {
|
||||
return 0;
|
||||
} else {
|
||||
return +1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an integer with only the first numBits bits of this value, sign
|
||||
* extended from the final bit.
|
||||
* @param {number} numBits The number of bits by which to shift.
|
||||
* @return {!goog.math.Integer} The shorted integer value.
|
||||
*/
|
||||
goog.math.Integer.prototype.shorten = function(numBits) {
|
||||
var arr_index = (numBits - 1) >> 5;
|
||||
var bit_index = (numBits - 1) % 32;
|
||||
var bits = [];
|
||||
for (var i = 0; i < arr_index; i++) {
|
||||
bits[i] = this.getBits(i);
|
||||
}
|
||||
var sigBits = bit_index == 31 ? 0xFFFFFFFF : (1 << (bit_index + 1)) - 1;
|
||||
var val = this.getBits(arr_index) & sigBits;
|
||||
if (val & (1 << bit_index)) {
|
||||
val |= 0xFFFFFFFF - sigBits;
|
||||
bits[arr_index] = val;
|
||||
return new goog.math.Integer(bits, -1);
|
||||
} else {
|
||||
bits[arr_index] = val;
|
||||
return new goog.math.Integer(bits, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @return {!goog.math.Integer} The negation of this value. */
|
||||
goog.math.Integer.prototype.negate = function() {
|
||||
return this.not().add(goog.math.Integer.ONE);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the sum of this and the given Integer.
|
||||
* @param {goog.math.Integer} other The Integer to add to this.
|
||||
* @return {!goog.math.Integer} The Integer result.
|
||||
*/
|
||||
goog.math.Integer.prototype.add = function(other) {
|
||||
var len = Math.max(this.bits_.length, other.bits_.length);
|
||||
var arr = [];
|
||||
var carry = 0;
|
||||
|
||||
for (var i = 0; i <= len; i++) {
|
||||
var a1 = this.getBits(i) >>> 16;
|
||||
var a0 = this.getBits(i) & 0xFFFF;
|
||||
|
||||
var b1 = other.getBits(i) >>> 16;
|
||||
var b0 = other.getBits(i) & 0xFFFF;
|
||||
|
||||
var c0 = carry + a0 + b0;
|
||||
var c1 = (c0 >>> 16) + a1 + b1;
|
||||
carry = c1 >>> 16;
|
||||
c0 &= 0xFFFF;
|
||||
c1 &= 0xFFFF;
|
||||
arr[i] = (c1 << 16) | c0;
|
||||
}
|
||||
return goog.math.Integer.fromBits(arr);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the difference of this and the given Integer.
|
||||
* @param {goog.math.Integer} other The Integer to subtract from this.
|
||||
* @return {!goog.math.Integer} The Integer result.
|
||||
*/
|
||||
goog.math.Integer.prototype.subtract = function(other) {
|
||||
return this.add(other.negate());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the product of this and the given Integer.
|
||||
* @param {goog.math.Integer} other The Integer to multiply against this.
|
||||
* @return {!goog.math.Integer} The product of this and the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.multiply = function(other) {
|
||||
if (this.isZero()) {
|
||||
return goog.math.Integer.ZERO;
|
||||
} else if (other.isZero()) {
|
||||
return goog.math.Integer.ZERO;
|
||||
}
|
||||
|
||||
if (this.isNegative()) {
|
||||
if (other.isNegative()) {
|
||||
return this.negate().multiply(other.negate());
|
||||
} else {
|
||||
return this.negate().multiply(other).negate();
|
||||
}
|
||||
} else if (other.isNegative()) {
|
||||
return this.multiply(other.negate()).negate();
|
||||
}
|
||||
|
||||
// If both numbers are small, use float multiplication
|
||||
if (this.lessThan(goog.math.Integer.TWO_PWR_24_) &&
|
||||
other.lessThan(goog.math.Integer.TWO_PWR_24_)) {
|
||||
return goog.math.Integer.fromNumber(this.toNumber() * other.toNumber());
|
||||
}
|
||||
|
||||
// Fill in an array of 16-bit products.
|
||||
var len = this.bits_.length + other.bits_.length;
|
||||
var arr = [];
|
||||
for (var i = 0; i < 2 * len; i++) {
|
||||
arr[i] = 0;
|
||||
}
|
||||
for (var i = 0; i < this.bits_.length; i++) {
|
||||
for (var j = 0; j < other.bits_.length; j++) {
|
||||
var a1 = this.getBits(i) >>> 16;
|
||||
var a0 = this.getBits(i) & 0xFFFF;
|
||||
|
||||
var b1 = other.getBits(j) >>> 16;
|
||||
var b0 = other.getBits(j) & 0xFFFF;
|
||||
|
||||
arr[2 * i + 2 * j] += a0 * b0;
|
||||
goog.math.Integer.carry16_(arr, 2 * i + 2 * j);
|
||||
arr[2 * i + 2 * j + 1] += a1 * b0;
|
||||
goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 1);
|
||||
arr[2 * i + 2 * j + 1] += a0 * b1;
|
||||
goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 1);
|
||||
arr[2 * i + 2 * j + 2] += a1 * b1;
|
||||
goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Combine the 16-bit values into 32-bit values.
|
||||
for (var i = 0; i < len; i++) {
|
||||
arr[i] = (arr[2 * i + 1] << 16) | arr[2 * i];
|
||||
}
|
||||
for (var i = len; i < 2 * len; i++) {
|
||||
arr[i] = 0;
|
||||
}
|
||||
return new goog.math.Integer(arr, 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Carries any overflow from the given index into later entries.
|
||||
* @param {Array<number>} bits Array of 16-bit values in little-endian order.
|
||||
* @param {number} index The index in question.
|
||||
* @private
|
||||
*/
|
||||
goog.math.Integer.carry16_ = function(bits, index) {
|
||||
while ((bits[index] & 0xFFFF) != bits[index]) {
|
||||
bits[index + 1] += bits[index] >>> 16;
|
||||
bits[index] &= 0xFFFF;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns "this" Integer divided by the given one. Both "this" and the given
|
||||
* Integer MUST be positive.
|
||||
*
|
||||
* This method is only needed for very large numbers (>10^308),
|
||||
* for which the original division algorithm gets into an infinite
|
||||
* loop (see https://github.com/google/closure-library/issues/500).
|
||||
*
|
||||
* The algorithm has some possible performance enhancements (or
|
||||
* could be rewritten entirely), it's just an initial solution for
|
||||
* the issue linked above.
|
||||
*
|
||||
* @param {!goog.math.Integer} other The Integer to divide "this" by.
|
||||
* @return {!goog.math.Integer} "this" value divided by the given one.
|
||||
* @private
|
||||
*/
|
||||
goog.math.Integer.prototype.slowDivide_ = function(other) {
|
||||
if (this.isNegative() || other.isNegative()) {
|
||||
throw Error('slowDivide_ only works with positive integers.');
|
||||
}
|
||||
|
||||
var twoPower = goog.math.Integer.ONE;
|
||||
var multiple = other;
|
||||
|
||||
// First we have to figure out what the highest bit of the result
|
||||
// is, so we increase "twoPower" and "multiple" until "multiple"
|
||||
// exceeds "this".
|
||||
while (multiple.lessThanOrEqual(this)) {
|
||||
twoPower = twoPower.shiftLeft(1);
|
||||
multiple = multiple.shiftLeft(1);
|
||||
}
|
||||
|
||||
// Rewind by one power of two, giving us the highest bit of the
|
||||
// result.
|
||||
var res = twoPower.shiftRight(1);
|
||||
var total = multiple.shiftRight(1);
|
||||
|
||||
// Now we starting decreasing "multiple" and "twoPower" to find the
|
||||
// rest of the bits of the result.
|
||||
var total2;
|
||||
multiple = multiple.shiftRight(2);
|
||||
twoPower = twoPower.shiftRight(2);
|
||||
while (!multiple.isZero()) {
|
||||
// whenever we can add "multiple" to the total and not exceed
|
||||
// "this", that means we've found a 1 bit. Else we've found a 0
|
||||
// and don't need to add to the result.
|
||||
total2 = total.add(multiple);
|
||||
if (total2.lessThanOrEqual(this)) {
|
||||
res = res.add(twoPower);
|
||||
total = total2;
|
||||
}
|
||||
multiple = multiple.shiftRight(1);
|
||||
twoPower = twoPower.shiftRight(1);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Integer divided by the given one.
|
||||
* @param {!goog.math.Integer} other The Integer to divide this by.
|
||||
* @return {!goog.math.Integer} This value divided by the given one.
|
||||
*/
|
||||
goog.math.Integer.prototype.divide = function(other) {
|
||||
if (other.isZero()) {
|
||||
throw Error('division by zero');
|
||||
} else if (this.isZero()) {
|
||||
return goog.math.Integer.ZERO;
|
||||
}
|
||||
|
||||
if (this.isNegative()) {
|
||||
if (other.isNegative()) {
|
||||
return this.negate().divide(other.negate());
|
||||
} else {
|
||||
return this.negate().divide(other).negate();
|
||||
}
|
||||
} else if (other.isNegative()) {
|
||||
return this.divide(other.negate()).negate();
|
||||
}
|
||||
|
||||
// Have to degrade to slowDivide for Very Large Numbers, because
|
||||
// they're out of range for the floating-point approximation
|
||||
// technique used below.
|
||||
if (this.bits_.length > 30) {
|
||||
return this.slowDivide_(other);
|
||||
}
|
||||
|
||||
// Repeat the following until the remainder is less than other: find a
|
||||
// floating-point that approximates remainder / other *from below*, add this
|
||||
// into the result, and subtract it from the remainder. It is critical that
|
||||
// the approximate value is less than or equal to the real value so that the
|
||||
// remainder never becomes negative.
|
||||
var res = goog.math.Integer.ZERO;
|
||||
var rem = this;
|
||||
while (rem.greaterThanOrEqual(other)) {
|
||||
// Approximate the result of division. This may be a little greater or
|
||||
// smaller than the actual value.
|
||||
var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber()));
|
||||
|
||||
// We will tweak the approximate result by changing it in the 48-th digit or
|
||||
// the smallest non-fractional digit, whichever is larger.
|
||||
var log2 = Math.ceil(Math.log(approx) / Math.LN2);
|
||||
var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48);
|
||||
|
||||
// Decrease the approximation until it is smaller than the remainder. Note
|
||||
// that if it is too large, the product overflows and is negative.
|
||||
var approxRes = goog.math.Integer.fromNumber(approx);
|
||||
var approxRem = approxRes.multiply(other);
|
||||
while (approxRem.isNegative() || approxRem.greaterThan(rem)) {
|
||||
approx -= delta;
|
||||
approxRes = goog.math.Integer.fromNumber(approx);
|
||||
approxRem = approxRes.multiply(other);
|
||||
}
|
||||
|
||||
// We know the answer can't be zero... and actually, zero would cause
|
||||
// infinite recursion since we would make no progress.
|
||||
if (approxRes.isZero()) {
|
||||
approxRes = goog.math.Integer.ONE;
|
||||
}
|
||||
|
||||
res = res.add(approxRes);
|
||||
rem = rem.subtract(approxRem);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Integer modulo the given one.
|
||||
* @param {!goog.math.Integer} other The Integer by which to mod.
|
||||
* @return {!goog.math.Integer} This value modulo the given one.
|
||||
*/
|
||||
goog.math.Integer.prototype.modulo = function(other) {
|
||||
return this.subtract(this.divide(other).multiply(other));
|
||||
};
|
||||
|
||||
|
||||
/** @return {!goog.math.Integer} The bitwise-NOT of this value. */
|
||||
goog.math.Integer.prototype.not = function() {
|
||||
var len = this.bits_.length;
|
||||
var arr = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
arr[i] = ~this.bits_[i];
|
||||
}
|
||||
return new goog.math.Integer(arr, ~this.sign_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bitwise-AND of this Integer and the given one.
|
||||
* @param {goog.math.Integer} other The Integer to AND with this.
|
||||
* @return {!goog.math.Integer} The bitwise-AND of this and the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.and = function(other) {
|
||||
var len = Math.max(this.bits_.length, other.bits_.length);
|
||||
var arr = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
arr[i] = this.getBits(i) & other.getBits(i);
|
||||
}
|
||||
return new goog.math.Integer(arr, this.sign_ & other.sign_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bitwise-OR of this Integer and the given one.
|
||||
* @param {goog.math.Integer} other The Integer to OR with this.
|
||||
* @return {!goog.math.Integer} The bitwise-OR of this and the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.or = function(other) {
|
||||
var len = Math.max(this.bits_.length, other.bits_.length);
|
||||
var arr = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
arr[i] = this.getBits(i) | other.getBits(i);
|
||||
}
|
||||
return new goog.math.Integer(arr, this.sign_ | other.sign_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bitwise-XOR of this Integer and the given one.
|
||||
* @param {goog.math.Integer} other The Integer to XOR with this.
|
||||
* @return {!goog.math.Integer} The bitwise-XOR of this and the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.xor = function(other) {
|
||||
var len = Math.max(this.bits_.length, other.bits_.length);
|
||||
var arr = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
arr[i] = this.getBits(i) ^ other.getBits(i);
|
||||
}
|
||||
return new goog.math.Integer(arr, this.sign_ ^ other.sign_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this value with bits shifted to the left by the given amount.
|
||||
* @param {number} numBits The number of bits by which to shift.
|
||||
* @return {!goog.math.Integer} This shifted to the left by the given amount.
|
||||
*/
|
||||
goog.math.Integer.prototype.shiftLeft = function(numBits) {
|
||||
var arr_delta = numBits >> 5;
|
||||
var bit_delta = numBits % 32;
|
||||
var len = this.bits_.length + arr_delta + (bit_delta > 0 ? 1 : 0);
|
||||
var arr = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (bit_delta > 0) {
|
||||
arr[i] = (this.getBits(i - arr_delta) << bit_delta) |
|
||||
(this.getBits(i - arr_delta - 1) >>> (32 - bit_delta));
|
||||
} else {
|
||||
arr[i] = this.getBits(i - arr_delta);
|
||||
}
|
||||
}
|
||||
return new goog.math.Integer(arr, this.sign_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this value with bits shifted to the right by the given amount.
|
||||
* @param {number} numBits The number of bits by which to shift.
|
||||
* @return {!goog.math.Integer} This shifted to the right by the given amount.
|
||||
*/
|
||||
goog.math.Integer.prototype.shiftRight = function(numBits) {
|
||||
var arr_delta = numBits >> 5;
|
||||
var bit_delta = numBits % 32;
|
||||
var len = this.bits_.length - arr_delta;
|
||||
var arr = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (bit_delta > 0) {
|
||||
arr[i] = (this.getBits(i + arr_delta) >>> bit_delta) |
|
||||
(this.getBits(i + arr_delta + 1) << (32 - bit_delta));
|
||||
} else {
|
||||
arr[i] = this.getBits(i + arr_delta);
|
||||
}
|
||||
}
|
||||
return new goog.math.Integer(arr, this.sign_);
|
||||
};
|
843
assets/viz/2/goog/math/long.js
Normal file
843
assets/viz/2/goog/math/long.js
Normal file
@ -0,0 +1,843 @@
|
||||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Defines a Long class for representing a 64-bit two's-complement
|
||||
* integer value, which faithfully simulates the behavior of a Java "long". This
|
||||
* implementation is derived from LongLib in GWT.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.math.Long');
|
||||
|
||||
goog.require('goog.reflect');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a 64-bit two's-complement integer, given its low and high 32-bit
|
||||
* values as *signed* integers. See the from* functions below for more
|
||||
* convenient ways of constructing Longs.
|
||||
*
|
||||
* The internal representation of a long is the two given signed, 32-bit values.
|
||||
* We use 32-bit pieces because these are the size of integers on which
|
||||
* Javascript performs bit-operations. For operations like addition and
|
||||
* multiplication, we split each number into 16-bit pieces, which can easily be
|
||||
* multiplied within Javascript's floating-point representation without overflow
|
||||
* or change in sign.
|
||||
*
|
||||
* In the algorithms below, we frequently reduce the negative case to the
|
||||
* positive case by negating the input(s) and then post-processing the result.
|
||||
* Note that we must ALWAYS check specially whether those values are MIN_VALUE
|
||||
* (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
|
||||
* a positive number, it overflows back into a negative). Not handling this
|
||||
* case would often result in infinite recursion.
|
||||
*
|
||||
* @param {number} low The low (signed) 32 bits of the long.
|
||||
* @param {number} high The high (signed) 32 bits of the long.
|
||||
* @struct
|
||||
* @constructor
|
||||
* @final
|
||||
*/
|
||||
goog.math.Long = function(low, high) {
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.low_ = low | 0; // force into 32 signed bits.
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.high_ = high | 0; // force into 32 signed bits.
|
||||
};
|
||||
|
||||
|
||||
// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the
|
||||
// from* methods on which they depend.
|
||||
|
||||
|
||||
/**
|
||||
* A cache of the Long representations of small integer values.
|
||||
* @type {!Object<number, !goog.math.Long>}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.IntCache_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* A cache of the Long representations of common values.
|
||||
* @type {!Object<goog.math.Long.ValueCacheId_, !goog.math.Long>}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.valueCache_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Long representing the given (32-bit) integer value.
|
||||
* @param {number} value The 32-bit integer in question.
|
||||
* @return {!goog.math.Long} The corresponding Long value.
|
||||
*/
|
||||
goog.math.Long.fromInt = function(value) {
|
||||
if (-128 <= value && value < 128) {
|
||||
return goog.reflect.cache(goog.math.Long.IntCache_, value, function(val) {
|
||||
return new goog.math.Long(val | 0, val < 0 ? -1 : 0);
|
||||
});
|
||||
} else {
|
||||
return new goog.math.Long(value | 0, value < 0 ? -1 : 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Long representing the given value.
|
||||
* NaN will be returned as zero. Infinity is converted to max value and
|
||||
* -Infinity to min value.
|
||||
* @param {number} value The number in question.
|
||||
* @return {!goog.math.Long} The corresponding Long value.
|
||||
*/
|
||||
goog.math.Long.fromNumber = function(value) {
|
||||
if (isNaN(value)) {
|
||||
return goog.math.Long.getZero();
|
||||
} else if (value <= -goog.math.Long.TWO_PWR_63_DBL_) {
|
||||
return goog.math.Long.getMinValue();
|
||||
} else if (value + 1 >= goog.math.Long.TWO_PWR_63_DBL_) {
|
||||
return goog.math.Long.getMaxValue();
|
||||
} else if (value < 0) {
|
||||
return goog.math.Long.fromNumber(-value).negate();
|
||||
} else {
|
||||
return new goog.math.Long(
|
||||
(value % goog.math.Long.TWO_PWR_32_DBL_) | 0,
|
||||
(value / goog.math.Long.TWO_PWR_32_DBL_) | 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Long representing the 64-bit integer that comes by concatenating
|
||||
* the given high and low bits. Each is assumed to use 32 bits.
|
||||
* @param {number} lowBits The low 32-bits.
|
||||
* @param {number} highBits The high 32-bits.
|
||||
* @return {!goog.math.Long} The corresponding Long value.
|
||||
*/
|
||||
goog.math.Long.fromBits = function(lowBits, highBits) {
|
||||
return new goog.math.Long(lowBits, highBits);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Long representation of the given string, written using the given
|
||||
* radix.
|
||||
* @param {string} str The textual representation of the Long.
|
||||
* @param {number=} opt_radix The radix in which the text is written.
|
||||
* @return {!goog.math.Long} The corresponding Long value.
|
||||
*/
|
||||
goog.math.Long.fromString = function(str, opt_radix) {
|
||||
if (str.length == 0) {
|
||||
throw Error('number format error: empty string');
|
||||
}
|
||||
|
||||
var radix = opt_radix || 10;
|
||||
if (radix < 2 || 36 < radix) {
|
||||
throw Error('radix out of range: ' + radix);
|
||||
}
|
||||
|
||||
if (str.charAt(0) == '-') {
|
||||
return goog.math.Long.fromString(str.substring(1), radix).negate();
|
||||
} else if (str.indexOf('-') >= 0) {
|
||||
throw Error('number format error: interior "-" character: ' + str);
|
||||
}
|
||||
|
||||
// Do several (8) digits each time through the loop, so as to
|
||||
// minimize the calls to the very expensive emulated div.
|
||||
var radixToPower = goog.math.Long.fromNumber(Math.pow(radix, 8));
|
||||
|
||||
var result = goog.math.Long.getZero();
|
||||
for (var i = 0; i < str.length; i += 8) {
|
||||
var size = Math.min(8, str.length - i);
|
||||
var value = parseInt(str.substring(i, i + size), radix);
|
||||
if (size < 8) {
|
||||
var power = goog.math.Long.fromNumber(Math.pow(radix, size));
|
||||
result = result.multiply(power).add(goog.math.Long.fromNumber(value));
|
||||
} else {
|
||||
result = result.multiply(radixToPower);
|
||||
result = result.add(goog.math.Long.fromNumber(value));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
// NOTE: the compiler should inline these constant values below and then remove
|
||||
// these variables, so there should be no runtime penalty for these.
|
||||
|
||||
|
||||
/**
|
||||
* Number used repeated below in calculations. This must appear before the
|
||||
* first call to any from* function below.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.TWO_PWR_16_DBL_ = 1 << 16;
|
||||
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.TWO_PWR_32_DBL_ =
|
||||
goog.math.Long.TWO_PWR_16_DBL_ * goog.math.Long.TWO_PWR_16_DBL_;
|
||||
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.TWO_PWR_64_DBL_ =
|
||||
goog.math.Long.TWO_PWR_32_DBL_ * goog.math.Long.TWO_PWR_32_DBL_;
|
||||
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.TWO_PWR_63_DBL_ = goog.math.Long.TWO_PWR_64_DBL_ / 2;
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Long}
|
||||
* @public
|
||||
*/
|
||||
goog.math.Long.getZero = function() {
|
||||
return goog.reflect.cache(
|
||||
goog.math.Long.valueCache_, goog.math.Long.ValueCacheId_.ZERO,
|
||||
function() { return goog.math.Long.fromInt(0); });
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Long}
|
||||
* @public
|
||||
*/
|
||||
goog.math.Long.getOne = function() {
|
||||
return goog.reflect.cache(
|
||||
goog.math.Long.valueCache_, goog.math.Long.ValueCacheId_.ONE,
|
||||
function() { return goog.math.Long.fromInt(1); });
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Long}
|
||||
* @public
|
||||
*/
|
||||
goog.math.Long.getNegOne = function() {
|
||||
return goog.reflect.cache(
|
||||
goog.math.Long.valueCache_, goog.math.Long.ValueCacheId_.NEG_ONE,
|
||||
function() { return goog.math.Long.fromInt(-1); });
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Long}
|
||||
* @public
|
||||
*/
|
||||
goog.math.Long.getMaxValue = function() {
|
||||
return goog.reflect.cache(
|
||||
goog.math.Long.valueCache_, goog.math.Long.ValueCacheId_.MAX_VALUE,
|
||||
function() {
|
||||
return goog.math.Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Long}
|
||||
* @public
|
||||
*/
|
||||
goog.math.Long.getMinValue = function() {
|
||||
return goog.reflect.cache(
|
||||
goog.math.Long.valueCache_, goog.math.Long.ValueCacheId_.MIN_VALUE,
|
||||
function() { return goog.math.Long.fromBits(0, 0x80000000 | 0); });
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Long}
|
||||
* @public
|
||||
*/
|
||||
goog.math.Long.getTwoPwr24 = function() {
|
||||
return goog.reflect.cache(
|
||||
goog.math.Long.valueCache_, goog.math.Long.ValueCacheId_.TWO_PWR_24,
|
||||
function() { return goog.math.Long.fromInt(1 << 24); });
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The value, assuming it is a 32-bit integer. */
|
||||
goog.math.Long.prototype.toInt = function() {
|
||||
return this.low_;
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The closest floating-point representation to this value. */
|
||||
goog.math.Long.prototype.toNumber = function() {
|
||||
return this.high_ * goog.math.Long.TWO_PWR_32_DBL_ +
|
||||
this.getLowBitsUnsigned();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number=} opt_radix The radix in which the text should be written.
|
||||
* @return {string} The textual representation of this value.
|
||||
* @override
|
||||
*/
|
||||
goog.math.Long.prototype.toString = function(opt_radix) {
|
||||
var radix = opt_radix || 10;
|
||||
if (radix < 2 || 36 < radix) {
|
||||
throw Error('radix out of range: ' + radix);
|
||||
}
|
||||
|
||||
if (this.isZero()) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
if (this.isNegative()) {
|
||||
if (this.equals(goog.math.Long.getMinValue())) {
|
||||
// We need to change the Long value before it can be negated, so we remove
|
||||
// the bottom-most digit in this base and then recurse to do the rest.
|
||||
var radixLong = goog.math.Long.fromNumber(radix);
|
||||
var div = this.div(radixLong);
|
||||
var rem = div.multiply(radixLong).subtract(this);
|
||||
return div.toString(radix) + rem.toInt().toString(radix);
|
||||
} else {
|
||||
return '-' + this.negate().toString(radix);
|
||||
}
|
||||
}
|
||||
|
||||
// Do several (6) digits each time through the loop, so as to
|
||||
// minimize the calls to the very expensive emulated div.
|
||||
var radixToPower = goog.math.Long.fromNumber(Math.pow(radix, 6));
|
||||
|
||||
var rem = this;
|
||||
var result = '';
|
||||
while (true) {
|
||||
var remDiv = rem.div(radixToPower);
|
||||
// The right shifting fixes negative values in the case when
|
||||
// intval >= 2^31; for more details see
|
||||
// https://github.com/google/closure-library/pull/498
|
||||
var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt() >>> 0;
|
||||
var digits = intval.toString(radix);
|
||||
|
||||
rem = remDiv;
|
||||
if (rem.isZero()) {
|
||||
return digits + result;
|
||||
} else {
|
||||
while (digits.length < 6) {
|
||||
digits = '0' + digits;
|
||||
}
|
||||
result = '' + digits + result;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The high 32-bits as a signed value. */
|
||||
goog.math.Long.prototype.getHighBits = function() {
|
||||
return this.high_;
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The low 32-bits as a signed value. */
|
||||
goog.math.Long.prototype.getLowBits = function() {
|
||||
return this.low_;
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The low 32-bits as an unsigned value. */
|
||||
goog.math.Long.prototype.getLowBitsUnsigned = function() {
|
||||
return (this.low_ >= 0) ? this.low_ :
|
||||
goog.math.Long.TWO_PWR_32_DBL_ + this.low_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Returns the number of bits needed to represent the absolute
|
||||
* value of this Long.
|
||||
*/
|
||||
goog.math.Long.prototype.getNumBitsAbs = function() {
|
||||
if (this.isNegative()) {
|
||||
if (this.equals(goog.math.Long.getMinValue())) {
|
||||
return 64;
|
||||
} else {
|
||||
return this.negate().getNumBitsAbs();
|
||||
}
|
||||
} else {
|
||||
var val = this.high_ != 0 ? this.high_ : this.low_;
|
||||
for (var bit = 31; bit > 0; bit--) {
|
||||
if ((val & (1 << bit)) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this.high_ != 0 ? bit + 33 : bit + 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @return {boolean} Whether this value is zero. */
|
||||
goog.math.Long.prototype.isZero = function() {
|
||||
return this.high_ == 0 && this.low_ == 0;
|
||||
};
|
||||
|
||||
|
||||
/** @return {boolean} Whether this value is negative. */
|
||||
goog.math.Long.prototype.isNegative = function() {
|
||||
return this.high_ < 0;
|
||||
};
|
||||
|
||||
|
||||
/** @return {boolean} Whether this value is odd. */
|
||||
goog.math.Long.prototype.isOdd = function() {
|
||||
return (this.low_ & 1) == 1;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {boolean} Whether this Long equals the other.
|
||||
*/
|
||||
goog.math.Long.prototype.equals = function(other) {
|
||||
return (this.high_ == other.high_) && (this.low_ == other.low_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {boolean} Whether this Long does not equal the other.
|
||||
*/
|
||||
goog.math.Long.prototype.notEquals = function(other) {
|
||||
return (this.high_ != other.high_) || (this.low_ != other.low_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {boolean} Whether this Long is less than the other.
|
||||
*/
|
||||
goog.math.Long.prototype.lessThan = function(other) {
|
||||
return this.compare(other) < 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {boolean} Whether this Long is less than or equal to the other.
|
||||
*/
|
||||
goog.math.Long.prototype.lessThanOrEqual = function(other) {
|
||||
return this.compare(other) <= 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {boolean} Whether this Long is greater than the other.
|
||||
*/
|
||||
goog.math.Long.prototype.greaterThan = function(other) {
|
||||
return this.compare(other) > 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {boolean} Whether this Long is greater than or equal to the other.
|
||||
*/
|
||||
goog.math.Long.prototype.greaterThanOrEqual = function(other) {
|
||||
return this.compare(other) >= 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compares this Long with the given one.
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {number} 0 if they are the same, 1 if the this is greater, and -1
|
||||
* if the given one is greater.
|
||||
*/
|
||||
goog.math.Long.prototype.compare = function(other) {
|
||||
if (this.equals(other)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var thisNeg = this.isNegative();
|
||||
var otherNeg = other.isNegative();
|
||||
if (thisNeg && !otherNeg) {
|
||||
return -1;
|
||||
}
|
||||
if (!thisNeg && otherNeg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// at this point, the signs are the same, so subtraction will not overflow
|
||||
if (this.subtract(other).isNegative()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @return {!goog.math.Long} The negation of this value. */
|
||||
goog.math.Long.prototype.negate = function() {
|
||||
if (this.equals(goog.math.Long.getMinValue())) {
|
||||
return goog.math.Long.getMinValue();
|
||||
} else {
|
||||
return this.not().add(goog.math.Long.getOne());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the sum of this and the given Long.
|
||||
* @param {goog.math.Long} other Long to add to this one.
|
||||
* @return {!goog.math.Long} The sum of this and the given Long.
|
||||
*/
|
||||
goog.math.Long.prototype.add = function(other) {
|
||||
// Divide each number into 4 chunks of 16 bits, and then sum the chunks.
|
||||
|
||||
var a48 = this.high_ >>> 16;
|
||||
var a32 = this.high_ & 0xFFFF;
|
||||
var a16 = this.low_ >>> 16;
|
||||
var a00 = this.low_ & 0xFFFF;
|
||||
|
||||
var b48 = other.high_ >>> 16;
|
||||
var b32 = other.high_ & 0xFFFF;
|
||||
var b16 = other.low_ >>> 16;
|
||||
var b00 = other.low_ & 0xFFFF;
|
||||
|
||||
var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
|
||||
c00 += a00 + b00;
|
||||
c16 += c00 >>> 16;
|
||||
c00 &= 0xFFFF;
|
||||
c16 += a16 + b16;
|
||||
c32 += c16 >>> 16;
|
||||
c16 &= 0xFFFF;
|
||||
c32 += a32 + b32;
|
||||
c48 += c32 >>> 16;
|
||||
c32 &= 0xFFFF;
|
||||
c48 += a48 + b48;
|
||||
c48 &= 0xFFFF;
|
||||
return goog.math.Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the difference of this and the given Long.
|
||||
* @param {goog.math.Long} other Long to subtract from this.
|
||||
* @return {!goog.math.Long} The difference of this and the given Long.
|
||||
*/
|
||||
goog.math.Long.prototype.subtract = function(other) {
|
||||
return this.add(other.negate());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the product of this and the given long.
|
||||
* @param {goog.math.Long} other Long to multiply with this.
|
||||
* @return {!goog.math.Long} The product of this and the other.
|
||||
*/
|
||||
goog.math.Long.prototype.multiply = function(other) {
|
||||
if (this.isZero()) {
|
||||
return goog.math.Long.getZero();
|
||||
} else if (other.isZero()) {
|
||||
return goog.math.Long.getZero();
|
||||
}
|
||||
|
||||
if (this.equals(goog.math.Long.getMinValue())) {
|
||||
return other.isOdd() ? goog.math.Long.getMinValue() :
|
||||
goog.math.Long.getZero();
|
||||
} else if (other.equals(goog.math.Long.getMinValue())) {
|
||||
return this.isOdd() ? goog.math.Long.getMinValue() :
|
||||
goog.math.Long.getZero();
|
||||
}
|
||||
|
||||
if (this.isNegative()) {
|
||||
if (other.isNegative()) {
|
||||
return this.negate().multiply(other.negate());
|
||||
} else {
|
||||
return this.negate().multiply(other).negate();
|
||||
}
|
||||
} else if (other.isNegative()) {
|
||||
return this.multiply(other.negate()).negate();
|
||||
}
|
||||
|
||||
// If both longs are small, use float multiplication
|
||||
if (this.lessThan(goog.math.Long.getTwoPwr24()) &&
|
||||
other.lessThan(goog.math.Long.getTwoPwr24())) {
|
||||
return goog.math.Long.fromNumber(this.toNumber() * other.toNumber());
|
||||
}
|
||||
|
||||
// Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
|
||||
// We can skip products that would overflow.
|
||||
|
||||
var a48 = this.high_ >>> 16;
|
||||
var a32 = this.high_ & 0xFFFF;
|
||||
var a16 = this.low_ >>> 16;
|
||||
var a00 = this.low_ & 0xFFFF;
|
||||
|
||||
var b48 = other.high_ >>> 16;
|
||||
var b32 = other.high_ & 0xFFFF;
|
||||
var b16 = other.low_ >>> 16;
|
||||
var b00 = other.low_ & 0xFFFF;
|
||||
|
||||
var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
|
||||
c00 += a00 * b00;
|
||||
c16 += c00 >>> 16;
|
||||
c00 &= 0xFFFF;
|
||||
c16 += a16 * b00;
|
||||
c32 += c16 >>> 16;
|
||||
c16 &= 0xFFFF;
|
||||
c16 += a00 * b16;
|
||||
c32 += c16 >>> 16;
|
||||
c16 &= 0xFFFF;
|
||||
c32 += a32 * b00;
|
||||
c48 += c32 >>> 16;
|
||||
c32 &= 0xFFFF;
|
||||
c32 += a16 * b16;
|
||||
c48 += c32 >>> 16;
|
||||
c32 &= 0xFFFF;
|
||||
c32 += a00 * b32;
|
||||
c48 += c32 >>> 16;
|
||||
c32 &= 0xFFFF;
|
||||
c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
|
||||
c48 &= 0xFFFF;
|
||||
return goog.math.Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Long divided by the given one.
|
||||
* @param {goog.math.Long} other Long by which to divide.
|
||||
* @return {!goog.math.Long} This Long divided by the given one.
|
||||
*/
|
||||
goog.math.Long.prototype.div = function(other) {
|
||||
if (other.isZero()) {
|
||||
throw Error('division by zero');
|
||||
} else if (this.isZero()) {
|
||||
return goog.math.Long.getZero();
|
||||
}
|
||||
|
||||
if (this.equals(goog.math.Long.getMinValue())) {
|
||||
if (other.equals(goog.math.Long.getOne()) ||
|
||||
other.equals(goog.math.Long.getNegOne())) {
|
||||
return goog.math.Long.getMinValue(); // recall -MIN_VALUE == MIN_VALUE
|
||||
} else if (other.equals(goog.math.Long.getMinValue())) {
|
||||
return goog.math.Long.getOne();
|
||||
} else {
|
||||
// At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
|
||||
var halfThis = this.shiftRight(1);
|
||||
var approx = halfThis.div(other).shiftLeft(1);
|
||||
if (approx.equals(goog.math.Long.getZero())) {
|
||||
return other.isNegative() ? goog.math.Long.getOne() :
|
||||
goog.math.Long.getNegOne();
|
||||
} else {
|
||||
var rem = this.subtract(other.multiply(approx));
|
||||
var result = approx.add(rem.div(other));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} else if (other.equals(goog.math.Long.getMinValue())) {
|
||||
return goog.math.Long.getZero();
|
||||
}
|
||||
|
||||
if (this.isNegative()) {
|
||||
if (other.isNegative()) {
|
||||
return this.negate().div(other.negate());
|
||||
} else {
|
||||
return this.negate().div(other).negate();
|
||||
}
|
||||
} else if (other.isNegative()) {
|
||||
return this.div(other.negate()).negate();
|
||||
}
|
||||
|
||||
// Repeat the following until the remainder is less than other: find a
|
||||
// floating-point that approximates remainder / other *from below*, add this
|
||||
// into the result, and subtract it from the remainder. It is critical that
|
||||
// the approximate value is less than or equal to the real value so that the
|
||||
// remainder never becomes negative.
|
||||
var res = goog.math.Long.getZero();
|
||||
var rem = this;
|
||||
while (rem.greaterThanOrEqual(other)) {
|
||||
// Approximate the result of division. This may be a little greater or
|
||||
// smaller than the actual value.
|
||||
var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber()));
|
||||
|
||||
// We will tweak the approximate result by changing it in the 48-th digit or
|
||||
// the smallest non-fractional digit, whichever is larger.
|
||||
var log2 = Math.ceil(Math.log(approx) / Math.LN2);
|
||||
var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48);
|
||||
|
||||
// Decrease the approximation until it is smaller than the remainder. Note
|
||||
// that if it is too large, the product overflows and is negative.
|
||||
var approxRes = goog.math.Long.fromNumber(approx);
|
||||
var approxRem = approxRes.multiply(other);
|
||||
while (approxRem.isNegative() || approxRem.greaterThan(rem)) {
|
||||
approx -= delta;
|
||||
approxRes = goog.math.Long.fromNumber(approx);
|
||||
approxRem = approxRes.multiply(other);
|
||||
}
|
||||
|
||||
// We know the answer can't be zero... and actually, zero would cause
|
||||
// infinite recursion since we would make no progress.
|
||||
if (approxRes.isZero()) {
|
||||
approxRes = goog.math.Long.getOne();
|
||||
}
|
||||
|
||||
res = res.add(approxRes);
|
||||
rem = rem.subtract(approxRem);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Long modulo the given one.
|
||||
* @param {goog.math.Long} other Long by which to mod.
|
||||
* @return {!goog.math.Long} This Long modulo the given one.
|
||||
*/
|
||||
goog.math.Long.prototype.modulo = function(other) {
|
||||
return this.subtract(this.div(other).multiply(other));
|
||||
};
|
||||
|
||||
|
||||
/** @return {!goog.math.Long} The bitwise-NOT of this value. */
|
||||
goog.math.Long.prototype.not = function() {
|
||||
return goog.math.Long.fromBits(~this.low_, ~this.high_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bitwise-AND of this Long and the given one.
|
||||
* @param {goog.math.Long} other The Long with which to AND.
|
||||
* @return {!goog.math.Long} The bitwise-AND of this and the other.
|
||||
*/
|
||||
goog.math.Long.prototype.and = function(other) {
|
||||
return goog.math.Long.fromBits(
|
||||
this.low_ & other.low_, this.high_ & other.high_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bitwise-OR of this Long and the given one.
|
||||
* @param {goog.math.Long} other The Long with which to OR.
|
||||
* @return {!goog.math.Long} The bitwise-OR of this and the other.
|
||||
*/
|
||||
goog.math.Long.prototype.or = function(other) {
|
||||
return goog.math.Long.fromBits(
|
||||
this.low_ | other.low_, this.high_ | other.high_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bitwise-XOR of this Long and the given one.
|
||||
* @param {goog.math.Long} other The Long with which to XOR.
|
||||
* @return {!goog.math.Long} The bitwise-XOR of this and the other.
|
||||
*/
|
||||
goog.math.Long.prototype.xor = function(other) {
|
||||
return goog.math.Long.fromBits(
|
||||
this.low_ ^ other.low_, this.high_ ^ other.high_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Long with bits shifted to the left by the given amount.
|
||||
* @param {number} numBits The number of bits by which to shift.
|
||||
* @return {!goog.math.Long} This shifted to the left by the given amount.
|
||||
*/
|
||||
goog.math.Long.prototype.shiftLeft = function(numBits) {
|
||||
numBits &= 63;
|
||||
if (numBits == 0) {
|
||||
return this;
|
||||
} else {
|
||||
var low = this.low_;
|
||||
if (numBits < 32) {
|
||||
var high = this.high_;
|
||||
return goog.math.Long.fromBits(
|
||||
low << numBits, (high << numBits) | (low >>> (32 - numBits)));
|
||||
} else {
|
||||
return goog.math.Long.fromBits(0, low << (numBits - 32));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Long with bits shifted to the right by the given amount.
|
||||
* The new leading bits match the current sign bit.
|
||||
* @param {number} numBits The number of bits by which to shift.
|
||||
* @return {!goog.math.Long} This shifted to the right by the given amount.
|
||||
*/
|
||||
goog.math.Long.prototype.shiftRight = function(numBits) {
|
||||
numBits &= 63;
|
||||
if (numBits == 0) {
|
||||
return this;
|
||||
} else {
|
||||
var high = this.high_;
|
||||
if (numBits < 32) {
|
||||
var low = this.low_;
|
||||
return goog.math.Long.fromBits(
|
||||
(low >>> numBits) | (high << (32 - numBits)), high >> numBits);
|
||||
} else {
|
||||
return goog.math.Long.fromBits(
|
||||
high >> (numBits - 32), high >= 0 ? 0 : -1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Long with bits shifted to the right by the given amount, with
|
||||
* zeros placed into the new leading bits.
|
||||
* @param {number} numBits The number of bits by which to shift.
|
||||
* @return {!goog.math.Long} This shifted to the right by the given amount, with
|
||||
* zeros placed into the new leading bits.
|
||||
*/
|
||||
goog.math.Long.prototype.shiftRightUnsigned = function(numBits) {
|
||||
numBits &= 63;
|
||||
if (numBits == 0) {
|
||||
return this;
|
||||
} else {
|
||||
var high = this.high_;
|
||||
if (numBits < 32) {
|
||||
var low = this.low_;
|
||||
return goog.math.Long.fromBits(
|
||||
(low >>> numBits) | (high << (32 - numBits)), high >>> numBits);
|
||||
} else if (numBits == 32) {
|
||||
return goog.math.Long.fromBits(high, 0);
|
||||
} else {
|
||||
return goog.math.Long.fromBits(high >>> (numBits - 32), 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {number} Ids of commonly requested Long instances.
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.ValueCacheId_ = {
|
||||
MAX_VALUE: 1,
|
||||
MIN_VALUE: 2,
|
||||
ZERO: 3,
|
||||
ONE: 4,
|
||||
NEG_ONE: 5,
|
||||
TWO_PWR_24: 6
|
||||
};
|
447
assets/viz/2/goog/math/math.js
Normal file
447
assets/viz/2/goog/math/math.js
Normal file
@ -0,0 +1,447 @@
|
||||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Additional mathematical functions.
|
||||
*/
|
||||
|
||||
goog.provide('goog.math');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
|
||||
|
||||
/**
|
||||
* Returns a random integer greater than or equal to 0 and less than {@code a}.
|
||||
* @param {number} a The upper bound for the random integer (exclusive).
|
||||
* @return {number} A random integer N such that 0 <= N < a.
|
||||
*/
|
||||
goog.math.randomInt = function(a) {
|
||||
return Math.floor(Math.random() * a);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a random number greater than or equal to {@code a} and less than
|
||||
* {@code b}.
|
||||
* @param {number} a The lower bound for the random number (inclusive).
|
||||
* @param {number} b The upper bound for the random number (exclusive).
|
||||
* @return {number} A random number N such that a <= N < b.
|
||||
*/
|
||||
goog.math.uniformRandom = function(a, b) {
|
||||
return a + Math.random() * (b - a);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Takes a number and clamps it to within the provided bounds.
|
||||
* @param {number} value The input number.
|
||||
* @param {number} min The minimum value to return.
|
||||
* @param {number} max The maximum value to return.
|
||||
* @return {number} The input number if it is within bounds, or the nearest
|
||||
* number within the bounds.
|
||||
*/
|
||||
goog.math.clamp = function(value, min, max) {
|
||||
return Math.min(Math.max(value, min), max);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The % operator in JavaScript returns the remainder of a / b, but differs from
|
||||
* some other languages in that the result will have the same sign as the
|
||||
* dividend. For example, -1 % 8 == -1, whereas in some other languages
|
||||
* (such as Python) the result would be 7. This function emulates the more
|
||||
* correct modulo behavior, which is useful for certain applications such as
|
||||
* calculating an offset index in a circular list.
|
||||
*
|
||||
* @param {number} a The dividend.
|
||||
* @param {number} b The divisor.
|
||||
* @return {number} a % b where the result is between 0 and b (either 0 <= x < b
|
||||
* or b < x <= 0, depending on the sign of b).
|
||||
*/
|
||||
goog.math.modulo = function(a, b) {
|
||||
var r = a % b;
|
||||
// If r and b differ in sign, add b to wrap the result to the correct sign.
|
||||
return (r * b < 0) ? r + b : r;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs linear interpolation between values a and b. Returns the value
|
||||
* between a and b proportional to x (when x is between 0 and 1. When x is
|
||||
* outside this range, the return value is a linear extrapolation).
|
||||
* @param {number} a A number.
|
||||
* @param {number} b A number.
|
||||
* @param {number} x The proportion between a and b.
|
||||
* @return {number} The interpolated value between a and b.
|
||||
*/
|
||||
goog.math.lerp = function(a, b, x) {
|
||||
return a + x * (b - a);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tests whether the two values are equal to each other, within a certain
|
||||
* tolerance to adjust for floating point errors.
|
||||
* @param {number} a A number.
|
||||
* @param {number} b A number.
|
||||
* @param {number=} opt_tolerance Optional tolerance range. Defaults
|
||||
* to 0.000001. If specified, should be greater than 0.
|
||||
* @return {boolean} Whether {@code a} and {@code b} are nearly equal.
|
||||
*/
|
||||
goog.math.nearlyEquals = function(a, b, opt_tolerance) {
|
||||
return Math.abs(a - b) <= (opt_tolerance || 0.000001);
|
||||
};
|
||||
|
||||
|
||||
// TODO(user): Rename to normalizeAngle, retaining old name as deprecated
|
||||
// alias.
|
||||
/**
|
||||
* Normalizes an angle to be in range [0-360). Angles outside this range will
|
||||
* be normalized to be the equivalent angle with that range.
|
||||
* @param {number} angle Angle in degrees.
|
||||
* @return {number} Standardized angle.
|
||||
*/
|
||||
goog.math.standardAngle = function(angle) {
|
||||
return goog.math.modulo(angle, 360);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes an angle to be in range [0-2*PI). Angles outside this range will
|
||||
* be normalized to be the equivalent angle with that range.
|
||||
* @param {number} angle Angle in radians.
|
||||
* @return {number} Standardized angle.
|
||||
*/
|
||||
goog.math.standardAngleInRadians = function(angle) {
|
||||
return goog.math.modulo(angle, 2 * Math.PI);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts degrees to radians.
|
||||
* @param {number} angleDegrees Angle in degrees.
|
||||
* @return {number} Angle in radians.
|
||||
*/
|
||||
goog.math.toRadians = function(angleDegrees) {
|
||||
return angleDegrees * Math.PI / 180;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts radians to degrees.
|
||||
* @param {number} angleRadians Angle in radians.
|
||||
* @return {number} Angle in degrees.
|
||||
*/
|
||||
goog.math.toDegrees = function(angleRadians) {
|
||||
return angleRadians * 180 / Math.PI;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* For a given angle and radius, finds the X portion of the offset.
|
||||
* @param {number} degrees Angle in degrees (zero points in +X direction).
|
||||
* @param {number} radius Radius.
|
||||
* @return {number} The x-distance for the angle and radius.
|
||||
*/
|
||||
goog.math.angleDx = function(degrees, radius) {
|
||||
return radius * Math.cos(goog.math.toRadians(degrees));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* For a given angle and radius, finds the Y portion of the offset.
|
||||
* @param {number} degrees Angle in degrees (zero points in +X direction).
|
||||
* @param {number} radius Radius.
|
||||
* @return {number} The y-distance for the angle and radius.
|
||||
*/
|
||||
goog.math.angleDy = function(degrees, radius) {
|
||||
return radius * Math.sin(goog.math.toRadians(degrees));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Computes the angle between two points (x1,y1) and (x2,y2).
|
||||
* Angle zero points in the +X direction, 90 degrees points in the +Y
|
||||
* direction (down) and from there we grow clockwise towards 360 degrees.
|
||||
* @param {number} x1 x of first point.
|
||||
* @param {number} y1 y of first point.
|
||||
* @param {number} x2 x of second point.
|
||||
* @param {number} y2 y of second point.
|
||||
* @return {number} Standardized angle in degrees of the vector from
|
||||
* x1,y1 to x2,y2.
|
||||
*/
|
||||
goog.math.angle = function(x1, y1, x2, y2) {
|
||||
return goog.math.standardAngle(
|
||||
goog.math.toDegrees(Math.atan2(y2 - y1, x2 - x1)));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Computes the difference between startAngle and endAngle (angles in degrees).
|
||||
* @param {number} startAngle Start angle in degrees.
|
||||
* @param {number} endAngle End angle in degrees.
|
||||
* @return {number} The number of degrees that when added to
|
||||
* startAngle will result in endAngle. Positive numbers mean that the
|
||||
* direction is clockwise. Negative numbers indicate a counter-clockwise
|
||||
* direction.
|
||||
* The shortest route (clockwise vs counter-clockwise) between the angles
|
||||
* is used.
|
||||
* When the difference is 180 degrees, the function returns 180 (not -180)
|
||||
* angleDifference(30, 40) is 10, and angleDifference(40, 30) is -10.
|
||||
* angleDifference(350, 10) is 20, and angleDifference(10, 350) is -20.
|
||||
*/
|
||||
goog.math.angleDifference = function(startAngle, endAngle) {
|
||||
var d =
|
||||
goog.math.standardAngle(endAngle) - goog.math.standardAngle(startAngle);
|
||||
if (d > 180) {
|
||||
d = d - 360;
|
||||
} else if (d <= -180) {
|
||||
d = 360 + d;
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the sign of a number as per the "sign" or "signum" function.
|
||||
* @param {number} x The number to take the sign of.
|
||||
* @return {number} -1 when negative, 1 when positive, 0 when 0. Preserves
|
||||
* signed zeros and NaN.
|
||||
*/
|
||||
goog.math.sign = Math.sign || function(x) {
|
||||
if (x > 0) {
|
||||
return 1;
|
||||
}
|
||||
if (x < 0) {
|
||||
return -1;
|
||||
}
|
||||
return x; // Preserves signed zeros and NaN.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* JavaScript implementation of Longest Common Subsequence problem.
|
||||
* http://en.wikipedia.org/wiki/Longest_common_subsequence
|
||||
*
|
||||
* Returns the longest possible array that is subarray of both of given arrays.
|
||||
*
|
||||
* @param {IArrayLike<S>} array1 First array of objects.
|
||||
* @param {IArrayLike<T>} array2 Second array of objects.
|
||||
* @param {Function=} opt_compareFn Function that acts as a custom comparator
|
||||
* for the array ojects. Function should return true if objects are equal,
|
||||
* otherwise false.
|
||||
* @param {Function=} opt_collectorFn Function used to decide what to return
|
||||
* as a result subsequence. It accepts 2 arguments: index of common element
|
||||
* in the first array and index in the second. The default function returns
|
||||
* element from the first array.
|
||||
* @return {!Array<S|T>} A list of objects that are common to both arrays
|
||||
* such that there is no common subsequence with size greater than the
|
||||
* length of the list.
|
||||
* @template S,T
|
||||
*/
|
||||
goog.math.longestCommonSubsequence = function(
|
||||
array1, array2, opt_compareFn, opt_collectorFn) {
|
||||
|
||||
var compare = opt_compareFn || function(a, b) { return a == b; };
|
||||
|
||||
var collect = opt_collectorFn || function(i1, i2) { return array1[i1]; };
|
||||
|
||||
var length1 = array1.length;
|
||||
var length2 = array2.length;
|
||||
|
||||
var arr = [];
|
||||
for (var i = 0; i < length1 + 1; i++) {
|
||||
arr[i] = [];
|
||||
arr[i][0] = 0;
|
||||
}
|
||||
|
||||
for (var j = 0; j < length2 + 1; j++) {
|
||||
arr[0][j] = 0;
|
||||
}
|
||||
|
||||
for (i = 1; i <= length1; i++) {
|
||||
for (j = 1; j <= length2; j++) {
|
||||
if (compare(array1[i - 1], array2[j - 1])) {
|
||||
arr[i][j] = arr[i - 1][j - 1] + 1;
|
||||
} else {
|
||||
arr[i][j] = Math.max(arr[i - 1][j], arr[i][j - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Backtracking
|
||||
var result = [];
|
||||
var i = length1, j = length2;
|
||||
while (i > 0 && j > 0) {
|
||||
if (compare(array1[i - 1], array2[j - 1])) {
|
||||
result.unshift(collect(i - 1, j - 1));
|
||||
i--;
|
||||
j--;
|
||||
} else {
|
||||
if (arr[i - 1][j] > arr[i][j - 1]) {
|
||||
i--;
|
||||
} else {
|
||||
j--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the sum of the arguments.
|
||||
* @param {...number} var_args Numbers to add.
|
||||
* @return {number} The sum of the arguments (0 if no arguments were provided,
|
||||
* {@code NaN} if any of the arguments is not a valid number).
|
||||
*/
|
||||
goog.math.sum = function(var_args) {
|
||||
return /** @type {number} */ (
|
||||
goog.array.reduce(
|
||||
arguments, function(sum, value) { return sum + value; }, 0));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the arithmetic mean of the arguments.
|
||||
* @param {...number} var_args Numbers to average.
|
||||
* @return {number} The average of the arguments ({@code NaN} if no arguments
|
||||
* were provided or any of the arguments is not a valid number).
|
||||
*/
|
||||
goog.math.average = function(var_args) {
|
||||
return goog.math.sum.apply(null, arguments) / arguments.length;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the unbiased sample variance of the arguments. For a definition,
|
||||
* see e.g. http://en.wikipedia.org/wiki/Variance
|
||||
* @param {...number} var_args Number samples to analyze.
|
||||
* @return {number} The unbiased sample variance of the arguments (0 if fewer
|
||||
* than two samples were provided, or {@code NaN} if any of the samples is
|
||||
* not a valid number).
|
||||
*/
|
||||
goog.math.sampleVariance = function(var_args) {
|
||||
var sampleSize = arguments.length;
|
||||
if (sampleSize < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var mean = goog.math.average.apply(null, arguments);
|
||||
var variance =
|
||||
goog.math.sum.apply(null, goog.array.map(arguments, function(val) {
|
||||
return Math.pow(val - mean, 2);
|
||||
})) / (sampleSize - 1);
|
||||
|
||||
return variance;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the sample standard deviation of the arguments. For a definition of
|
||||
* sample standard deviation, see e.g.
|
||||
* http://en.wikipedia.org/wiki/Standard_deviation
|
||||
* @param {...number} var_args Number samples to analyze.
|
||||
* @return {number} The sample standard deviation of the arguments (0 if fewer
|
||||
* than two samples were provided, or {@code NaN} if any of the samples is
|
||||
* not a valid number).
|
||||
*/
|
||||
goog.math.standardDeviation = function(var_args) {
|
||||
return Math.sqrt(goog.math.sampleVariance.apply(null, arguments));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the supplied number represents an integer, i.e. that is has
|
||||
* no fractional component. No range-checking is performed on the number.
|
||||
* @param {number} num The number to test.
|
||||
* @return {boolean} Whether {@code num} is an integer.
|
||||
*/
|
||||
goog.math.isInt = function(num) {
|
||||
return isFinite(num) && num % 1 == 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the supplied number is finite and not NaN.
|
||||
* @param {number} num The number to test.
|
||||
* @return {boolean} Whether {@code num} is a finite number.
|
||||
*/
|
||||
goog.math.isFiniteNumber = function(num) {
|
||||
return isFinite(num) && !isNaN(num);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} num The number to test.
|
||||
* @return {boolean} Whether it is negative zero.
|
||||
*/
|
||||
goog.math.isNegativeZero = function(num) {
|
||||
return num == 0 && 1 / num < 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the precise value of floor(log10(num)).
|
||||
* Simpler implementations didn't work because of floating point rounding
|
||||
* errors. For example
|
||||
* <ul>
|
||||
* <li>Math.floor(Math.log(num) / Math.LN10) is off by one for num == 1e+3.
|
||||
* <li>Math.floor(Math.log(num) * Math.LOG10E) is off by one for num == 1e+15.
|
||||
* <li>Math.floor(Math.log10(num)) is off by one for num == 1e+15 - 1.
|
||||
* </ul>
|
||||
* @param {number} num A floating point number.
|
||||
* @return {number} Its logarithm to base 10 rounded down to the nearest
|
||||
* integer if num > 0. -Infinity if num == 0. NaN if num < 0.
|
||||
*/
|
||||
goog.math.log10Floor = function(num) {
|
||||
if (num > 0) {
|
||||
var x = Math.round(Math.log(num) * Math.LOG10E);
|
||||
return x - (parseFloat('1e' + x) > num ? 1 : 0);
|
||||
}
|
||||
return num == 0 ? -Infinity : NaN;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A tweaked variant of {@code Math.floor} which tolerates if the passed number
|
||||
* is infinitesimally smaller than the closest integer. It often happens with
|
||||
* the results of floating point calculations because of the finite precision
|
||||
* of the intermediate results. For example {@code Math.floor(Math.log(1000) /
|
||||
* Math.LN10) == 2}, not 3 as one would expect.
|
||||
* @param {number} num A number.
|
||||
* @param {number=} opt_epsilon An infinitesimally small positive number, the
|
||||
* rounding error to tolerate.
|
||||
* @return {number} The largest integer less than or equal to {@code num}.
|
||||
*/
|
||||
goog.math.safeFloor = function(num, opt_epsilon) {
|
||||
goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0);
|
||||
return Math.floor(num + (opt_epsilon || 2e-15));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A tweaked variant of {@code Math.ceil}. See {@code goog.math.safeFloor} for
|
||||
* details.
|
||||
* @param {number} num A number.
|
||||
* @param {number=} opt_epsilon An infinitesimally small positive number, the
|
||||
* rounding error to tolerate.
|
||||
* @return {number} The smallest integer greater than or equal to {@code num}.
|
||||
*/
|
||||
goog.math.safeCeil = function(num, opt_epsilon) {
|
||||
goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0);
|
||||
return Math.ceil(num - (opt_epsilon || 2e-15));
|
||||
};
|
227
assets/viz/2/goog/math/size.js
Normal file
227
assets/viz/2/goog/math/size.js
Normal file
@ -0,0 +1,227 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A utility class for representing two-dimensional sizes.
|
||||
* @author brenneman@google.com (Shawn Brenneman)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.math.Size');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class for representing sizes consisting of a width and height. Undefined
|
||||
* width and height support is deprecated and results in compiler warning.
|
||||
* @param {number} width Width.
|
||||
* @param {number} height Height.
|
||||
* @struct
|
||||
* @constructor
|
||||
*/
|
||||
goog.math.Size = function(width, height) {
|
||||
/**
|
||||
* Width
|
||||
* @type {number}
|
||||
*/
|
||||
this.width = width;
|
||||
|
||||
/**
|
||||
* Height
|
||||
* @type {number}
|
||||
*/
|
||||
this.height = height;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compares sizes for equality.
|
||||
* @param {goog.math.Size} a A Size.
|
||||
* @param {goog.math.Size} b A Size.
|
||||
* @return {boolean} True iff the sizes have equal widths and equal
|
||||
* heights, or if both are null.
|
||||
*/
|
||||
goog.math.Size.equals = function(a, b) {
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
if (!a || !b) {
|
||||
return false;
|
||||
}
|
||||
return a.width == b.width && a.height == b.height;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Size} A new copy of the Size.
|
||||
*/
|
||||
goog.math.Size.prototype.clone = function() {
|
||||
return new goog.math.Size(this.width, this.height);
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a nice string representing size.
|
||||
* @return {string} In the form (50 x 73).
|
||||
* @override
|
||||
*/
|
||||
goog.math.Size.prototype.toString = function() {
|
||||
return '(' + this.width + ' x ' + this.height + ')';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The longer of the two dimensions in the size.
|
||||
*/
|
||||
goog.math.Size.prototype.getLongest = function() {
|
||||
return Math.max(this.width, this.height);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The shorter of the two dimensions in the size.
|
||||
*/
|
||||
goog.math.Size.prototype.getShortest = function() {
|
||||
return Math.min(this.width, this.height);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The area of the size (width * height).
|
||||
*/
|
||||
goog.math.Size.prototype.area = function() {
|
||||
return this.width * this.height;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The perimeter of the size (width + height) * 2.
|
||||
*/
|
||||
goog.math.Size.prototype.perimeter = function() {
|
||||
return (this.width + this.height) * 2;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The ratio of the size's width to its height.
|
||||
*/
|
||||
goog.math.Size.prototype.aspectRatio = function() {
|
||||
return this.width / this.height;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} True if the size has zero area, false if both dimensions
|
||||
* are non-zero numbers.
|
||||
*/
|
||||
goog.math.Size.prototype.isEmpty = function() {
|
||||
return !this.area();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the width and height parameters upward to integer values.
|
||||
* @return {!goog.math.Size} This size with ceil'd components.
|
||||
*/
|
||||
goog.math.Size.prototype.ceil = function() {
|
||||
this.width = Math.ceil(this.width);
|
||||
this.height = Math.ceil(this.height);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!goog.math.Size} target The target size.
|
||||
* @return {boolean} True if this Size is the same size or smaller than the
|
||||
* target size in both dimensions.
|
||||
*/
|
||||
goog.math.Size.prototype.fitsInside = function(target) {
|
||||
return this.width <= target.width && this.height <= target.height;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the width and height parameters downward to integer values.
|
||||
* @return {!goog.math.Size} This size with floored components.
|
||||
*/
|
||||
goog.math.Size.prototype.floor = function() {
|
||||
this.width = Math.floor(this.width);
|
||||
this.height = Math.floor(this.height);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rounds the width and height parameters to integer values.
|
||||
* @return {!goog.math.Size} This size with rounded components.
|
||||
*/
|
||||
goog.math.Size.prototype.round = function() {
|
||||
this.width = Math.round(this.width);
|
||||
this.height = Math.round(this.height);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Scales this size by the given scale factors. The width and height are scaled
|
||||
* by {@code sx} and {@code opt_sy} respectively. If {@code opt_sy} is not
|
||||
* given, then {@code sx} is used for both the width and height.
|
||||
* @param {number} sx The scale factor to use for the width.
|
||||
* @param {number=} opt_sy The scale factor to use for the height.
|
||||
* @return {!goog.math.Size} This Size object after scaling.
|
||||
*/
|
||||
goog.math.Size.prototype.scale = function(sx, opt_sy) {
|
||||
var sy = goog.isNumber(opt_sy) ? opt_sy : sx;
|
||||
this.width *= sx;
|
||||
this.height *= sy;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Uniformly scales the size to perfectly cover the dimensions of a given size.
|
||||
* If the size is already larger than the target, it will be scaled down to the
|
||||
* minimum size at which it still covers the entire target. The original aspect
|
||||
* ratio will be preserved.
|
||||
*
|
||||
* This function assumes that both Sizes contain strictly positive dimensions.
|
||||
* @param {!goog.math.Size} target The target size.
|
||||
* @return {!goog.math.Size} This Size object, after optional scaling.
|
||||
*/
|
||||
goog.math.Size.prototype.scaleToCover = function(target) {
|
||||
var s = this.aspectRatio() <= target.aspectRatio() ?
|
||||
target.width / this.width :
|
||||
target.height / this.height;
|
||||
|
||||
return this.scale(s);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Uniformly scales the size to fit inside the dimensions of a given size. The
|
||||
* original aspect ratio will be preserved.
|
||||
*
|
||||
* This function assumes that both Sizes contain strictly positive dimensions.
|
||||
* @param {!goog.math.Size} target The target size.
|
||||
* @return {!goog.math.Size} This Size object, after optional scaling.
|
||||
*/
|
||||
goog.math.Size.prototype.scaleToFit = function(target) {
|
||||
var s = this.aspectRatio() > target.aspectRatio() ?
|
||||
target.width / this.width :
|
||||
target.height / this.height;
|
||||
|
||||
return this.scale(s);
|
||||
};
|
705
assets/viz/2/goog/object/object.js
Normal file
705
assets/viz/2/goog/object/object.js
Normal file
@ -0,0 +1,705 @@
|
||||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities for manipulating objects/maps/hashes.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*/
|
||||
|
||||
goog.provide('goog.object');
|
||||
|
||||
|
||||
/**
|
||||
* Whether two values are not observably distinguishable. This
|
||||
* correctly detects that 0 is not the same as -0 and two NaNs are
|
||||
* practically equivalent.
|
||||
*
|
||||
* The implementation is as suggested by harmony:egal proposal.
|
||||
*
|
||||
* @param {*} v The first value to compare.
|
||||
* @param {*} v2 The second value to compare.
|
||||
* @return {boolean} Whether two values are not observably distinguishable.
|
||||
* @see http://wiki.ecmascript.org/doku.php?id=harmony:egal
|
||||
*/
|
||||
goog.object.is = function(v, v2) {
|
||||
if (v === v2) {
|
||||
// 0 === -0, but they are not identical.
|
||||
// We need the cast because the compiler requires that v2 is a
|
||||
// number (although 1/v2 works with non-number). We cast to ? to
|
||||
// stop the compiler from type-checking this statement.
|
||||
return v !== 0 || 1 / v === 1 / /** @type {?} */ (v2);
|
||||
}
|
||||
|
||||
// NaN is non-reflexive: NaN !== NaN, although they are identical.
|
||||
return v !== v && v2 !== v2;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls a function for each element in an object/map/hash.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object over which to iterate.
|
||||
* @param {function(this:T,V,?,Object<K,V>):?} f The function to call
|
||||
* for every element. This function takes 3 arguments (the value, the
|
||||
* key and the object) and the return value is ignored.
|
||||
* @param {T=} opt_obj This is used as the 'this' object within f.
|
||||
* @template T,K,V
|
||||
*/
|
||||
goog.object.forEach = function(obj, f, opt_obj) {
|
||||
for (var key in obj) {
|
||||
f.call(/** @type {?} */ (opt_obj), obj[key], key, obj);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls a function for each element in an object/map/hash. If that call returns
|
||||
* true, adds the element to a new object.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object over which to iterate.
|
||||
* @param {function(this:T,V,?,Object<K,V>):boolean} f The function to call
|
||||
* for every element. This
|
||||
* function takes 3 arguments (the value, the key and the object)
|
||||
* and should return a boolean. If the return value is true the
|
||||
* element is added to the result object. If it is false the
|
||||
* element is not included.
|
||||
* @param {T=} opt_obj This is used as the 'this' object within f.
|
||||
* @return {!Object<K,V>} a new object in which only elements that passed the
|
||||
* test are present.
|
||||
* @template T,K,V
|
||||
*/
|
||||
goog.object.filter = function(obj, f, opt_obj) {
|
||||
var res = {};
|
||||
for (var key in obj) {
|
||||
if (f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) {
|
||||
res[key] = obj[key];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* For every element in an object/map/hash calls a function and inserts the
|
||||
* result into a new object.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object over which to iterate.
|
||||
* @param {function(this:T,V,?,Object<K,V>):R} f The function to call
|
||||
* for every element. This function
|
||||
* takes 3 arguments (the value, the key and the object)
|
||||
* and should return something. The result will be inserted
|
||||
* into a new object.
|
||||
* @param {T=} opt_obj This is used as the 'this' object within f.
|
||||
* @return {!Object<K,R>} a new object with the results from f.
|
||||
* @template T,K,V,R
|
||||
*/
|
||||
goog.object.map = function(obj, f, opt_obj) {
|
||||
var res = {};
|
||||
for (var key in obj) {
|
||||
res[key] = f.call(/** @type {?} */ (opt_obj), obj[key], key, obj);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls a function for each element in an object/map/hash. If any
|
||||
* call returns true, returns true (without checking the rest). If
|
||||
* all calls return false, returns false.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object to check.
|
||||
* @param {function(this:T,V,?,Object<K,V>):boolean} f The function to
|
||||
* call for every element. This function
|
||||
* takes 3 arguments (the value, the key and the object) and should
|
||||
* return a boolean.
|
||||
* @param {T=} opt_obj This is used as the 'this' object within f.
|
||||
* @return {boolean} true if any element passes the test.
|
||||
* @template T,K,V
|
||||
*/
|
||||
goog.object.some = function(obj, f, opt_obj) {
|
||||
for (var key in obj) {
|
||||
if (f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls a function for each element in an object/map/hash. If
|
||||
* all calls return true, returns true. If any call returns false, returns
|
||||
* false at this point and does not continue to check the remaining elements.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object to check.
|
||||
* @param {?function(this:T,V,?,Object<K,V>):boolean} f The function to
|
||||
* call for every element. This function
|
||||
* takes 3 arguments (the value, the key and the object) and should
|
||||
* return a boolean.
|
||||
* @param {T=} opt_obj This is used as the 'this' object within f.
|
||||
* @return {boolean} false if any element fails the test.
|
||||
* @template T,K,V
|
||||
*/
|
||||
goog.object.every = function(obj, f, opt_obj) {
|
||||
for (var key in obj) {
|
||||
if (!f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of key-value pairs in the object map.
|
||||
*
|
||||
* @param {Object} obj The object for which to get the number of key-value
|
||||
* pairs.
|
||||
* @return {number} The number of key-value pairs in the object map.
|
||||
*/
|
||||
goog.object.getCount = function(obj) {
|
||||
var rv = 0;
|
||||
for (var key in obj) {
|
||||
rv++;
|
||||
}
|
||||
return rv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns one key from the object map, if any exists.
|
||||
* For map literals the returned key will be the first one in most of the
|
||||
* browsers (a know exception is Konqueror).
|
||||
*
|
||||
* @param {Object} obj The object to pick a key from.
|
||||
* @return {string|undefined} The key or undefined if the object is empty.
|
||||
*/
|
||||
goog.object.getAnyKey = function(obj) {
|
||||
for (var key in obj) {
|
||||
return key;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns one value from the object map, if any exists.
|
||||
* For map literals the returned value will be the first one in most of the
|
||||
* browsers (a know exception is Konqueror).
|
||||
*
|
||||
* @param {Object<K,V>} obj The object to pick a value from.
|
||||
* @return {V|undefined} The value or undefined if the object is empty.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.getAnyValue = function(obj) {
|
||||
for (var key in obj) {
|
||||
return obj[key];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the object/hash/map contains the given object as a value.
|
||||
* An alias for goog.object.containsValue(obj, val).
|
||||
*
|
||||
* @param {Object<K,V>} obj The object in which to look for val.
|
||||
* @param {V} val The object for which to check.
|
||||
* @return {boolean} true if val is present.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.contains = function(obj, val) {
|
||||
return goog.object.containsValue(obj, val);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the values of the object/map/hash.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object from which to get the values.
|
||||
* @return {!Array<V>} The values in the object/map/hash.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.getValues = function(obj) {
|
||||
var res = [];
|
||||
var i = 0;
|
||||
for (var key in obj) {
|
||||
res[i++] = obj[key];
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the keys of the object/map/hash.
|
||||
*
|
||||
* @param {Object} obj The object from which to get the keys.
|
||||
* @return {!Array<string>} Array of property keys.
|
||||
*/
|
||||
goog.object.getKeys = function(obj) {
|
||||
var res = [];
|
||||
var i = 0;
|
||||
for (var key in obj) {
|
||||
res[i++] = key;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get a value from an object multiple levels deep. This is useful for
|
||||
* pulling values from deeply nested objects, such as JSON responses.
|
||||
* Example usage: getValueByKeys(jsonObj, 'foo', 'entries', 3)
|
||||
*
|
||||
* @param {!Object} obj An object to get the value from. Can be array-like.
|
||||
* @param {...(string|number|!IArrayLike<number|string>)}
|
||||
* var_args A number of keys
|
||||
* (as strings, or numbers, for array-like objects). Can also be
|
||||
* specified as a single array of keys.
|
||||
* @return {*} The resulting value. If, at any point, the value for a key
|
||||
* is undefined, returns undefined.
|
||||
*/
|
||||
goog.object.getValueByKeys = function(obj, var_args) {
|
||||
var isArrayLike = goog.isArrayLike(var_args);
|
||||
var keys = isArrayLike ? var_args : arguments;
|
||||
|
||||
// Start with the 2nd parameter for the variable parameters syntax.
|
||||
for (var i = isArrayLike ? 0 : 1; i < keys.length; i++) {
|
||||
obj = obj[keys[i]];
|
||||
if (!goog.isDef(obj)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the object/map/hash contains the given key.
|
||||
*
|
||||
* @param {Object} obj The object in which to look for key.
|
||||
* @param {?} key The key for which to check.
|
||||
* @return {boolean} true If the map contains the key.
|
||||
*/
|
||||
goog.object.containsKey = function(obj, key) {
|
||||
return obj !== null && key in obj;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the object/map/hash contains the given value. This is O(n).
|
||||
*
|
||||
* @param {Object<K,V>} obj The object in which to look for val.
|
||||
* @param {V} val The value for which to check.
|
||||
* @return {boolean} true If the map contains the value.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.containsValue = function(obj, val) {
|
||||
for (var key in obj) {
|
||||
if (obj[key] == val) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Searches an object for an element that satisfies the given condition and
|
||||
* returns its key.
|
||||
* @param {Object<K,V>} obj The object to search in.
|
||||
* @param {function(this:T,V,string,Object<K,V>):boolean} f The
|
||||
* function to call for every element. Takes 3 arguments (the value,
|
||||
* the key and the object) and should return a boolean.
|
||||
* @param {T=} opt_this An optional "this" context for the function.
|
||||
* @return {string|undefined} The key of an element for which the function
|
||||
* returns true or undefined if no such element is found.
|
||||
* @template T,K,V
|
||||
*/
|
||||
goog.object.findKey = function(obj, f, opt_this) {
|
||||
for (var key in obj) {
|
||||
if (f.call(/** @type {?} */ (opt_this), obj[key], key, obj)) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Searches an object for an element that satisfies the given condition and
|
||||
* returns its value.
|
||||
* @param {Object<K,V>} obj The object to search in.
|
||||
* @param {function(this:T,V,string,Object<K,V>):boolean} f The function
|
||||
* to call for every element. Takes 3 arguments (the value, the key
|
||||
* and the object) and should return a boolean.
|
||||
* @param {T=} opt_this An optional "this" context for the function.
|
||||
* @return {V} The value of an element for which the function returns true or
|
||||
* undefined if no such element is found.
|
||||
* @template T,K,V
|
||||
*/
|
||||
goog.object.findValue = function(obj, f, opt_this) {
|
||||
var key = goog.object.findKey(obj, f, opt_this);
|
||||
return key && obj[key];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the object/map/hash is empty.
|
||||
*
|
||||
* @param {Object} obj The object to test.
|
||||
* @return {boolean} true if obj is empty.
|
||||
*/
|
||||
goog.object.isEmpty = function(obj) {
|
||||
for (var key in obj) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes all key value pairs from the object/map/hash.
|
||||
*
|
||||
* @param {Object} obj The object to clear.
|
||||
*/
|
||||
goog.object.clear = function(obj) {
|
||||
for (var i in obj) {
|
||||
delete obj[i];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes a key-value pair based on the key.
|
||||
*
|
||||
* @param {Object} obj The object from which to remove the key.
|
||||
* @param {?} key The key to remove.
|
||||
* @return {boolean} Whether an element was removed.
|
||||
*/
|
||||
goog.object.remove = function(obj, key) {
|
||||
var rv;
|
||||
if (rv = key in /** @type {!Object} */ (obj)) {
|
||||
delete obj[key];
|
||||
}
|
||||
return rv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a key-value pair to the object. Throws an exception if the key is
|
||||
* already in use. Use set if you want to change an existing pair.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object to which to add the key-value pair.
|
||||
* @param {string} key The key to add.
|
||||
* @param {V} val The value to add.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.add = function(obj, key, val) {
|
||||
if (obj !== null && key in obj) {
|
||||
throw Error('The object already contains the key "' + key + '"');
|
||||
}
|
||||
goog.object.set(obj, key, val);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value for the given key.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object from which to get the value.
|
||||
* @param {string} key The key for which to get the value.
|
||||
* @param {R=} opt_val The value to return if no item is found for the given
|
||||
* key (default is undefined).
|
||||
* @return {V|R|undefined} The value for the given key.
|
||||
* @template K,V,R
|
||||
*/
|
||||
goog.object.get = function(obj, key, opt_val) {
|
||||
if (obj !== null && key in obj) {
|
||||
return obj[key];
|
||||
}
|
||||
return opt_val;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a key-value pair to the object/map/hash.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object to which to add the key-value pair.
|
||||
* @param {string} key The key to add.
|
||||
* @param {V} value The value to add.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.set = function(obj, key, value) {
|
||||
obj[key] = value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a key-value pair to the object/map/hash if it doesn't exist yet.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object to which to add the key-value pair.
|
||||
* @param {string} key The key to add.
|
||||
* @param {V} value The value to add if the key wasn't present.
|
||||
* @return {V} The value of the entry at the end of the function.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.setIfUndefined = function(obj, key, value) {
|
||||
return key in /** @type {!Object} */ (obj) ? obj[key] : (obj[key] = value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets a key and value to an object if the key is not set. The value will be
|
||||
* the return value of the given function. If the key already exists, the
|
||||
* object will not be changed and the function will not be called (the function
|
||||
* will be lazily evaluated -- only called if necessary).
|
||||
*
|
||||
* This function is particularly useful for use with a map used a as a cache.
|
||||
*
|
||||
* @param {!Object<K,V>} obj The object to which to add the key-value pair.
|
||||
* @param {string} key The key to add.
|
||||
* @param {function():V} f The value to add if the key wasn't present.
|
||||
* @return {V} The value of the entry at the end of the function.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.setWithReturnValueIfNotSet = function(obj, key, f) {
|
||||
if (key in obj) {
|
||||
return obj[key];
|
||||
}
|
||||
|
||||
var val = f();
|
||||
obj[key] = val;
|
||||
return val;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compares two objects for equality using === on the values.
|
||||
*
|
||||
* @param {!Object<K,V>} a
|
||||
* @param {!Object<K,V>} b
|
||||
* @return {boolean}
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.equals = function(a, b) {
|
||||
for (var k in a) {
|
||||
if (!(k in b) || a[k] !== b[k]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (var k in b) {
|
||||
if (!(k in a)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a shallow clone of the object.
|
||||
*
|
||||
* @param {Object<K,V>} obj Object to clone.
|
||||
* @return {!Object<K,V>} Clone of the input object.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.clone = function(obj) {
|
||||
// We cannot use the prototype trick because a lot of methods depend on where
|
||||
// the actual key is set.
|
||||
|
||||
var res = {};
|
||||
for (var key in obj) {
|
||||
res[key] = obj[key];
|
||||
}
|
||||
return res;
|
||||
// We could also use goog.mixin but I wanted this to be independent from that.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clones a value. The input may be an Object, Array, or basic type. Objects and
|
||||
* arrays will be cloned recursively.
|
||||
*
|
||||
* WARNINGS:
|
||||
* <code>goog.object.unsafeClone</code> does not detect reference loops. Objects
|
||||
* that refer to themselves will cause infinite recursion.
|
||||
*
|
||||
* <code>goog.object.unsafeClone</code> is unaware of unique identifiers, and
|
||||
* copies UIDs created by <code>getUid</code> into cloned results.
|
||||
*
|
||||
* @param {*} obj The value to clone.
|
||||
* @return {*} A clone of the input value.
|
||||
*/
|
||||
goog.object.unsafeClone = function(obj) {
|
||||
var type = goog.typeOf(obj);
|
||||
if (type == 'object' || type == 'array') {
|
||||
if (goog.isFunction(obj.clone)) {
|
||||
return obj.clone();
|
||||
}
|
||||
var clone = type == 'array' ? [] : {};
|
||||
for (var key in obj) {
|
||||
clone[key] = goog.object.unsafeClone(obj[key]);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new object in which all the keys and values are interchanged
|
||||
* (keys become values and values become keys). If multiple keys map to the
|
||||
* same value, the chosen transposed value is implementation-dependent.
|
||||
*
|
||||
* @param {Object} obj The object to transpose.
|
||||
* @return {!Object} The transposed object.
|
||||
*/
|
||||
goog.object.transpose = function(obj) {
|
||||
var transposed = {};
|
||||
for (var key in obj) {
|
||||
transposed[obj[key]] = key;
|
||||
}
|
||||
return transposed;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The names of the fields that are defined on Object.prototype.
|
||||
* @type {Array<string>}
|
||||
* @private
|
||||
*/
|
||||
goog.object.PROTOTYPE_FIELDS_ = [
|
||||
'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
|
||||
'toLocaleString', 'toString', 'valueOf'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Extends an object with another object.
|
||||
* This operates 'in-place'; it does not create a new Object.
|
||||
*
|
||||
* Example:
|
||||
* var o = {};
|
||||
* goog.object.extend(o, {a: 0, b: 1});
|
||||
* o; // {a: 0, b: 1}
|
||||
* goog.object.extend(o, {b: 2, c: 3});
|
||||
* o; // {a: 0, b: 2, c: 3}
|
||||
*
|
||||
* @param {Object} target The object to modify. Existing properties will be
|
||||
* overwritten if they are also present in one of the objects in
|
||||
* {@code var_args}.
|
||||
* @param {...Object} var_args The objects from which values will be copied.
|
||||
*/
|
||||
goog.object.extend = function(target, var_args) {
|
||||
var key, source;
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
source = arguments[i];
|
||||
for (key in source) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
|
||||
// For IE the for-in-loop does not contain any properties that are not
|
||||
// enumerable on the prototype object (for example isPrototypeOf from
|
||||
// Object.prototype) and it will also not include 'replace' on objects that
|
||||
// extend String and change 'replace' (not that it is common for anyone to
|
||||
// extend anything except Object).
|
||||
|
||||
for (var j = 0; j < goog.object.PROTOTYPE_FIELDS_.length; j++) {
|
||||
key = goog.object.PROTOTYPE_FIELDS_[j];
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new object built from the key-value pairs provided as arguments.
|
||||
* @param {...*} var_args If only one argument is provided and it is an array
|
||||
* then this is used as the arguments, otherwise even arguments are used as
|
||||
* the property names and odd arguments are used as the property values.
|
||||
* @return {!Object} The new object.
|
||||
* @throws {Error} If there are uneven number of arguments or there is only one
|
||||
* non array argument.
|
||||
*/
|
||||
goog.object.create = function(var_args) {
|
||||
var argLength = arguments.length;
|
||||
if (argLength == 1 && goog.isArray(arguments[0])) {
|
||||
return goog.object.create.apply(null, arguments[0]);
|
||||
}
|
||||
|
||||
if (argLength % 2) {
|
||||
throw Error('Uneven number of arguments');
|
||||
}
|
||||
|
||||
var rv = {};
|
||||
for (var i = 0; i < argLength; i += 2) {
|
||||
rv[arguments[i]] = arguments[i + 1];
|
||||
}
|
||||
return rv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new object where the property names come from the arguments but
|
||||
* the value is always set to true
|
||||
* @param {...*} var_args If only one argument is provided and it is an array
|
||||
* then this is used as the arguments, otherwise the arguments are used
|
||||
* as the property names.
|
||||
* @return {!Object} The new object.
|
||||
*/
|
||||
goog.object.createSet = function(var_args) {
|
||||
var argLength = arguments.length;
|
||||
if (argLength == 1 && goog.isArray(arguments[0])) {
|
||||
return goog.object.createSet.apply(null, arguments[0]);
|
||||
}
|
||||
|
||||
var rv = {};
|
||||
for (var i = 0; i < argLength; i++) {
|
||||
rv[arguments[i]] = true;
|
||||
}
|
||||
return rv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates an immutable view of the underlying object, if the browser
|
||||
* supports immutable objects.
|
||||
*
|
||||
* In default mode, writes to this view will fail silently. In strict mode,
|
||||
* they will throw an error.
|
||||
*
|
||||
* @param {!Object<K,V>} obj An object.
|
||||
* @return {!Object<K,V>} An immutable view of that object, or the
|
||||
* original object if this browser does not support immutables.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.createImmutableView = function(obj) {
|
||||
var result = obj;
|
||||
if (Object.isFrozen && !Object.isFrozen(obj)) {
|
||||
result = Object.create(obj);
|
||||
Object.freeze(result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!Object} obj An object.
|
||||
* @return {boolean} Whether this is an immutable view of the object.
|
||||
*/
|
||||
goog.object.isImmutableView = function(obj) {
|
||||
return !!Object.isFrozen && Object.isFrozen(obj);
|
||||
};
|
138
assets/viz/2/goog/reflect/reflect.js
Normal file
138
assets/viz/2/goog/reflect/reflect.js
Normal file
@ -0,0 +1,138 @@
|
||||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Useful compiler idioms.
|
||||
*
|
||||
* @author johnlenz@google.com (John Lenz)
|
||||
*/
|
||||
|
||||
goog.provide('goog.reflect');
|
||||
|
||||
|
||||
/**
|
||||
* Syntax for object literal casts.
|
||||
* @see http://go/jscompiler-renaming
|
||||
* @see https://goo.gl/CRs09P
|
||||
*
|
||||
* Use this if you have an object literal whose keys need to have the same names
|
||||
* as the properties of some class even after they are renamed by the compiler.
|
||||
*
|
||||
* @param {!Function} type Type to cast to.
|
||||
* @param {Object} object Object literal to cast.
|
||||
* @return {Object} The object literal.
|
||||
*/
|
||||
goog.reflect.object = function(type, object) {
|
||||
return object;
|
||||
};
|
||||
|
||||
/**
|
||||
* Syntax for renaming property strings.
|
||||
* @see http://go/jscompiler-renaming
|
||||
* @see https://goo.gl/CRs09P
|
||||
*
|
||||
* Use this if you have an need to access a property as a string, but want
|
||||
* to also have the property renamed by the compiler. In contrast to
|
||||
* goog.reflect.object, this method takes an instance of an object.
|
||||
*
|
||||
* Properties must be simple names (not qualified names).
|
||||
*
|
||||
* @param {string} prop Name of the property
|
||||
* @param {!Object} object Instance of the object whose type will be used
|
||||
* for renaming
|
||||
* @return {string} The renamed property.
|
||||
*/
|
||||
goog.reflect.objectProperty = function(prop, object) {
|
||||
return prop;
|
||||
};
|
||||
|
||||
/**
|
||||
* To assert to the compiler that an operation is needed when it would
|
||||
* otherwise be stripped. For example:
|
||||
* <code>
|
||||
* // Force a layout
|
||||
* goog.reflect.sinkValue(dialog.offsetHeight);
|
||||
* </code>
|
||||
* @param {T} x
|
||||
* @return {T}
|
||||
* @template T
|
||||
*/
|
||||
goog.reflect.sinkValue = function(x) {
|
||||
goog.reflect.sinkValue[' '](x);
|
||||
return x;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The compiler should optimize this function away iff no one ever uses
|
||||
* goog.reflect.sinkValue.
|
||||
*/
|
||||
goog.reflect.sinkValue[' '] = goog.nullFunction;
|
||||
|
||||
|
||||
/**
|
||||
* Check if a property can be accessed without throwing an exception.
|
||||
* @param {Object} obj The owner of the property.
|
||||
* @param {string} prop The property name.
|
||||
* @return {boolean} Whether the property is accessible. Will also return true
|
||||
* if obj is null.
|
||||
*/
|
||||
goog.reflect.canAccessProperty = function(obj, prop) {
|
||||
/** @preserveTry */
|
||||
try {
|
||||
goog.reflect.sinkValue(obj[prop]);
|
||||
return true;
|
||||
} catch (e) {
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a value from a cache given a key. The compiler provides special
|
||||
* consideration for this call such that it is generally considered side-effect
|
||||
* free. However, if the {@code opt_keyFn} or {@code valueFn} have side-effects
|
||||
* then the entire call is considered to have side-effects.
|
||||
*
|
||||
* Conventionally storing the value on the cache would be considered a
|
||||
* side-effect and preclude unused calls from being pruned, ie. even if
|
||||
* the value was never used, it would still always be stored in the cache.
|
||||
*
|
||||
* Providing a side-effect free {@code valueFn} and {@code opt_keyFn}
|
||||
* allows unused calls to {@code goog.cache} to be pruned.
|
||||
*
|
||||
* @param {!Object<K, V>} cacheObj The object that contains the cached values.
|
||||
* @param {?} key The key to lookup in the cache. If it is not string or number
|
||||
* then a {@code opt_keyFn} should be provided. The key is also used as the
|
||||
* parameter to the {@code valueFn}.
|
||||
* @param {!function(?):V} valueFn The value provider to use to calculate the
|
||||
* value to store in the cache. This function should be side-effect free
|
||||
* to take advantage of the optimization.
|
||||
* @param {function(?):K=} opt_keyFn The key provider to determine the cache
|
||||
* map key. This should be used if the given key is not a string or number.
|
||||
* If not provided then the given key is used. This function should be
|
||||
* side-effect free to take advantage of the optimization.
|
||||
* @return {V} The cached or calculated value.
|
||||
* @template K
|
||||
* @template V
|
||||
*/
|
||||
goog.reflect.cache = function(cacheObj, key, valueFn, opt_keyFn) {
|
||||
var storedKey = opt_keyFn ? opt_keyFn(key) : key;
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(cacheObj, storedKey)) {
|
||||
return cacheObj[storedKey];
|
||||
}
|
||||
|
||||
return (cacheObj[storedKey] = valueFn(key));
|
||||
};
|
182
assets/viz/2/goog/string/const.js
Normal file
182
assets/viz/2/goog/string/const.js
Normal file
@ -0,0 +1,182 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.string.Const');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for compile-time-constant strings.
|
||||
*
|
||||
* Const is a wrapper for strings that can only be created from program
|
||||
* constants (i.e., string literals). This property relies on a custom Closure
|
||||
* compiler check that {@code goog.string.Const.from} is only invoked on
|
||||
* compile-time-constant expressions.
|
||||
*
|
||||
* Const is useful in APIs whose correct and secure use requires that certain
|
||||
* arguments are not attacker controlled: Compile-time constants are inherently
|
||||
* under the control of the application and not under control of external
|
||||
* attackers, and hence are safe to use in such contexts.
|
||||
*
|
||||
* Instances of this type must be created via its factory method
|
||||
* {@code goog.string.Const.from} and not by invoking its constructor. The
|
||||
* constructor intentionally takes no parameters and the type is immutable;
|
||||
* hence only a default instance corresponding to the empty string can be
|
||||
* obtained via constructor invocation.
|
||||
*
|
||||
* @see goog.string.Const#from
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.string.Const = function() {
|
||||
/**
|
||||
* The wrapped value of this Const object. The field has a purposely ugly
|
||||
* name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.string.Const#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_ =
|
||||
goog.string.Const.TYPE_MARKER_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.string.Const.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Const's value a string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security-relevant that an object's type is
|
||||
* indeed {@code goog.string.Const}, use {@code goog.string.Const.unwrap}
|
||||
* instead of this method.
|
||||
*
|
||||
* @see goog.string.Const#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.string.Const.prototype.getTypedStringValue = function() {
|
||||
return this.stringConstValueWithSecurityContract__googStringSecurityPrivate_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a debug-string representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped inside an object of this type,
|
||||
* use {@code goog.string.Const.unwrap}.
|
||||
*
|
||||
* @see goog.string.Const#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.string.Const.prototype.toString = function() {
|
||||
return 'Const{' +
|
||||
this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ +
|
||||
'}';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed an instance
|
||||
* of {@code goog.string.Const}, and returns its value.
|
||||
* @param {!goog.string.Const} stringConst The object to extract from.
|
||||
* @return {string} The Const object's contained string, unless the run-time
|
||||
* type check fails. In that case, {@code unwrap} returns an innocuous
|
||||
* string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.string.Const.unwrap = function(stringConst) {
|
||||
// Perform additional run-time type-checking to ensure that stringConst is
|
||||
// indeed an instance of the expected type. This provides some additional
|
||||
// protection against security bugs due to application code that disables type
|
||||
// checks.
|
||||
if (stringConst instanceof goog.string.Const &&
|
||||
stringConst.constructor === goog.string.Const &&
|
||||
stringConst.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_ ===
|
||||
goog.string.Const.TYPE_MARKER_) {
|
||||
return stringConst
|
||||
.stringConstValueWithSecurityContract__googStringSecurityPrivate_;
|
||||
} else {
|
||||
goog.asserts.fail(
|
||||
'expected object of type Const, got \'' + stringConst + '\'');
|
||||
return 'type_error:Const';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a Const object from a compile-time constant string.
|
||||
*
|
||||
* It is illegal to invoke this function on an expression whose
|
||||
* compile-time-contant value cannot be determined by the Closure compiler.
|
||||
*
|
||||
* Correct invocations include,
|
||||
* <pre>
|
||||
* var s = goog.string.Const.from('hello');
|
||||
* var t = goog.string.Const.from('hello' + 'world');
|
||||
* </pre>
|
||||
*
|
||||
* In contrast, the following are illegal:
|
||||
* <pre>
|
||||
* var s = goog.string.Const.from(getHello());
|
||||
* var t = goog.string.Const.from('hello' + world);
|
||||
* </pre>
|
||||
*
|
||||
* TODO(xtof): Compile-time checks that this function is only called
|
||||
* with compile-time constant expressions.
|
||||
*
|
||||
* @param {string} s A constant string from which to create a Const.
|
||||
* @return {!goog.string.Const} A Const object initialized to stringConst.
|
||||
*/
|
||||
goog.string.Const.from = function(s) {
|
||||
return goog.string.Const.create__googStringSecurityPrivate_(s);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the Const type, used to implement additional run-time
|
||||
* type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.string.Const.TYPE_MARKER_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Utility method to create Const instances.
|
||||
* @param {string} s The string to initialize the Const object with.
|
||||
* @return {!goog.string.Const} The initialized Const object.
|
||||
* @private
|
||||
*/
|
||||
goog.string.Const.create__googStringSecurityPrivate_ = function(s) {
|
||||
var stringConst = new goog.string.Const();
|
||||
stringConst.stringConstValueWithSecurityContract__googStringSecurityPrivate_ =
|
||||
s;
|
||||
return stringConst;
|
||||
};
|
1631
assets/viz/2/goog/string/string.js
Normal file
1631
assets/viz/2/goog/string/string.js
Normal file
File diff suppressed because it is too large
Load Diff
103
assets/viz/2/goog/string/stringbuffer.js
Normal file
103
assets/viz/2/goog/string/stringbuffer.js
Normal file
@ -0,0 +1,103 @@
|
||||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utility for fast string concatenation.
|
||||
*/
|
||||
|
||||
goog.provide('goog.string.StringBuffer');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Utility class to facilitate string concatenation.
|
||||
*
|
||||
* @param {*=} opt_a1 Optional first initial item to append.
|
||||
* @param {...*} var_args Other initial items to
|
||||
* append, e.g., new goog.string.StringBuffer('foo', 'bar').
|
||||
* @constructor
|
||||
*/
|
||||
goog.string.StringBuffer = function(opt_a1, var_args) {
|
||||
if (opt_a1 != null) {
|
||||
this.append.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Internal buffer for the string to be concatenated.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.string.StringBuffer.prototype.buffer_ = '';
|
||||
|
||||
|
||||
/**
|
||||
* Sets the contents of the string buffer object, replacing what's currently
|
||||
* there.
|
||||
*
|
||||
* @param {*} s String to set.
|
||||
*/
|
||||
goog.string.StringBuffer.prototype.set = function(s) {
|
||||
this.buffer_ = '' + s;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Appends one or more items to the buffer.
|
||||
*
|
||||
* Calling this with null, undefined, or empty arguments is an error.
|
||||
*
|
||||
* @param {*} a1 Required first string.
|
||||
* @param {*=} opt_a2 Optional second string.
|
||||
* @param {...?} var_args Other items to append,
|
||||
* e.g., sb.append('foo', 'bar', 'baz').
|
||||
* @return {!goog.string.StringBuffer} This same StringBuffer object.
|
||||
* @suppress {duplicate}
|
||||
*/
|
||||
goog.string.StringBuffer.prototype.append = function(a1, opt_a2, var_args) {
|
||||
// Use a1 directly to avoid arguments instantiation for single-arg case.
|
||||
this.buffer_ += String(a1);
|
||||
if (opt_a2 != null) { // second argument is undefined (null == undefined)
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
this.buffer_ += arguments[i];
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the internal buffer.
|
||||
*/
|
||||
goog.string.StringBuffer.prototype.clear = function() {
|
||||
this.buffer_ = '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} the length of the current contents of the buffer.
|
||||
*/
|
||||
goog.string.StringBuffer.prototype.getLength = function() {
|
||||
return this.buffer_.length;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The concatenated string.
|
||||
* @override
|
||||
*/
|
||||
goog.string.StringBuffer.prototype.toString = function() {
|
||||
return this.buffer_;
|
||||
};
|
221
assets/viz/2/goog/string/stringformat.js
Normal file
221
assets/viz/2/goog/string/stringformat.js
Normal file
@ -0,0 +1,221 @@
|
||||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Implementation of sprintf-like, python-%-operator-like,
|
||||
* .NET-String.Format-like functionality. Uses JS string's replace method to
|
||||
* extract format specifiers and sends those specifiers to a handler function,
|
||||
* which then, based on conversion type part of the specifier, calls the
|
||||
* appropriate function to handle the specific conversion.
|
||||
* For specific functionality implemented, look at formatRe below, or look
|
||||
* at the tests.
|
||||
*/
|
||||
|
||||
goog.provide('goog.string.format');
|
||||
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* Performs sprintf-like conversion, i.e. puts the values in a template.
|
||||
* DO NOT use it instead of built-in conversions in simple cases such as
|
||||
* 'Cost: %.2f' as it would introduce unnecessary latency opposed to
|
||||
* 'Cost: ' + cost.toFixed(2).
|
||||
* @param {string} formatString Template string containing % specifiers.
|
||||
* @param {...string|number} var_args Values formatString is to be filled with.
|
||||
* @return {string} Formatted string.
|
||||
*/
|
||||
goog.string.format = function(formatString, var_args) {
|
||||
|
||||
// Convert the arguments to an array (MDC recommended way).
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
|
||||
// Try to get the template.
|
||||
var template = args.shift();
|
||||
if (typeof template == 'undefined') {
|
||||
throw Error('[goog.string.format] Template required');
|
||||
}
|
||||
|
||||
// This re is used for matching, it also defines what is supported.
|
||||
var formatRe = /%([0\-\ \+]*)(\d+)?(\.(\d+))?([%sfdiu])/g;
|
||||
|
||||
/**
|
||||
* Chooses which conversion function to call based on type conversion
|
||||
* specifier.
|
||||
* @param {string} match Contains the re matched string.
|
||||
* @param {string} flags Formatting flags.
|
||||
* @param {string} width Replacement string minimum width.
|
||||
* @param {string} dotp Matched precision including a dot.
|
||||
* @param {string} precision Specifies floating point precision.
|
||||
* @param {string} type Type conversion specifier.
|
||||
* @param {string} offset Matching location in the original string.
|
||||
* @param {string} wholeString Has the actualString being searched.
|
||||
* @return {string} Formatted parameter.
|
||||
*/
|
||||
function replacerDemuxer(
|
||||
match, flags, width, dotp, precision, type, offset, wholeString) {
|
||||
// The % is too simple and doesn't take an argument.
|
||||
if (type == '%') {
|
||||
return '%';
|
||||
}
|
||||
|
||||
// Try to get the actual value from parent function.
|
||||
var value = args.shift();
|
||||
|
||||
// If we didn't get any arguments, fail.
|
||||
if (typeof value == 'undefined') {
|
||||
throw Error('[goog.string.format] Not enough arguments');
|
||||
}
|
||||
|
||||
// Patch the value argument to the beginning of our type specific call.
|
||||
arguments[0] = value;
|
||||
|
||||
return goog.string.format.demuxes_[type].apply(null, arguments);
|
||||
}
|
||||
|
||||
return template.replace(formatRe, replacerDemuxer);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Contains various conversion functions (to be filled in later on).
|
||||
* @private {!Object}
|
||||
*/
|
||||
goog.string.format.demuxes_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Processes %s conversion specifier.
|
||||
* @param {string} value Contains the formatRe matched string.
|
||||
* @param {string} flags Formatting flags.
|
||||
* @param {string} width Replacement string minimum width.
|
||||
* @param {string} dotp Matched precision including a dot.
|
||||
* @param {string} precision Specifies floating point precision.
|
||||
* @param {string} type Type conversion specifier.
|
||||
* @param {string} offset Matching location in the original string.
|
||||
* @param {string} wholeString Has the actualString being searched.
|
||||
* @return {string} Replacement string.
|
||||
*/
|
||||
goog.string.format.demuxes_['s'] = function(
|
||||
value, flags, width, dotp, precision, type, offset, wholeString) {
|
||||
var replacement = value;
|
||||
// If no padding is necessary we're done.
|
||||
// The check for '' is necessary because Firefox incorrectly provides the
|
||||
// empty string instead of undefined for non-participating capture groups,
|
||||
// and isNaN('') == false.
|
||||
if (isNaN(width) || width == '' || replacement.length >= Number(width)) {
|
||||
return replacement;
|
||||
}
|
||||
|
||||
// Otherwise we should find out where to put spaces.
|
||||
if (flags.indexOf('-', 0) > -1) {
|
||||
replacement = replacement +
|
||||
goog.string.repeat(' ', Number(width) - replacement.length);
|
||||
} else {
|
||||
replacement = goog.string.repeat(' ', Number(width) - replacement.length) +
|
||||
replacement;
|
||||
}
|
||||
return replacement;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Processes %f conversion specifier.
|
||||
* @param {string} value Contains the formatRe matched string.
|
||||
* @param {string} flags Formatting flags.
|
||||
* @param {string} width Replacement string minimum width.
|
||||
* @param {string} dotp Matched precision including a dot.
|
||||
* @param {string} precision Specifies floating point precision.
|
||||
* @param {string} type Type conversion specifier.
|
||||
* @param {string} offset Matching location in the original string.
|
||||
* @param {string} wholeString Has the actualString being searched.
|
||||
* @return {string} Replacement string.
|
||||
*/
|
||||
goog.string.format.demuxes_['f'] = function(
|
||||
value, flags, width, dotp, precision, type, offset, wholeString) {
|
||||
|
||||
var replacement = value.toString();
|
||||
|
||||
// The check for '' is necessary because Firefox incorrectly provides the
|
||||
// empty string instead of undefined for non-participating capture groups,
|
||||
// and isNaN('') == false.
|
||||
if (!(isNaN(precision) || precision == '')) {
|
||||
replacement = parseFloat(value).toFixed(precision);
|
||||
}
|
||||
|
||||
// Generates sign string that will be attached to the replacement.
|
||||
var sign;
|
||||
if (Number(value) < 0) {
|
||||
sign = '-';
|
||||
} else if (flags.indexOf('+') >= 0) {
|
||||
sign = '+';
|
||||
} else if (flags.indexOf(' ') >= 0) {
|
||||
sign = ' ';
|
||||
} else {
|
||||
sign = '';
|
||||
}
|
||||
|
||||
if (Number(value) >= 0) {
|
||||
replacement = sign + replacement;
|
||||
}
|
||||
|
||||
// If no padding is necessary we're done.
|
||||
if (isNaN(width) || replacement.length >= Number(width)) {
|
||||
return replacement;
|
||||
}
|
||||
|
||||
// We need a clean signless replacement to start with
|
||||
replacement = isNaN(precision) ? Math.abs(Number(value)).toString() :
|
||||
Math.abs(Number(value)).toFixed(precision);
|
||||
|
||||
var padCount = Number(width) - replacement.length - sign.length;
|
||||
|
||||
// Find out which side to pad, and if it's left side, then which character to
|
||||
// pad, and set the sign on the left and padding in the middle.
|
||||
if (flags.indexOf('-', 0) >= 0) {
|
||||
replacement = sign + replacement + goog.string.repeat(' ', padCount);
|
||||
} else {
|
||||
// Decides which character to pad.
|
||||
var paddingChar = (flags.indexOf('0', 0) >= 0) ? '0' : ' ';
|
||||
replacement =
|
||||
sign + goog.string.repeat(paddingChar, padCount) + replacement;
|
||||
}
|
||||
|
||||
return replacement;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Processes %d conversion specifier.
|
||||
* @param {string} value Contains the formatRe matched string.
|
||||
* @param {string} flags Formatting flags.
|
||||
* @param {string} width Replacement string minimum width.
|
||||
* @param {string} dotp Matched precision including a dot.
|
||||
* @param {string} precision Specifies floating point precision.
|
||||
* @param {string} type Type conversion specifier.
|
||||
* @param {string} offset Matching location in the original string.
|
||||
* @param {string} wholeString Has the actualString being searched.
|
||||
* @return {string} Replacement string.
|
||||
*/
|
||||
goog.string.format.demuxes_['d'] = function(
|
||||
value, flags, width, dotp, precision, type, offset, wholeString) {
|
||||
return goog.string.format.demuxes_['f'](
|
||||
parseInt(value, 10) /* value */, flags, width, dotp, 0 /* precision */,
|
||||
type, offset, wholeString);
|
||||
};
|
||||
|
||||
|
||||
// These are additional aliases, for integer conversion.
|
||||
goog.string.format.demuxes_['i'] = goog.string.format.demuxes_['d'];
|
||||
goog.string.format.demuxes_['u'] = goog.string.format.demuxes_['d'];
|
48
assets/viz/2/goog/string/typedstring.js
Normal file
48
assets/viz/2/goog/string/typedstring.js
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for strings that conform to a data type or language.
|
||||
*
|
||||
* Implementations of this interface are wrappers for strings, and typically
|
||||
* associate a type contract with the wrapped string. Concrete implementations
|
||||
* of this interface may choose to implement additional run-time type checking,
|
||||
* see for example {@code goog.html.SafeHtml}. If available, client code that
|
||||
* needs to ensure type membership of an object should use the type's function
|
||||
* to assert type membership, such as {@code goog.html.SafeHtml.unwrap}.
|
||||
* @interface
|
||||
*/
|
||||
goog.string.TypedString = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Interface marker of the TypedString interface.
|
||||
*
|
||||
* This property can be used to determine at runtime whether or not an object
|
||||
* implements this interface. All implementations of this interface set this
|
||||
* property to {@code true}.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.string.TypedString.prototype.implementsGoogStringTypedString;
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves this wrapped string's value.
|
||||
* @return {!string} The wrapped string's value.
|
||||
*/
|
||||
goog.string.TypedString.prototype.getTypedStringValue;
|
568
assets/viz/2/goog/useragent/useragent.js
Normal file
568
assets/viz/2/goog/useragent/useragent.js
Normal file
@ -0,0 +1,568 @@
|
||||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Rendering engine detection.
|
||||
* @see <a href="http://www.useragentstring.com/">User agent strings</a>
|
||||
* For information on the browser brand (such as Safari versus Chrome), see
|
||||
* goog.userAgent.product.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @see ../demos/useragent.html
|
||||
*/
|
||||
|
||||
goog.provide('goog.userAgent');
|
||||
|
||||
goog.require('goog.labs.userAgent.browser');
|
||||
goog.require('goog.labs.userAgent.engine');
|
||||
goog.require('goog.labs.userAgent.platform');
|
||||
goog.require('goog.labs.userAgent.util');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the browser is IE.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_IE', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the browser is EDGE.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_EDGE', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the browser is GECKO.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_GECKO', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the browser is WEBKIT.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_WEBKIT', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the browser is a
|
||||
* mobile device running WebKit e.g. iPhone or Android.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_MOBILE_WEBKIT', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the browser is OPERA.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_OPERA', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the
|
||||
* {@code goog.userAgent.isVersionOrHigher}
|
||||
* function will return true for any version.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_ANY_VERSION', false);
|
||||
|
||||
|
||||
/**
|
||||
* Whether we know the browser engine at compile-time.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.BROWSER_KNOWN_ = goog.userAgent.ASSUME_IE ||
|
||||
goog.userAgent.ASSUME_EDGE || goog.userAgent.ASSUME_GECKO ||
|
||||
goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.ASSUME_WEBKIT ||
|
||||
goog.userAgent.ASSUME_OPERA;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the userAgent string for the current browser.
|
||||
*
|
||||
* @return {string} The userAgent string.
|
||||
*/
|
||||
goog.userAgent.getUserAgentString = function() {
|
||||
return goog.labs.userAgent.util.getUserAgent();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* TODO(nnaze): Change type to "Navigator" and update compilation targets.
|
||||
* @return {Object} The native navigator object.
|
||||
*/
|
||||
goog.userAgent.getNavigator = function() {
|
||||
// Need a local navigator reference instead of using the global one,
|
||||
// to avoid the rare case where they reference different objects.
|
||||
// (in a WorkerPool, for example).
|
||||
return goog.global['navigator'] || null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is Opera.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_OPERA :
|
||||
goog.labs.userAgent.browser.isOpera();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is Internet Explorer.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_IE :
|
||||
goog.labs.userAgent.browser.isIE();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is Microsoft Edge.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.EDGE = goog.userAgent.BROWSER_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_EDGE :
|
||||
goog.labs.userAgent.engine.isEdge();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is MS Internet Explorer or MS Edge.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.EDGE_OR_IE = goog.userAgent.EDGE || goog.userAgent.IE;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is Gecko. Gecko is the rendering engine used by
|
||||
* Mozilla, Firefox, and others.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_GECKO :
|
||||
goog.labs.userAgent.engine.isGecko();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is WebKit. WebKit is the rendering engine that
|
||||
* Safari, Android and others use.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT :
|
||||
goog.labs.userAgent.engine.isWebKit();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on a mobile device.
|
||||
*
|
||||
* This is a separate function so that the logic can be tested.
|
||||
*
|
||||
* TODO(nnaze): Investigate swapping in goog.labs.userAgent.device.isMobile().
|
||||
*
|
||||
* @return {boolean} Whether the user agent is running on a mobile device.
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.isMobile_ = function() {
|
||||
return goog.userAgent.WEBKIT &&
|
||||
goog.labs.userAgent.util.matchUserAgent('Mobile');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on a mobile device.
|
||||
*
|
||||
* TODO(nnaze): Consider deprecating MOBILE when labs.userAgent
|
||||
* is promoted as the gecko/webkit logic is likely inaccurate.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.MOBILE =
|
||||
goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.isMobile_();
|
||||
|
||||
|
||||
/**
|
||||
* Used while transitioning code to use WEBKIT instead.
|
||||
* @type {boolean}
|
||||
* @deprecated Use {@link goog.userAgent.product.SAFARI} instead.
|
||||
* TODO(nicksantos): Delete this from goog.userAgent.
|
||||
*/
|
||||
goog.userAgent.SAFARI = goog.userAgent.WEBKIT;
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} the platform (operating system) the user agent is running
|
||||
* on. Default to empty string because navigator.platform may not be defined
|
||||
* (on Rhino, for example).
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.determinePlatform_ = function() {
|
||||
var navigator = goog.userAgent.getNavigator();
|
||||
return navigator && navigator.platform || '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The platform (operating system) the user agent is running on. Default to
|
||||
* empty string because navigator.platform may not be defined (on Rhino, for
|
||||
* example).
|
||||
* @type {string}
|
||||
*/
|
||||
goog.userAgent.PLATFORM = goog.userAgent.determinePlatform_();
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on a Macintosh operating
|
||||
* system.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_MAC', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on a Windows operating
|
||||
* system.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_WINDOWS', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on a Linux operating
|
||||
* system.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_LINUX', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on a X11 windowing
|
||||
* system.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_X11', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on Android.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_ANDROID', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on an iPhone.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_IPHONE', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on an iPad.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_IPAD', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on an iPod.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_IPOD', false);
|
||||
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.PLATFORM_KNOWN_ = goog.userAgent.ASSUME_MAC ||
|
||||
goog.userAgent.ASSUME_WINDOWS || goog.userAgent.ASSUME_LINUX ||
|
||||
goog.userAgent.ASSUME_X11 || goog.userAgent.ASSUME_ANDROID ||
|
||||
goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD ||
|
||||
goog.userAgent.ASSUME_IPOD;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on a Macintosh operating system.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_MAC :
|
||||
goog.labs.userAgent.platform.isMacintosh();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on a Windows operating system.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_WINDOWS :
|
||||
goog.labs.userAgent.platform.isWindows();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is Linux per the legacy behavior of
|
||||
* goog.userAgent.LINUX, which considered ChromeOS to also be
|
||||
* Linux.
|
||||
* @return {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.isLegacyLinux_ = function() {
|
||||
return goog.labs.userAgent.platform.isLinux() ||
|
||||
goog.labs.userAgent.platform.isChromeOS();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on a Linux operating system.
|
||||
*
|
||||
* Note that goog.userAgent.LINUX considers ChromeOS to be Linux,
|
||||
* while goog.labs.userAgent.platform considers ChromeOS and
|
||||
* Linux to be different OSes.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_LINUX :
|
||||
goog.userAgent.isLegacyLinux_();
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user agent is an X11 windowing system.
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.isX11_ = function() {
|
||||
var navigator = goog.userAgent.getNavigator();
|
||||
return !!navigator &&
|
||||
goog.string.contains(navigator['appVersion'] || '', 'X11');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on a X11 windowing system.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_X11 :
|
||||
goog.userAgent.isX11_();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on Android.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_ANDROID :
|
||||
goog.labs.userAgent.platform.isAndroid();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on an iPhone.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_IPHONE :
|
||||
goog.labs.userAgent.platform.isIphone();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on an iPad.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_IPAD :
|
||||
goog.labs.userAgent.platform.isIpad();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on an iPod.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.IPOD = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_IPOD :
|
||||
goog.labs.userAgent.platform.isIpod();
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The string that describes the version number of the user
|
||||
* agent.
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.determineVersion_ = function() {
|
||||
// All browsers have different ways to detect the version and they all have
|
||||
// different naming schemes.
|
||||
// version is a string rather than a number because it may contain 'b', 'a',
|
||||
// and so on.
|
||||
var version = '';
|
||||
var arr = goog.userAgent.getVersionRegexResult_();
|
||||
if (arr) {
|
||||
version = arr ? arr[1] : '';
|
||||
}
|
||||
|
||||
if (goog.userAgent.IE) {
|
||||
// IE9 can be in document mode 9 but be reporting an inconsistent user agent
|
||||
// version. If it is identifying as a version lower than 9 we take the
|
||||
// documentMode as the version instead. IE8 has similar behavior.
|
||||
// It is recommended to set the X-UA-Compatible header to ensure that IE9
|
||||
// uses documentMode 9.
|
||||
var docMode = goog.userAgent.getDocumentMode_();
|
||||
if (docMode != null && docMode > parseFloat(version)) {
|
||||
return String(docMode);
|
||||
}
|
||||
}
|
||||
|
||||
return version;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {?Array|undefined} The version regex matches from parsing the user
|
||||
* agent string. These regex statements must be executed inline so they can
|
||||
* be compiled out by the closure compiler with the rest of the useragent
|
||||
* detection logic when ASSUME_* is specified.
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.getVersionRegexResult_ = function() {
|
||||
var userAgent = goog.userAgent.getUserAgentString();
|
||||
if (goog.userAgent.GECKO) {
|
||||
return /rv\:([^\);]+)(\)|;)/.exec(userAgent);
|
||||
}
|
||||
if (goog.userAgent.EDGE) {
|
||||
return /Edge\/([\d\.]+)/.exec(userAgent);
|
||||
}
|
||||
if (goog.userAgent.IE) {
|
||||
return /\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(userAgent);
|
||||
}
|
||||
if (goog.userAgent.WEBKIT) {
|
||||
// WebKit/125.4
|
||||
return /WebKit\/(\S+)/.exec(userAgent);
|
||||
}
|
||||
if (goog.userAgent.OPERA) {
|
||||
// If none of the above browsers were detected but the browser is Opera, the
|
||||
// only string that is of interest is 'Version/<number>'.
|
||||
return /(?:Version)[ \/]?(\S+)/.exec(userAgent);
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number|undefined} Returns the document mode (for testing).
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.getDocumentMode_ = function() {
|
||||
// NOTE(user): goog.userAgent may be used in context where there is no DOM.
|
||||
var doc = goog.global['document'];
|
||||
return doc ? doc['documentMode'] : undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The version of the user agent. This is a string because it might contain
|
||||
* 'b' (as in beta) as well as multiple dots.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.userAgent.VERSION = goog.userAgent.determineVersion_();
|
||||
|
||||
|
||||
/**
|
||||
* Compares two version numbers.
|
||||
*
|
||||
* @param {string} v1 Version of first item.
|
||||
* @param {string} v2 Version of second item.
|
||||
*
|
||||
* @return {number} 1 if first argument is higher
|
||||
* 0 if arguments are equal
|
||||
* -1 if second argument is higher.
|
||||
* @deprecated Use goog.string.compareVersions.
|
||||
*/
|
||||
goog.userAgent.compare = function(v1, v2) {
|
||||
return goog.string.compareVersions(v1, v2);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cache for {@link goog.userAgent.isVersionOrHigher}.
|
||||
* Calls to compareVersions are surprisingly expensive and, as a browser's
|
||||
* version number is unlikely to change during a session, we cache the results.
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.isVersionOrHigherCache_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent version is higher or the same as the given version.
|
||||
* NOTE: When checking the version numbers for Firefox and Safari, be sure to
|
||||
* use the engine's version, not the browser's version number. For example,
|
||||
* Firefox 3.0 corresponds to Gecko 1.9 and Safari 3.0 to Webkit 522.11.
|
||||
* Opera and Internet Explorer versions match the product release number.<br>
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Safari_version_history">
|
||||
* Webkit</a>
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Gecko_engine">Gecko</a>
|
||||
*
|
||||
* @param {string|number} version The version to check.
|
||||
* @return {boolean} Whether the user agent version is higher or the same as
|
||||
* the given version.
|
||||
*/
|
||||
goog.userAgent.isVersionOrHigher = function(version) {
|
||||
return goog.userAgent.ASSUME_ANY_VERSION ||
|
||||
goog.userAgent.isVersionOrHigherCache_[version] ||
|
||||
(goog.userAgent.isVersionOrHigherCache_[version] =
|
||||
goog.string.compareVersions(goog.userAgent.VERSION, version) >= 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deprecated alias to {@code goog.userAgent.isVersionOrHigher}.
|
||||
* @param {string|number} version The version to check.
|
||||
* @return {boolean} Whether the user agent version is higher or the same as
|
||||
* the given version.
|
||||
* @deprecated Use goog.userAgent.isVersionOrHigher().
|
||||
*/
|
||||
goog.userAgent.isVersion = goog.userAgent.isVersionOrHigher;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the IE effective document mode is higher or the same as the given
|
||||
* document mode version.
|
||||
* NOTE: Only for IE, return false for another browser.
|
||||
*
|
||||
* @param {number} documentMode The document mode version to check.
|
||||
* @return {boolean} Whether the IE effective document mode is higher or the
|
||||
* same as the given version.
|
||||
*/
|
||||
goog.userAgent.isDocumentModeOrHigher = function(documentMode) {
|
||||
return Number(goog.userAgent.DOCUMENT_MODE) >= documentMode;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deprecated alias to {@code goog.userAgent.isDocumentModeOrHigher}.
|
||||
* @param {number} version The version to check.
|
||||
* @return {boolean} Whether the IE effective document mode is higher or the
|
||||
* same as the given version.
|
||||
* @deprecated Use goog.userAgent.isDocumentModeOrHigher().
|
||||
*/
|
||||
goog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher;
|
||||
|
||||
|
||||
/**
|
||||
* For IE version < 7, documentMode is undefined, so attempt to use the
|
||||
* CSS1Compat property to see if we are in standards mode. If we are in
|
||||
* standards mode, treat the browser version as the document mode. Otherwise,
|
||||
* IE is emulating version 5.
|
||||
* @type {number|undefined}
|
||||
* @const
|
||||
*/
|
||||
goog.userAgent.DOCUMENT_MODE = (function() {
|
||||
var doc = goog.global['document'];
|
||||
var mode = goog.userAgent.getDocumentMode_();
|
||||
if (!doc || !goog.userAgent.IE) {
|
||||
return undefined;
|
||||
}
|
||||
return mode || (doc['compatMode'] == 'CSS1Compat' ?
|
||||
parseInt(goog.userAgent.VERSION, 10) :
|
||||
5);
|
||||
})();
|
21796
assets/viz/2/processing.js
Normal file
21796
assets/viz/2/processing.js
Normal file
File diff suppressed because it is too large
Load Diff
4993
assets/viz/2/quil/core.cljc
Normal file
4993
assets/viz/2/quil/core.cljc
Normal file
File diff suppressed because it is too large
Load Diff
1
assets/viz/2/quil/core.cljc.cache.edn
Normal file
1
assets/viz/2/quil/core.cljc.cache.edn
Normal file
File diff suppressed because one or more lines are too long
6643
assets/viz/2/quil/core.js
Normal file
6643
assets/viz/2/quil/core.js
Normal file
File diff suppressed because it is too large
Load Diff
1
assets/viz/2/quil/core.js.map
Normal file
1
assets/viz/2/quil/core.js.map
Normal file
File diff suppressed because one or more lines are too long
144
assets/viz/2/quil/middleware.cljc
Normal file
144
assets/viz/2/quil/middleware.cljc
Normal file
@ -0,0 +1,144 @@
|
||||
(ns ^{:doc "Quil middleware."}
|
||||
quil.middleware
|
||||
(:require [quil.middlewares.fun-mode :as fun-mode]
|
||||
#?(:clj [quil.middlewares.pause-on-error :as pause-on-error])
|
||||
[quil.middlewares.navigation-3d :as navigation-3d]
|
||||
[quil.middlewares.navigation-2d :as navigation-2d]
|
||||
))
|
||||
|
||||
(defn ^{:requires-bindings false
|
||||
:category "Middleware"
|
||||
:subcategory nil
|
||||
:ns "quil.middleware"
|
||||
:added "2.1.0"}
|
||||
fun-mode
|
||||
"Introduces function mode. Adds 'update' function which takes current
|
||||
state and returns new state. Makes all other functions (setup, draw,
|
||||
mouse-click, etc) state-aware. See wiki for more details."
|
||||
[options]
|
||||
(fun-mode/fun-mode options))
|
||||
|
||||
#?(:clj
|
||||
(defn ^{:requires-bindings false
|
||||
:category "Middleware"
|
||||
:subcategory nil
|
||||
:ns "quil.middleware"
|
||||
:added "2.2.0"}
|
||||
pause-on-error
|
||||
"Pauses sketch if any of user-provided handlers throws error.
|
||||
It allows to fix the error on the fly and continue sketch.
|
||||
May be good alternative to default '500ms pause if exception'
|
||||
behaviour."
|
||||
[options]
|
||||
(pause-on-error/pause-on-error options)))
|
||||
|
||||
(defn ^{:requires-bindings false
|
||||
:category "Middleware"
|
||||
:subcategory nil
|
||||
:ns "quil.middleware"
|
||||
:added "2.2.0"}
|
||||
navigation-3d
|
||||
"Enables navigation in 3D space. Similar to how it is done in
|
||||
shooters: WASD navigation, space is go up, drag mouse to look around.
|
||||
This middleware requires fun-mode.
|
||||
|
||||
|
||||
Navigation
|
||||
|
||||
* Drag mouse to look around. You can change settings to bind
|
||||
mouse-moved instead of mouse-dragged to look around. See
|
||||
customization info below.
|
||||
|
||||
* Keyboard:
|
||||
* w - go forward
|
||||
* s - go backward
|
||||
* a - strafe left
|
||||
* d - strafe right
|
||||
* space - go up
|
||||
* z - go down, can't bind to ctrl, limitation of Processing
|
||||
|
||||
|
||||
Customization
|
||||
|
||||
You can customize this middleware by providing map as
|
||||
:navigation-3d option in defsketch/sketch. Map can have following
|
||||
optional keys:
|
||||
|
||||
:position - vector of 3 numbers, initial camera position. Default
|
||||
is the same as in 'camera' function.
|
||||
|
||||
:straight - vector of 3 numbers, direction you'll be looking at.
|
||||
Default is [0 0 -1] (looking down).
|
||||
|
||||
:up - vector of 3 numbers, 'up' direction. Default is [0 1 0].
|
||||
|
||||
:pixels-in-360 - number, mouse sensitivity. Defines how many pixels
|
||||
you need to move/drag you mouse to rotate 360 degrees.
|
||||
The less the number the more sensitive is mouse.
|
||||
Default is 1000.
|
||||
|
||||
:step-size - number, number of pixels you move on each key event (wasd).
|
||||
Default is 20.
|
||||
|
||||
:rotate-on - keyword, either :mouse-dragged or :mouse-moved. Specifies
|
||||
on which mouse event camera should rotate. Default is
|
||||
:mouse-dragged.
|
||||
|
||||
|
||||
Accessing position information from sketch
|
||||
|
||||
navigation-3d uses fun-mode under the hood so all position-related
|
||||
information is stored in the state map. It means that you can access in
|
||||
draw/update/any handler and modify it if you need to. Position
|
||||
information is a map which is stored under :navigation-3d key in the
|
||||
state map. Position consists of 3 values: :position, :straight and :up.
|
||||
See \"Customization\" section above for more details.
|
||||
|
||||
Usage example:
|
||||
|
||||
(q/defsketch my-sketch
|
||||
...
|
||||
:middleware [m/fun-mode m/navigation-3d])
|
||||
|
||||
See wiki article for more(?) details:
|
||||
https://github.com/quil/quil/wiki/Navigation-3D"
|
||||
[options]
|
||||
(navigation-3d/navigation-3d options))
|
||||
|
||||
(defn ^{:requires-bindings false
|
||||
:category "Middleware"
|
||||
:subcategory nil
|
||||
:ns "quil.middleware"
|
||||
:added "2.2.6"}
|
||||
navigation-2d
|
||||
"Enables navigation over 2D sketch. Drag mouse to change the center of the
|
||||
sketch and mouse wheel controls zoom. This middleware requires fun-mode.
|
||||
|
||||
Customization
|
||||
|
||||
You can customize this middleware by providing map as
|
||||
:navigation-2d option in defsketch/sketch. Map can have following
|
||||
optional keys:
|
||||
|
||||
:position - vector of 2 numbers, x and y - center of the screen.
|
||||
Default is width/2, height/2.
|
||||
|
||||
:zoom - number indicating current zoom level. Default is 1.
|
||||
|
||||
Accessing position information from sketch
|
||||
|
||||
navigation-2d uses fun-mode under the hood so all position-related
|
||||
information is stored in the state map. It means that you can access in
|
||||
draw/update/any handler and modify it if you need to. Position
|
||||
information is a map which is stored under :navigation-2d key in the
|
||||
state map. Position consists of 2 values: :position and :zoom.
|
||||
See \"Customization\" section above for more details.
|
||||
|
||||
Usage example:
|
||||
|
||||
(q/defsketch my-sketch
|
||||
...
|
||||
:middleware [m/fun-mode m/navigation-2d])
|
||||
"
|
||||
[options]
|
||||
(navigation-2d/navigation-2d options))
|
1
assets/viz/2/quil/middleware.cljc.cache.edn
Normal file
1
assets/viz/2/quil/middleware.cljc.cache.edn
Normal file
File diff suppressed because one or more lines are too long
118
assets/viz/2/quil/middleware.js
Normal file
118
assets/viz/2/quil/middleware.js
Normal file
@ -0,0 +1,118 @@
|
||||
// Compiled by ClojureScript 1.9.473 {}
|
||||
goog.provide('quil.middleware');
|
||||
goog.require('cljs.core');
|
||||
goog.require('quil.middlewares.fun_mode');
|
||||
goog.require('quil.middlewares.navigation_3d');
|
||||
goog.require('quil.middlewares.navigation_2d');
|
||||
/**
|
||||
* Introduces function mode. Adds 'update' function which takes current
|
||||
* state and returns new state. Makes all other functions (setup, draw,
|
||||
* mouse-click, etc) state-aware. See wiki for more details.
|
||||
*/
|
||||
quil.middleware.fun_mode = (function quil$middleware$fun_mode(options){
|
||||
return quil.middlewares.fun_mode.fun_mode.call(null,options);
|
||||
});
|
||||
/**
|
||||
* Enables navigation in 3D space. Similar to how it is done in
|
||||
* shooters: WASD navigation, space is go up, drag mouse to look around.
|
||||
* This middleware requires fun-mode.
|
||||
*
|
||||
*
|
||||
* Navigation
|
||||
*
|
||||
* * Drag mouse to look around. You can change settings to bind
|
||||
* mouse-moved instead of mouse-dragged to look around. See
|
||||
* customization info below.
|
||||
*
|
||||
* * Keyboard:
|
||||
* * w - go forward
|
||||
* * s - go backward
|
||||
* * a - strafe left
|
||||
* * d - strafe right
|
||||
* * space - go up
|
||||
* * z - go down, can't bind to ctrl, limitation of Processing
|
||||
*
|
||||
*
|
||||
* Customization
|
||||
*
|
||||
* You can customize this middleware by providing map as
|
||||
* :navigation-3d option in defsketch/sketch. Map can have following
|
||||
* optional keys:
|
||||
*
|
||||
* :position - vector of 3 numbers, initial camera position. Default
|
||||
* is the same as in 'camera' function.
|
||||
*
|
||||
* :straight - vector of 3 numbers, direction you'll be looking at.
|
||||
* Default is [0 0 -1] (looking down).
|
||||
*
|
||||
* :up - vector of 3 numbers, 'up' direction. Default is [0 1 0].
|
||||
*
|
||||
* :pixels-in-360 - number, mouse sensitivity. Defines how many pixels
|
||||
* you need to move/drag you mouse to rotate 360 degrees.
|
||||
* The less the number the more sensitive is mouse.
|
||||
* Default is 1000.
|
||||
*
|
||||
* :step-size - number, number of pixels you move on each key event (wasd).
|
||||
* Default is 20.
|
||||
*
|
||||
* :rotate-on - keyword, either :mouse-dragged or :mouse-moved. Specifies
|
||||
* on which mouse event camera should rotate. Default is
|
||||
* :mouse-dragged.
|
||||
*
|
||||
*
|
||||
* Accessing position information from sketch
|
||||
*
|
||||
* navigation-3d uses fun-mode under the hood so all position-related
|
||||
* information is stored in the state map. It means that you can access in
|
||||
* draw/update/any handler and modify it if you need to. Position
|
||||
* information is a map which is stored under :navigation-3d key in the
|
||||
* state map. Position consists of 3 values: :position, :straight and :up.
|
||||
* See "Customization" section above for more details.
|
||||
*
|
||||
* Usage example:
|
||||
*
|
||||
* (q/defsketch my-sketch
|
||||
* ...
|
||||
* :middleware [m/fun-mode m/navigation-3d])
|
||||
*
|
||||
* See wiki article for more(?) details:
|
||||
* https://github.com/quil/quil/wiki/Navigation-3D
|
||||
*/
|
||||
quil.middleware.navigation_3d = (function quil$middleware$navigation_3d(options){
|
||||
return quil.middlewares.navigation_3d.navigation_3d.call(null,options);
|
||||
});
|
||||
/**
|
||||
* Enables navigation over 2D sketch. Drag mouse to change the center of the
|
||||
* sketch and mouse wheel controls zoom. This middleware requires fun-mode.
|
||||
*
|
||||
* Customization
|
||||
*
|
||||
* You can customize this middleware by providing map as
|
||||
* :navigation-2d option in defsketch/sketch. Map can have following
|
||||
* optional keys:
|
||||
*
|
||||
* :position - vector of 2 numbers, x and y - center of the screen.
|
||||
* Default is width/2, height/2.
|
||||
*
|
||||
* :zoom - number indicating current zoom level. Default is 1.
|
||||
*
|
||||
* Accessing position information from sketch
|
||||
*
|
||||
* navigation-2d uses fun-mode under the hood so all position-related
|
||||
* information is stored in the state map. It means that you can access in
|
||||
* draw/update/any handler and modify it if you need to. Position
|
||||
* information is a map which is stored under :navigation-2d key in the
|
||||
* state map. Position consists of 2 values: :position and :zoom.
|
||||
* See "Customization" section above for more details.
|
||||
*
|
||||
* Usage example:
|
||||
*
|
||||
* (q/defsketch my-sketch
|
||||
* ...
|
||||
* :middleware [m/fun-mode m/navigation-2d])
|
||||
*/
|
||||
quil.middleware.navigation_2d = (function quil$middleware$navigation_2d(options){
|
||||
return quil.middlewares.navigation_2d.navigation_2d.call(null,options);
|
||||
});
|
||||
|
||||
//# sourceMappingURL=middleware.js.map
|
1
assets/viz/2/quil/middleware.js.map
Normal file
1
assets/viz/2/quil/middleware.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/quil\/middleware.js","sources":["middleware.cljc"],"lineCount":118,"mappings":";AAAA;;;;;AAQA;;;;;2BAAA,3BAKEA,8DAICC;AATH,AAUE,OAACC,6CAAkBD;;AAgBrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAAA,hCAKEE,wEAiECF;AAtEH,AAuEE,OAACG,uDAA4BH;;AAE\/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAAA,hCAKEI,wEA8BCJ;AAnCH,AAoCE,OAACK,uDAA4BL","names":["quil.middleware\/fun-mode","options","quil.middlewares.fun-mode\/fun-mode","quil.middleware\/navigation-3d","quil.middlewares.navigation-3d\/navigation-3d","quil.middleware\/navigation-2d","quil.middlewares.navigation-2d\/navigation-2d"]}
|
26
assets/viz/2/quil/middlewares/deprecated_options.cljc
Normal file
26
assets/viz/2/quil/middlewares/deprecated_options.cljc
Normal file
@ -0,0 +1,26 @@
|
||||
(ns quil.middlewares.deprecated-options)
|
||||
|
||||
(def ^:private deprecated
|
||||
{:decor ["2.0" "Try :features [:present] for similar effect"]
|
||||
:target ["2.0" "Use :features [:keep-on-top] instead."]
|
||||
:safe-draw-fn ["2.0" "Use :features [:no-safe-fns] instead."]})
|
||||
|
||||
(defn- check-features-vector [features]
|
||||
(let [features (set features)]
|
||||
(when (features :no-safe-draw)
|
||||
(println "Feature :no-safe-draw was renamed to :no-safe-fns in Quil 2.1."
|
||||
"Use :feature [:no-safe-fns] now."))
|
||||
(disj features :no-safe-draw)))
|
||||
|
||||
(defn deprecated-options
|
||||
"Checks if options map contains deprected options and removes them.
|
||||
Prints messages how to fix deprecated functions."
|
||||
[options]
|
||||
(let [options (update-in options [:features] check-features-vector)]
|
||||
(->> (for [[name value] options]
|
||||
(if-let [[version message] (deprecated name)]
|
||||
(do (println name "option was removed in Quil" version "." message)
|
||||
nil)
|
||||
[name value]))
|
||||
(remove nil?)
|
||||
(into {}))))
|
@ -0,0 +1 @@
|
||||
{:rename-macros {}, :renames {}, :use-macros {}, :excludes #{}, :name quil.middlewares.deprecated-options, :imports nil, :requires nil, :uses nil, :defs {deprecated {:name quil.middlewares.deprecated-options/deprecated, :file "out/quil/middlewares/deprecated_options.cljc", :line 3, :column 1, :end-line 3, :end-column 26, :private true, :meta {:file "/home/mediocregopher/src/viz/out/quil/middlewares/deprecated_options.cljc", :line 3, :column 16, :end-line 3, :end-column 26, :private true}, :tag cljs.core/IMap}, check-features-vector {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/quil/middlewares/deprecated_options.cljc", :line 8, :column 8, :end-line 8, :end-column 29, :private true, :arglists (quote ([features]))}, :private true, :name quil.middlewares.deprecated-options/check-features-vector, :variadic false, :file "out/quil/middlewares/deprecated_options.cljc", :end-column 29, :method-params ([features]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 8, :end-line 8, :max-fixed-arity 1, :fn-var true, :arglists (quote ([features]))}, deprecated-options {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/out/quil/middlewares/deprecated_options.cljc", :line 15, :column 7, :end-line 15, :end-column 25, :arglists (quote ([options])), :doc "Checks if options map contains deprected options and removes them.\n Prints messages how to fix deprecated functions."}, :name quil.middlewares.deprecated-options/deprecated-options, :variadic false, :file "out/quil/middlewares/deprecated_options.cljc", :end-column 25, :method-params ([options]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 15, :end-line 15, :max-fixed-arity 1, :fn-var true, :arglists (quote ([options])), :doc "Checks if options map contains deprected options and removes them.\n Prints messages how to fix deprecated functions."}}, :require-macros nil, :cljs.analyzer/constants {:seen #{:features :decor :safe-draw-fn :no-safe-draw :target}, :order [:decor :target :safe-draw-fn :no-safe-draw :features]}, :doc nil}
|
95
assets/viz/2/quil/middlewares/deprecated_options.js
Normal file
95
assets/viz/2/quil/middlewares/deprecated_options.js
Normal file
@ -0,0 +1,95 @@
|
||||
// Compiled by ClojureScript 1.9.473 {}
|
||||
goog.provide('quil.middlewares.deprecated_options');
|
||||
goog.require('cljs.core');
|
||||
quil.middlewares.deprecated_options.deprecated = new cljs.core.PersistentArrayMap(null, 3, [new cljs.core.Keyword(null,"decor","decor",-1730969431),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, ["2.0","Try :features [:present] for similar effect"], null),new cljs.core.Keyword(null,"target","target",253001721),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, ["2.0","Use :features [:keep-on-top] instead."], null),new cljs.core.Keyword(null,"safe-draw-fn","safe-draw-fn",1454900202),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, ["2.0","Use :features [:no-safe-fns] instead."], null)], null);
|
||||
quil.middlewares.deprecated_options.check_features_vector = (function quil$middlewares$deprecated_options$check_features_vector(features){
|
||||
var features__$1 = cljs.core.set.call(null,features);
|
||||
if(cljs.core.truth_(features__$1.call(null,new cljs.core.Keyword(null,"no-safe-draw","no-safe-draw",-1157778157)))){
|
||||
cljs.core.println.call(null,"Feature :no-safe-draw was renamed to :no-safe-fns in Quil 2.1.","Use :feature [:no-safe-fns] now.");
|
||||
} else {
|
||||
}
|
||||
|
||||
return cljs.core.disj.call(null,features__$1,new cljs.core.Keyword(null,"no-safe-draw","no-safe-draw",-1157778157));
|
||||
});
|
||||
/**
|
||||
* Checks if options map contains deprected options and removes them.
|
||||
* Prints messages how to fix deprecated functions.
|
||||
*/
|
||||
quil.middlewares.deprecated_options.deprecated_options = (function quil$middlewares$deprecated_options$deprecated_options(options){
|
||||
var options__$1 = cljs.core.update_in.call(null,options,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"features","features",-1146962336)], null),quil.middlewares.deprecated_options.check_features_vector);
|
||||
return cljs.core.into.call(null,cljs.core.PersistentArrayMap.EMPTY,cljs.core.remove.call(null,cljs.core.nil_QMARK_,(function (){var iter__7602__auto__ = ((function (options__$1){
|
||||
return (function quil$middlewares$deprecated_options$deprecated_options_$_iter__8043(s__8044){
|
||||
return (new cljs.core.LazySeq(null,((function (options__$1){
|
||||
return (function (){
|
||||
var s__8044__$1 = s__8044;
|
||||
while(true){
|
||||
var temp__4657__auto__ = cljs.core.seq.call(null,s__8044__$1);
|
||||
if(temp__4657__auto__){
|
||||
var s__8044__$2 = temp__4657__auto__;
|
||||
if(cljs.core.chunked_seq_QMARK_.call(null,s__8044__$2)){
|
||||
var c__7600__auto__ = cljs.core.chunk_first.call(null,s__8044__$2);
|
||||
var size__7601__auto__ = cljs.core.count.call(null,c__7600__auto__);
|
||||
var b__8046 = cljs.core.chunk_buffer.call(null,size__7601__auto__);
|
||||
if((function (){var i__8045 = (0);
|
||||
while(true){
|
||||
if((i__8045 < size__7601__auto__)){
|
||||
var vec__8059 = cljs.core._nth.call(null,c__7600__auto__,i__8045);
|
||||
var name = cljs.core.nth.call(null,vec__8059,(0),null);
|
||||
var value = cljs.core.nth.call(null,vec__8059,(1),null);
|
||||
cljs.core.chunk_append.call(null,b__8046,(function (){var temp__4655__auto__ = quil.middlewares.deprecated_options.deprecated.call(null,name);
|
||||
if(cljs.core.truth_(temp__4655__auto__)){
|
||||
var vec__8062 = temp__4655__auto__;
|
||||
var version = cljs.core.nth.call(null,vec__8062,(0),null);
|
||||
var message = cljs.core.nth.call(null,vec__8062,(1),null);
|
||||
cljs.core.println.call(null,name,"option was removed in Quil",version,".",message);
|
||||
|
||||
return null;
|
||||
} else {
|
||||
return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [name,value], null);
|
||||
}
|
||||
})());
|
||||
|
||||
var G__8071 = (i__8045 + (1));
|
||||
i__8045 = G__8071;
|
||||
continue;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
})()){
|
||||
return cljs.core.chunk_cons.call(null,cljs.core.chunk.call(null,b__8046),quil$middlewares$deprecated_options$deprecated_options_$_iter__8043.call(null,cljs.core.chunk_rest.call(null,s__8044__$2)));
|
||||
} else {
|
||||
return cljs.core.chunk_cons.call(null,cljs.core.chunk.call(null,b__8046),null);
|
||||
}
|
||||
} else {
|
||||
var vec__8065 = cljs.core.first.call(null,s__8044__$2);
|
||||
var name = cljs.core.nth.call(null,vec__8065,(0),null);
|
||||
var value = cljs.core.nth.call(null,vec__8065,(1),null);
|
||||
return cljs.core.cons.call(null,(function (){var temp__4655__auto__ = quil.middlewares.deprecated_options.deprecated.call(null,name);
|
||||
if(cljs.core.truth_(temp__4655__auto__)){
|
||||
var vec__8068 = temp__4655__auto__;
|
||||
var version = cljs.core.nth.call(null,vec__8068,(0),null);
|
||||
var message = cljs.core.nth.call(null,vec__8068,(1),null);
|
||||
cljs.core.println.call(null,name,"option was removed in Quil",version,".",message);
|
||||
|
||||
return null;
|
||||
} else {
|
||||
return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [name,value], null);
|
||||
}
|
||||
})(),quil$middlewares$deprecated_options$deprecated_options_$_iter__8043.call(null,cljs.core.rest.call(null,s__8044__$2)));
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});})(options__$1))
|
||||
,null,null));
|
||||
});})(options__$1))
|
||||
;
|
||||
return iter__7602__auto__.call(null,options__$1);
|
||||
})()));
|
||||
});
|
||||
|
||||
//# sourceMappingURL=deprecated_options.js.map
|
1
assets/viz/2/quil/middlewares/deprecated_options.js.map
Normal file
1
assets/viz/2/quil/middlewares/deprecated_options.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/quil\/middlewares\/deprecated_options.js","sources":["deprecated_options.cljc"],"lineCount":95,"mappings":";AAAA;;AAEA,iDAAA,2CAAA,wDAAA,mFAAA,MAAA,sDAAA,wDAAA,mFAAA,MAAA,gDAAA,qEAAA,mFAAA,MAAA,loBAAeA;AAKf,4DAAA,5DAAOC,gIAAuBC;AAA9B,AACE,IAAMA,eAAS,AAACC,wBAAID;AAApB,AACE,oBAAM,uBAAA,vBAACA;AAAP,AACE,4BAAA,iEAAA,7FAACE;;AADH;;AAGA,6CAAA,tCAACC,yBAAKH;;AAEV;;;;yDAAA,zDAAMI,0HAGHC;AAHH,AAIE,IAAMA,cAAQ,sCAAA,mFAAA,zHAACC,8BAAUD,iKAAoBN;AAA7C,mHACO,iBAAAQ,qBAAA,tFAKA,AAAC+B,2BAAOC,9FACR,gCAAA,zBAACC;qFANDhC;AAAA,AAAA,YAAAC,kBAAA,KAAA;;AAAA,AAAA,IAAAD,cAAAA;;AAAA,AAAA,IAAAE,qBAAA,AAAAC,wBAAAH;AAAA,AAAA,GAAAE;AAAA,AAAA,IAAAF,cAAAE;AAAA,AAAA,GAAA,AAAAE,uCAAAJ;AAAA,IAAAK,kBAqwE0C,AAAA4B,gCAAAjC;IArwE1CM,qBAAA,AAAAC,0BAAAF;IAAAG,UAAA,AAAAC,iCAAAH;AAAA,AAAA,GAAA,AAAA,iBAAAI,UAAA;;AAAA,AAAA,GAAA,CAAAA,UAAAJ;AAAA,IAAAK,YAAA,AAAAC,yBAAAP,gBAAAK;WAAA,AAAAG,wBAAAF,UAAA,IAAA,7CAAOY;YAAP,AAAAV,wBAAAF,UAAA,IAAA,9CAAYa;AAAZ,AAAA,AAAA,AAAAV,iCAAAN,QACE,iBAAAiB,qBAA2B,AAACnC,yDAAWiC;AAAvC,AAAA,oBAAAE;AAAA,IAAAC,YAAAD;cAAA,AAAAZ,wBAAAa,UAAA,IAAA,hDAAUE;cAAV,AAAAf,wBAAAa,UAAA,IAAA,hDAAkBG;AAAlB,AACE,AAAI,iCAAA,qCAAA,tEAACnC,4BAAQ6B,kCAAkCK,YAAYC;;AAA3D;;AADF,0FAGGN,KAAKC;;;;AAJV,cAAA,CAAAd,UAAA;;;;AAAA;;;;;AAAA,OAAAK,+BAAA,AAAAC,0BAAAR,SAAA,AAAAS,8EAAA,AAAAC,+BAAAlB;;AAAA,OAAAe,+BAAA,AAAAC,0BAAAR,SAAA;;;AAAA,IAAAW,YAAA,AAAAC,0BAAApB;WAAA,AAAAa,wBAAAM,UAAA,IAAA,7CAAOI;YAAP,AAAAV,wBAAAM,UAAA,IAAA,9CAAYK;AAAZ,AAAA,OAAAH,yBACE,iBAAAI,qBAA2B,AAACnC,yDAAWiC;AAAvC,AAAA,oBAAAE;AAAA,IAAAE,YAAAF;cAAA,AAAAZ,wBAAAc,UAAA,IAAA,hDAAUC;cAAV,AAAAf,wBAAAc,UAAA,IAAA,hDAAkBE;AAAlB,AACE,AAAI,iCAAA,qCAAA,tEAACnC,4BAAQ6B,kCAAkCK,YAAYC;;AAA3D;;AADF,0FAGGN,KAAKC;;KAJV,AAAAP,8EAAA,AAAAK,yBAAAtB;;;AAAA;;;;;CAAA,KAAA;;;AAAA,AAAA,OAAAD,6BAAmBF","names":["quil.middlewares.deprecated-options\/deprecated","quil.middlewares.deprecated-options\/check-features-vector","features","cljs.core\/set","cljs.core\/println","cljs.core\/disj","quil.middlewares.deprecated-options\/deprecated-options","options","cljs.core\/update-in","iter__7602__auto__","s__8044","cljs.core\/LazySeq","temp__4657__auto__","cljs.core\/seq","cljs.core\/chunked-seq?","c__7600__auto__","size__7601__auto__","cljs.core\/count","b__8046","cljs.core\/chunk-buffer","i__8045","vec__8059","cljs.core\/-nth","cljs.core\/nth","cljs.core\/chunk-append","cljs.core\/chunk-cons","cljs.core\/chunk","iter__8043","cljs.core\/chunk-rest","vec__8065","cljs.core\/first","cljs.core\/cons","cljs.core\/rest","name","value","temp__4655__auto__","vec__8062","vec__8068","version","message","cljs.core\/remove","cljs.core\/nil?","cljs.core\/into","cljs.core\/chunk-first"]}
|
78
assets/viz/2/quil/middlewares/fun_mode.cljc
Normal file
78
assets/viz/2/quil/middlewares/fun_mode.cljc
Normal file
@ -0,0 +1,78 @@
|
||||
(ns quil.middlewares.fun-mode
|
||||
(:require [quil.core :as q]))
|
||||
|
||||
(defn- wrap-setup [options]
|
||||
(let [setup (:setup options (fn [] nil))]
|
||||
(assoc options
|
||||
:setup #(reset! (q/state-atom) (setup)))))
|
||||
|
||||
(defn- wrap-draw-update [options]
|
||||
(let [draw (:draw options (fn [_]))
|
||||
update (:update options identity)
|
||||
quil-draw #(-> (q/state-atom)
|
||||
(swap! (if (= (q/frame-count) 1)
|
||||
identity
|
||||
update))
|
||||
(draw))]
|
||||
(-> options
|
||||
(dissoc :update)
|
||||
(assoc :draw quil-draw))))
|
||||
|
||||
(defn- mouse-event []
|
||||
{:x (q/mouse-x)
|
||||
:y (q/mouse-y)})
|
||||
|
||||
(defn- mouse-event-full []
|
||||
{:x (q/mouse-x)
|
||||
:y (q/mouse-y)
|
||||
:button (q/mouse-button)})
|
||||
|
||||
(defn- key-event []
|
||||
{:key (q/key-as-keyword)
|
||||
:key-code (q/key-code)
|
||||
:raw-key (q/raw-key)
|
||||
#?@(:clj [:modifiers (q/key-modifiers)])})
|
||||
|
||||
(defn- wrap-handler
|
||||
([options handler-key]
|
||||
(wrap-handler options handler-key nil))
|
||||
([options handler-key event-fn]
|
||||
(if-let [handler (options handler-key)]
|
||||
(assoc options handler-key
|
||||
(if event-fn
|
||||
#(swap! (q/state-atom) handler (event-fn))
|
||||
#(swap! (q/state-atom) handler)))
|
||||
options)))
|
||||
|
||||
(defn- wrap-handlers [options & handlers]
|
||||
(reduce (fn [options handler]
|
||||
(if (keyword? handler)
|
||||
(wrap-handler options handler)
|
||||
(apply wrap-handler options handler)))
|
||||
options handlers))
|
||||
|
||||
(defn- wrap-mouse-wheel [options]
|
||||
(if-let [handler (:mouse-wheel options)]
|
||||
(assoc options :mouse-wheel
|
||||
(fn [rotation]
|
||||
(swap! (q/state-atom) handler rotation)))
|
||||
options))
|
||||
|
||||
(defn fun-mode
|
||||
"Introduces function mode making all handlers (setup, draw, mouse-click, etc)
|
||||
state-aware. Adds support for 'update' function."
|
||||
[options]
|
||||
(-> options
|
||||
wrap-setup
|
||||
wrap-draw-update
|
||||
(wrap-handlers :focus-gained :focus-lost [:mouse-entered mouse-event]
|
||||
[:mouse-exited mouse-event] [:mouse-pressed mouse-event-full]
|
||||
[:mouse-released mouse-event] [:mouse-clicked mouse-event-full]
|
||||
[:mouse-moved (fn [] {:x (q/mouse-x) :y (q/mouse-y)
|
||||
:p-x (q/pmouse-x) :p-y (q/pmouse-y)})]
|
||||
[:mouse-dragged (fn [] {:x (q/mouse-x) :y (q/mouse-y)
|
||||
:p-x (q/pmouse-x) :p-y (q/pmouse-y)
|
||||
:button (q/mouse-button)})]
|
||||
[:key-pressed key-event] :key-released [:key-typed key-event]
|
||||
:on-close)
|
||||
wrap-mouse-wheel))
|
1
assets/viz/2/quil/middlewares/fun_mode.cljc.cache.edn
Normal file
1
assets/viz/2/quil/middlewares/fun_mode.cljc.cache.edn
Normal file
File diff suppressed because one or more lines are too long
155
assets/viz/2/quil/middlewares/fun_mode.js
Normal file
155
assets/viz/2/quil/middlewares/fun_mode.js
Normal file
@ -0,0 +1,155 @@
|
||||
// Compiled by ClojureScript 1.9.473 {}
|
||||
goog.provide('quil.middlewares.fun_mode');
|
||||
goog.require('cljs.core');
|
||||
goog.require('quil.core');
|
||||
quil.middlewares.fun_mode.wrap_setup = (function quil$middlewares$fun_mode$wrap_setup(options){
|
||||
var setup = new cljs.core.Keyword(null,"setup","setup",1987730512).cljs$core$IFn$_invoke$arity$2(options,(function (){
|
||||
return null;
|
||||
}));
|
||||
return cljs.core.assoc.call(null,options,new cljs.core.Keyword(null,"setup","setup",1987730512),((function (setup){
|
||||
return (function (){
|
||||
return cljs.core.reset_BANG_.call(null,quil.core.state_atom.call(null),setup.call(null));
|
||||
});})(setup))
|
||||
);
|
||||
});
|
||||
quil.middlewares.fun_mode.wrap_draw_update = (function quil$middlewares$fun_mode$wrap_draw_update(options){
|
||||
var draw = new cljs.core.Keyword(null,"draw","draw",1358331674).cljs$core$IFn$_invoke$arity$2(options,(function (_){
|
||||
return null;
|
||||
}));
|
||||
var update = new cljs.core.Keyword(null,"update","update",1045576396).cljs$core$IFn$_invoke$arity$2(options,cljs.core.identity);
|
||||
var quil_draw = ((function (draw,update){
|
||||
return (function (){
|
||||
return draw.call(null,cljs.core.swap_BANG_.call(null,quil.core.state_atom.call(null),((cljs.core._EQ_.call(null,quil.core.frame_count.call(null),(1)))?cljs.core.identity:update)));
|
||||
});})(draw,update))
|
||||
;
|
||||
return cljs.core.assoc.call(null,cljs.core.dissoc.call(null,options,new cljs.core.Keyword(null,"update","update",1045576396)),new cljs.core.Keyword(null,"draw","draw",1358331674),quil_draw);
|
||||
});
|
||||
quil.middlewares.fun_mode.mouse_event = (function quil$middlewares$fun_mode$mouse_event(){
|
||||
return new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"x","x",2099068185),quil.core.mouse_x.call(null),new cljs.core.Keyword(null,"y","y",-1757859776),quil.core.mouse_y.call(null)], null);
|
||||
});
|
||||
quil.middlewares.fun_mode.mouse_event_full = (function quil$middlewares$fun_mode$mouse_event_full(){
|
||||
return new cljs.core.PersistentArrayMap(null, 3, [new cljs.core.Keyword(null,"x","x",2099068185),quil.core.mouse_x.call(null),new cljs.core.Keyword(null,"y","y",-1757859776),quil.core.mouse_y.call(null),new cljs.core.Keyword(null,"button","button",1456579943),quil.core.mouse_button.call(null)], null);
|
||||
});
|
||||
quil.middlewares.fun_mode.key_event = (function quil$middlewares$fun_mode$key_event(){
|
||||
return new cljs.core.PersistentArrayMap(null, 3, [new cljs.core.Keyword(null,"key","key",-1516042587),quil.core.key_as_keyword.call(null),new cljs.core.Keyword(null,"key-code","key-code",-1732114304),quil.core.key_code.call(null),new cljs.core.Keyword(null,"raw-key","raw-key",-162482279),quil.core.raw_key.call(null)], null);
|
||||
});
|
||||
quil.middlewares.fun_mode.wrap_handler = (function quil$middlewares$fun_mode$wrap_handler(var_args){
|
||||
var args9436 = [];
|
||||
var len__7927__auto___9439 = arguments.length;
|
||||
var i__7928__auto___9440 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___9440 < len__7927__auto___9439)){
|
||||
args9436.push((arguments[i__7928__auto___9440]));
|
||||
|
||||
var G__9441 = (i__7928__auto___9440 + (1));
|
||||
i__7928__auto___9440 = G__9441;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var G__9438 = args9436.length;
|
||||
switch (G__9438) {
|
||||
case 2:
|
||||
return quil.middlewares.fun_mode.wrap_handler.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
|
||||
|
||||
break;
|
||||
case 3:
|
||||
return quil.middlewares.fun_mode.wrap_handler.cljs$core$IFn$_invoke$arity$3((arguments[(0)]),(arguments[(1)]),(arguments[(2)]));
|
||||
|
||||
break;
|
||||
default:
|
||||
throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid arity: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(args9436.length)].join('')));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
quil.middlewares.fun_mode.wrap_handler.cljs$core$IFn$_invoke$arity$2 = (function (options,handler_key){
|
||||
return quil.middlewares.fun_mode.wrap_handler.call(null,options,handler_key,null);
|
||||
});
|
||||
|
||||
quil.middlewares.fun_mode.wrap_handler.cljs$core$IFn$_invoke$arity$3 = (function (options,handler_key,event_fn){
|
||||
var temp__4655__auto__ = options.call(null,handler_key);
|
||||
if(cljs.core.truth_(temp__4655__auto__)){
|
||||
var handler = temp__4655__auto__;
|
||||
return cljs.core.assoc.call(null,options,handler_key,(cljs.core.truth_(event_fn)?((function (handler,temp__4655__auto__){
|
||||
return (function (){
|
||||
return cljs.core.swap_BANG_.call(null,quil.core.state_atom.call(null),handler,event_fn.call(null));
|
||||
});})(handler,temp__4655__auto__))
|
||||
:((function (handler,temp__4655__auto__){
|
||||
return (function (){
|
||||
return cljs.core.swap_BANG_.call(null,quil.core.state_atom.call(null),handler);
|
||||
});})(handler,temp__4655__auto__))
|
||||
));
|
||||
} else {
|
||||
return options;
|
||||
}
|
||||
});
|
||||
|
||||
quil.middlewares.fun_mode.wrap_handler.cljs$lang$maxFixedArity = 3;
|
||||
|
||||
quil.middlewares.fun_mode.wrap_handlers = (function quil$middlewares$fun_mode$wrap_handlers(var_args){
|
||||
var args__7934__auto__ = [];
|
||||
var len__7927__auto___9445 = arguments.length;
|
||||
var i__7928__auto___9446 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___9446 < len__7927__auto___9445)){
|
||||
args__7934__auto__.push((arguments[i__7928__auto___9446]));
|
||||
|
||||
var G__9447 = (i__7928__auto___9446 + (1));
|
||||
i__7928__auto___9446 = G__9447;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var argseq__7935__auto__ = ((((1) < args__7934__auto__.length))?(new cljs.core.IndexedSeq(args__7934__auto__.slice((1)),(0),null)):null);
|
||||
return quil.middlewares.fun_mode.wrap_handlers.cljs$core$IFn$_invoke$arity$variadic((arguments[(0)]),argseq__7935__auto__);
|
||||
});
|
||||
|
||||
quil.middlewares.fun_mode.wrap_handlers.cljs$core$IFn$_invoke$arity$variadic = (function (options,handlers){
|
||||
return cljs.core.reduce.call(null,(function (options__$1,handler){
|
||||
if((handler instanceof cljs.core.Keyword)){
|
||||
return quil.middlewares.fun_mode.wrap_handler.call(null,options__$1,handler);
|
||||
} else {
|
||||
return cljs.core.apply.call(null,quil.middlewares.fun_mode.wrap_handler,options__$1,handler);
|
||||
}
|
||||
}),options,handlers);
|
||||
});
|
||||
|
||||
quil.middlewares.fun_mode.wrap_handlers.cljs$lang$maxFixedArity = (1);
|
||||
|
||||
quil.middlewares.fun_mode.wrap_handlers.cljs$lang$applyTo = (function (seq9443){
|
||||
var G__9444 = cljs.core.first.call(null,seq9443);
|
||||
var seq9443__$1 = cljs.core.next.call(null,seq9443);
|
||||
return quil.middlewares.fun_mode.wrap_handlers.cljs$core$IFn$_invoke$arity$variadic(G__9444,seq9443__$1);
|
||||
});
|
||||
|
||||
quil.middlewares.fun_mode.wrap_mouse_wheel = (function quil$middlewares$fun_mode$wrap_mouse_wheel(options){
|
||||
var temp__4655__auto__ = new cljs.core.Keyword(null,"mouse-wheel","mouse-wheel",1811662439).cljs$core$IFn$_invoke$arity$1(options);
|
||||
if(cljs.core.truth_(temp__4655__auto__)){
|
||||
var handler = temp__4655__auto__;
|
||||
return cljs.core.assoc.call(null,options,new cljs.core.Keyword(null,"mouse-wheel","mouse-wheel",1811662439),((function (handler,temp__4655__auto__){
|
||||
return (function (rotation){
|
||||
return cljs.core.swap_BANG_.call(null,quil.core.state_atom.call(null),handler,rotation);
|
||||
});})(handler,temp__4655__auto__))
|
||||
);
|
||||
} else {
|
||||
return options;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Introduces function mode making all handlers (setup, draw, mouse-click, etc)
|
||||
* state-aware. Adds support for 'update' function.
|
||||
*/
|
||||
quil.middlewares.fun_mode.fun_mode = (function quil$middlewares$fun_mode$fun_mode(options){
|
||||
return quil.middlewares.fun_mode.wrap_mouse_wheel.call(null,quil.middlewares.fun_mode.wrap_handlers.call(null,quil.middlewares.fun_mode.wrap_draw_update.call(null,quil.middlewares.fun_mode.wrap_setup.call(null,options)),new cljs.core.Keyword(null,"focus-gained","focus-gained",-857086384),new cljs.core.Keyword(null,"focus-lost","focus-lost",-554849613),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-entered","mouse-entered",811350322),quil.middlewares.fun_mode.mouse_event], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-exited","mouse-exited",-483205244),quil.middlewares.fun_mode.mouse_event], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-pressed","mouse-pressed",736955536),quil.middlewares.fun_mode.mouse_event_full], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-released","mouse-released",-664480061),quil.middlewares.fun_mode.mouse_event], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-clicked","mouse-clicked",-199339421),quil.middlewares.fun_mode.mouse_event_full], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-moved","mouse-moved",-1918152310),(function (){
|
||||
return new cljs.core.PersistentArrayMap(null, 4, [new cljs.core.Keyword(null,"x","x",2099068185),quil.core.mouse_x.call(null),new cljs.core.Keyword(null,"y","y",-1757859776),quil.core.mouse_y.call(null),new cljs.core.Keyword(null,"p-x","p-x",-1721211211),quil.core.pmouse_x.call(null),new cljs.core.Keyword(null,"p-y","p-y",-530704830),quil.core.pmouse_y.call(null)], null);
|
||||
})], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-dragged","mouse-dragged",-1220073441),(function (){
|
||||
return new cljs.core.PersistentArrayMap(null, 5, [new cljs.core.Keyword(null,"x","x",2099068185),quil.core.mouse_x.call(null),new cljs.core.Keyword(null,"y","y",-1757859776),quil.core.mouse_y.call(null),new cljs.core.Keyword(null,"p-x","p-x",-1721211211),quil.core.pmouse_x.call(null),new cljs.core.Keyword(null,"p-y","p-y",-530704830),quil.core.pmouse_y.call(null),new cljs.core.Keyword(null,"button","button",1456579943),quil.core.mouse_button.call(null)], null);
|
||||
})], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"key-pressed","key-pressed",-757100364),quil.middlewares.fun_mode.key_event], null),new cljs.core.Keyword(null,"key-released","key-released",215919828),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"key-typed","key-typed",-876037597),quil.middlewares.fun_mode.key_event], null),new cljs.core.Keyword(null,"on-close","on-close",-761178394)));
|
||||
});
|
||||
|
||||
//# sourceMappingURL=fun_mode.js.map
|
1
assets/viz/2/quil/middlewares/fun_mode.js.map
Normal file
1
assets/viz/2/quil/middlewares/fun_mode.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/quil\/middlewares\/fun_mode.js","sources":["fun_mode.cljc"],"lineCount":155,"mappings":";AAAA;;;AAGA,uCAAA,vCAAOA,sFAAYC;AAAnB,AACE,IAAMC,QAAM,AAAA,qFAAQD,QAAQ;AAAA,AAAA;;AAA5B,AACE,yCAAA,uDAAA,zFAACE,0BAAMF;;AAAP,AACU,OAACG,gCAAO,AAACC,gCAAc,AAACH;;;;AAEtC,6CAAA,7CAAOI,kGAAkBL;AAAzB,AACE,IAAMM,OAAK,AAAA,mFAAON,QAAQ,WAAKO;AAAL,AAAA;;IACpBC,SAAO,AAAA,uFAASR,QAAQS;gBAD9B,ZAEMC;;AAFN,qDAEqB,AAACN,\/BACD,AAACO,+DAAM,EAAI,0DAAA,1DAACC,yBAAE,AAACC,uCACNJ,mBACAD,1KACT,OAACF;;;AANtB,4DAOMN,3BACA,mCAAA,nCAACc,jCACD,8HAAA,vHAACZ,4KAAYQ;;AAErB,wCAAA,xCAAOK;AAAP,AAAA,kDAAA,4EAAA,7BACM,AAACC,6EACD,AAACC;;AAEP,6CAAA,7CAAOC;AAAP,AAAA,kDAAA,4EAAA,6EAAA,1GACM,AAACF,6EACD,AAACC,sFACI,AAACE;;AAEZ,sCAAA,tCAAOC;AAAP,AAAA,kDAAA,wFAAA,4FAAA,hIACQ,AAACC,kGACI,AAACC,yFACF,AAACC;;AAGb,AAAA,yCAAA,iDAAAC,1FAAOK;AAAP,AAAA,IAAAJ,WAAA;AAAA,AAAA,IAAAC,yBAAA,AAAA;AAAA,AAAA,IAAAC,uBAAA;;AAAA,AAAA,GAAA,CAAAA,uBAAAD;AAAA,AAAA,AAAAD,cAAA,CAAA,UAAAE;;AAAA,cAAA,CAAAA,uBAAA;;;;AAAA;;;;AAAA,IAAAC,UAAA,AAAAH;AAAA,AAAA,QAAAG;KAAA;AAAA,OAAAC,qEAAA,CAAA,UAAA,MAAA,CAAA,UAAA;;;KAAA;AAAA,OAAAA,qEAAA,CAAA,UAAA,MAAA,CAAA,UAAA,MAAA,CAAA,UAAA;;;;AAAA,MAAA,KAAAC,MAAA,6CAAA,+DAAA,AAAAL;;;;;AAAA,AAAA,uEAAA,vEAAOI,kFACH7B,QAAQ+B;AADZ,AAEK,4EAAA,rEAACF,iDAAa7B,QAAQ+B;;;AAF3B,AAAA,uEAAA,vEAAOF,kFAGH7B,QAAQ+B,YAAYC;AAHxB,AAIK,IAAAC,qBAAiB,AAACjC,kBAAQ+B;AAA1B,AAAA,oBAAAE;AAAA,cAAAA,VAASC;AAAT,AACE,OAAChC,0BAAMF,QAAQ+B,YACR,4BAAA,VAAIC;;AAAJ,AACG,OAACrB,+BAAM,AAACP,gCAAc8B,QAAQ,AAACF;;CADlC;;AAAA,AAEG,OAACrB,+BAAM,AAACP,gCAAc8B;;;;AAChClC;;;;AATP,AAAA,iEAAA,jEAAO6B;;AAAP,AAWA,AAAA,0CAAA,kDAAAL,5FAAOc;AAAP,AAAA,IAAAH,qBAAA;AAAA,AAAA,IAAAT,yBAAA,AAAA;AAAA,AAAA,IAAAC,uBAAA;;AAAA,AAAA,GAAA,CAAAA,uBAAAD;AAAA,AAAA,AAAAS,wBAAA,CAAA,UAAAR;;AAAA,cAAA,CAAAA,uBAAA;;;;AAAA;;;;AAAA,IAAAS,uBAAA,EAAA,CAAA,MAAA,AAAAD,4BAAA,AAAA,KAAAE,qBAAA,AAAAF,yBAAA,KAAA,IAAA,OAAA;AAAA,AAAA,OAAAG,6EAAA,CAAA,UAAA,MAAAF;;;AAAA,AAAA,AAAA,AAAAE,+EAAA,WAAsBtC,QAAU2C;AAAhC,AACE,OAACC,2BAAO,WAAK5C,YAAQkC;AAAb,AACE,GAAI,oBAAAW,nBAAUX;AACZ,OAACL,iDAAa7B,YAAQkC;;AACtB,OAACY,0BAAMjB,uCAAa7B,YAAQkC;;GAChClC,QAAQ2C;;;AALlB,AAAA,AAAAL,kEAAA;;AAAA,AAAA,AAAAA,4DAAA,WAAAC;AAAA,AAAA,IAAAC,UAAA,AAAAC,0BAAAF;IAAAA,cAAA,AAAAG,yBAAAH;AAAA,AAAA,OAAAD,6EAAAE,QAAAD;;;AAAA,AAOA,6CAAA,7CAAOQ,kGAAkB\/C;AAAzB,AACE,IAAAiC,qBAAiB,AAAA,iGAAcjC;AAA\/B,AAAA,oBAAAiC;AAAA,cAAAA,VAASC;AAAT,AACE,yCAAA,lCAAChC,0BAAMF,2EACA;kBAAKgD;AAAL,AACE,OAACrC,+BAAM,AAACP,gCAAc8B,QAAQc;;;;AACvChD;;;AAEJ;;;;qCAAA,rCAAMiD,kFAGHjD;AAHH,AAIE,kNAAIA,\/CACAD,rDACAM,lDACA,kDAAA,qDAAA,yDAAA,qEAAA,iEAAA,mFAAA,oHAAA,mFAAA,mHAAA,mFAAA,yHAAA,mFAAA,uHAAA,mFAAA,0HAAA,mFAAA,z2CAACiC,+bAAwDvB,sMAC3BA,uMAA6BG,+MAC3BH,wMAA6BG,0MAChC,l+CAO7B6B;AAP6B,AAAA,kDAAA,4EAAA,6EAAA,kFAAA,5LAAW,AAAC\/B,6EAAc,AAACC,iFACd,AAACiC,iFAAiB,AAACC;WAJ7D,mFAAA,wEAK+B;AAAA,AAAA,kDAAA,4EAAA,6EAAA,kFAAA,iFAAA,7QAAW,AAACnC,6EAAc,AAACC,iFACd,AAACiC,iFAAiB,AAACC,uFAChB,AAAChC;WAPhD,mFAAA,+GAAA,oEAAA,mFAAA,2GAAA,9SAQ6BC,kQAAqCA","names":["quil.middlewares.fun-mode\/wrap-setup","options","setup","cljs.core\/assoc","cljs.core\/reset!","quil.core\/state-atom","quil.middlewares.fun-mode\/wrap-draw-update","draw","_","update","cljs.core\/identity","quil-draw","cljs.core\/swap!","cljs.core\/=","quil.core\/frame-count","cljs.core\/dissoc","quil.middlewares.fun-mode\/mouse-event","quil.core\/mouse-x","quil.core\/mouse-y","quil.middlewares.fun-mode\/mouse-event-full","quil.core\/mouse-button","quil.middlewares.fun-mode\/key-event","quil.core\/key-as-keyword","quil.core\/key-code","quil.core\/raw-key","var_args","args9436","len__7927__auto__","i__7928__auto__","G__9438","quil.middlewares.fun-mode\/wrap-handler","js\/Error","handler-key","event-fn","temp__4655__auto__","handler","args__7934__auto__","argseq__7935__auto__","cljs.core\/IndexedSeq","quil.middlewares.fun-mode\/wrap-handlers","seq9443","G__9444","cljs.core\/first","cljs.core\/next","handlers","cljs.core\/reduce","cljs.core\/Keyword","cljs.core\/apply","quil.middlewares.fun-mode\/wrap-mouse-wheel","rotation","quil.middlewares.fun-mode\/fun-mode","quil.core\/pmouse-x","quil.core\/pmouse-y"]}
|
89
assets/viz/2/quil/middlewares/navigation_2d.cljc
Normal file
89
assets/viz/2/quil/middlewares/navigation_2d.cljc
Normal file
@ -0,0 +1,89 @@
|
||||
(ns quil.middlewares.navigation-2d
|
||||
(:require [quil.core :as q :include-macros true]))
|
||||
|
||||
(def ^:private missing-navigation-key-error
|
||||
(str "state map is missing :navigation-2d key. "
|
||||
"Did you accidentally removed it from the state in "
|
||||
":update or any other handler?"))
|
||||
|
||||
(defn- assert-state-has-navigation
|
||||
"Asserts that state map contains :navigation-2d object."
|
||||
[state]
|
||||
(when-not (:navigation-2d state)
|
||||
(throw #?(:clj (RuntimeException. missing-navigation-key-error)
|
||||
:cljs (js/Error. missing-navigation-key-error)))))
|
||||
|
||||
(defn- default-position
|
||||
"Default position configuration: zoom is neutral and central point is
|
||||
width/2, height/2."
|
||||
[]
|
||||
{:position [(/ (q/width) 2.0)
|
||||
(/ (q/height) 2.0)]
|
||||
:zoom 1})
|
||||
|
||||
(defn- setup-2d-nav
|
||||
"Custom 'setup' function which creates initial position
|
||||
configuration and puts it to the state map."
|
||||
[user-setup user-settings]
|
||||
(let [initial-state (-> user-settings
|
||||
(select-keys [:position :zoom])
|
||||
(->> (merge (default-position))))]
|
||||
(update-in (user-setup) [:navigation-2d]
|
||||
#(merge initial-state %))))
|
||||
|
||||
(defn- mouse-dragged
|
||||
"Changes center of the sketch depending on the last mouse move. Takes
|
||||
zoom into account as well."
|
||||
[state event]
|
||||
(assert-state-has-navigation state)
|
||||
(let [dx (- (:p-x event) (:x event))
|
||||
dy (- (:p-y event) (:y event))
|
||||
zoom (-> state :navigation-2d :zoom)]
|
||||
(-> state
|
||||
(update-in [:navigation-2d :position 0] + (/ dx zoom))
|
||||
(update-in [:navigation-2d :position 1] + (/ dy zoom)))))
|
||||
|
||||
(defn- mouse-wheel
|
||||
"Changes zoom settings based on scroll."
|
||||
[state event]
|
||||
(assert-state-has-navigation state)
|
||||
(update-in state [:navigation-2d :zoom] * (+ 1 (* -0.1 event))))
|
||||
|
||||
(defn- draw
|
||||
"Calls user draw function with necessary all transformations (position
|
||||
and zoom) applied."
|
||||
[user-draw state]
|
||||
(assert-state-has-navigation state)
|
||||
(q/push-matrix)
|
||||
(let [nav-2d (:navigation-2d state)
|
||||
zoom (:zoom nav-2d)
|
||||
pos (:position nav-2d)]
|
||||
(q/scale zoom)
|
||||
(q/with-translation [(- (/ (q/width) 2 zoom) (first pos))
|
||||
(- (/ (q/height) 2 zoom) (second pos))]
|
||||
(user-draw state)))
|
||||
(q/pop-matrix))
|
||||
|
||||
(defn navigation-2d
|
||||
"Enables navigation over 2D sketch. Dragging mouse will move center of the
|
||||
skecth and mouse wheel controls zoom."
|
||||
[options]
|
||||
(let [; 2d-navigation related user settings
|
||||
user-settings (:navigation-2d options)
|
||||
|
||||
; user-provided handlers which will be overridden
|
||||
; by 3d-navigation
|
||||
user-draw (:draw options (fn [state]))
|
||||
user-mouse-dragged (:mouse-dragged options (fn [state _] state))
|
||||
user-mouse-wheel (:mouse-wheel options (fn [state _] state))
|
||||
setup (:setup options (fn [] {}))]
|
||||
(assoc options
|
||||
|
||||
:setup (partial setup-2d-nav setup user-settings)
|
||||
|
||||
:draw (partial draw user-draw)
|
||||
|
||||
:mouse-dragged (fn [state event]
|
||||
(user-mouse-dragged (mouse-dragged state event) event))
|
||||
:mouse-wheel (fn [state event]
|
||||
(user-mouse-wheel (mouse-wheel state event) event)))))
|
File diff suppressed because one or more lines are too long
116
assets/viz/2/quil/middlewares/navigation_2d.js
Normal file
116
assets/viz/2/quil/middlewares/navigation_2d.js
Normal file
@ -0,0 +1,116 @@
|
||||
// Compiled by ClojureScript 1.9.473 {}
|
||||
goog.provide('quil.middlewares.navigation_2d');
|
||||
goog.require('cljs.core');
|
||||
goog.require('quil.core');
|
||||
quil.middlewares.navigation_2d.missing_navigation_key_error = [cljs.core.str.cljs$core$IFn$_invoke$arity$1("state map is missing :navigation-2d key. "),cljs.core.str.cljs$core$IFn$_invoke$arity$1("Did you accidentally removed it from the state in "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(":update or any other handler?")].join('');
|
||||
/**
|
||||
* Asserts that state map contains :navigation-2d object.
|
||||
*/
|
||||
quil.middlewares.navigation_2d.assert_state_has_navigation = (function quil$middlewares$navigation_2d$assert_state_has_navigation(state){
|
||||
if(cljs.core.truth_(new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611).cljs$core$IFn$_invoke$arity$1(state))){
|
||||
return null;
|
||||
} else {
|
||||
throw (new Error(quil.middlewares.navigation_2d.missing_navigation_key_error));
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Default position configuration: zoom is neutral and central point is
|
||||
* width/2, height/2.
|
||||
*/
|
||||
quil.middlewares.navigation_2d.default_position = (function quil$middlewares$navigation_2d$default_position(){
|
||||
return new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"position","position",-2011731912),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(quil.core.width.call(null) / 2.0),(quil.core.height.call(null) / 2.0)], null),new cljs.core.Keyword(null,"zoom","zoom",-1827487038),(1)], null);
|
||||
});
|
||||
/**
|
||||
* Custom 'setup' function which creates initial position
|
||||
* configuration and puts it to the state map.
|
||||
*/
|
||||
quil.middlewares.navigation_2d.setup_2d_nav = (function quil$middlewares$navigation_2d$setup_2d_nav(user_setup,user_settings){
|
||||
var initial_state = cljs.core.merge.call(null,quil.middlewares.navigation_2d.default_position.call(null),cljs.core.select_keys.call(null,user_settings,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"position","position",-2011731912),new cljs.core.Keyword(null,"zoom","zoom",-1827487038)], null)));
|
||||
return cljs.core.update_in.call(null,user_setup.call(null),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611)], null),((function (initial_state){
|
||||
return (function (p1__9429_SHARP_){
|
||||
return cljs.core.merge.call(null,initial_state,p1__9429_SHARP_);
|
||||
});})(initial_state))
|
||||
);
|
||||
});
|
||||
/**
|
||||
* Changes center of the sketch depending on the last mouse move. Takes
|
||||
* zoom into account as well.
|
||||
*/
|
||||
quil.middlewares.navigation_2d.mouse_dragged = (function quil$middlewares$navigation_2d$mouse_dragged(state,event){
|
||||
quil.middlewares.navigation_2d.assert_state_has_navigation.call(null,state);
|
||||
|
||||
var dx = (new cljs.core.Keyword(null,"p-x","p-x",-1721211211).cljs$core$IFn$_invoke$arity$1(event) - new cljs.core.Keyword(null,"x","x",2099068185).cljs$core$IFn$_invoke$arity$1(event));
|
||||
var dy = (new cljs.core.Keyword(null,"p-y","p-y",-530704830).cljs$core$IFn$_invoke$arity$1(event) - new cljs.core.Keyword(null,"y","y",-1757859776).cljs$core$IFn$_invoke$arity$1(event));
|
||||
var zoom = new cljs.core.Keyword(null,"zoom","zoom",-1827487038).cljs$core$IFn$_invoke$arity$1(new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611).cljs$core$IFn$_invoke$arity$1(state));
|
||||
return cljs.core.update_in.call(null,cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611),new cljs.core.Keyword(null,"position","position",-2011731912),(0)], null),cljs.core._PLUS_,(dx / zoom)),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611),new cljs.core.Keyword(null,"position","position",-2011731912),(1)], null),cljs.core._PLUS_,(dy / zoom));
|
||||
});
|
||||
/**
|
||||
* Changes zoom settings based on scroll.
|
||||
*/
|
||||
quil.middlewares.navigation_2d.mouse_wheel = (function quil$middlewares$navigation_2d$mouse_wheel(state,event){
|
||||
quil.middlewares.navigation_2d.assert_state_has_navigation.call(null,state);
|
||||
|
||||
return cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611),new cljs.core.Keyword(null,"zoom","zoom",-1827487038)], null),cljs.core._STAR_,((1) + (-0.1 * event)));
|
||||
});
|
||||
/**
|
||||
* Calls user draw function with necessary all transformations (position
|
||||
* and zoom) applied.
|
||||
*/
|
||||
quil.middlewares.navigation_2d.draw = (function quil$middlewares$navigation_2d$draw(user_draw,state){
|
||||
quil.middlewares.navigation_2d.assert_state_has_navigation.call(null,state);
|
||||
|
||||
quil.core.push_matrix.call(null);
|
||||
|
||||
var nav_2d_9430 = new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611).cljs$core$IFn$_invoke$arity$1(state);
|
||||
var zoom_9431 = new cljs.core.Keyword(null,"zoom","zoom",-1827487038).cljs$core$IFn$_invoke$arity$1(nav_2d_9430);
|
||||
var pos_9432 = new cljs.core.Keyword(null,"position","position",-2011731912).cljs$core$IFn$_invoke$arity$1(nav_2d_9430);
|
||||
quil.core.scale.call(null,zoom_9431);
|
||||
|
||||
var tr__9352__auto___9433 = new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(((quil.core.width.call(null) / (2)) / zoom_9431) - cljs.core.first.call(null,pos_9432)),(((quil.core.height.call(null) / (2)) / zoom_9431) - cljs.core.second.call(null,pos_9432))], null);
|
||||
quil.core.push_matrix.call(null);
|
||||
|
||||
try{quil.core.translate.call(null,tr__9352__auto___9433);
|
||||
|
||||
user_draw.call(null,state);
|
||||
}finally {quil.core.pop_matrix.call(null);
|
||||
}
|
||||
return quil.core.pop_matrix.call(null);
|
||||
});
|
||||
/**
|
||||
* Enables navigation over 2D sketch. Dragging mouse will move center of the
|
||||
* skecth and mouse wheel controls zoom.
|
||||
*/
|
||||
quil.middlewares.navigation_2d.navigation_2d = (function quil$middlewares$navigation_2d$navigation_2d(options){
|
||||
var user_settings = new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611).cljs$core$IFn$_invoke$arity$1(options);
|
||||
var user_draw = new cljs.core.Keyword(null,"draw","draw",1358331674).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings){
|
||||
return (function (state){
|
||||
return null;
|
||||
});})(user_settings))
|
||||
);
|
||||
var user_mouse_dragged = new cljs.core.Keyword(null,"mouse-dragged","mouse-dragged",-1220073441).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings,user_draw){
|
||||
return (function (state,_){
|
||||
return state;
|
||||
});})(user_settings,user_draw))
|
||||
);
|
||||
var user_mouse_wheel = new cljs.core.Keyword(null,"mouse-wheel","mouse-wheel",1811662439).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings,user_draw,user_mouse_dragged){
|
||||
return (function (state,_){
|
||||
return state;
|
||||
});})(user_settings,user_draw,user_mouse_dragged))
|
||||
);
|
||||
var setup = new cljs.core.Keyword(null,"setup","setup",1987730512).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings,user_draw,user_mouse_dragged,user_mouse_wheel){
|
||||
return (function (){
|
||||
return cljs.core.PersistentArrayMap.EMPTY;
|
||||
});})(user_settings,user_draw,user_mouse_dragged,user_mouse_wheel))
|
||||
);
|
||||
return cljs.core.assoc.call(null,options,new cljs.core.Keyword(null,"setup","setup",1987730512),cljs.core.partial.call(null,quil.middlewares.navigation_2d.setup_2d_nav,setup,user_settings),new cljs.core.Keyword(null,"draw","draw",1358331674),cljs.core.partial.call(null,quil.middlewares.navigation_2d.draw,user_draw),new cljs.core.Keyword(null,"mouse-dragged","mouse-dragged",-1220073441),((function (user_settings,user_draw,user_mouse_dragged,user_mouse_wheel,setup){
|
||||
return (function (state,event){
|
||||
return user_mouse_dragged.call(null,quil.middlewares.navigation_2d.mouse_dragged.call(null,state,event),event);
|
||||
});})(user_settings,user_draw,user_mouse_dragged,user_mouse_wheel,setup))
|
||||
,new cljs.core.Keyword(null,"mouse-wheel","mouse-wheel",1811662439),((function (user_settings,user_draw,user_mouse_dragged,user_mouse_wheel,setup){
|
||||
return (function (state,event){
|
||||
return user_mouse_wheel.call(null,quil.middlewares.navigation_2d.mouse_wheel.call(null,state,event),event);
|
||||
});})(user_settings,user_draw,user_mouse_dragged,user_mouse_wheel,setup))
|
||||
);
|
||||
});
|
||||
|
||||
//# sourceMappingURL=navigation_2d.js.map
|
1
assets/viz/2/quil/middlewares/navigation_2d.js.map
Normal file
1
assets/viz/2/quil/middlewares/navigation_2d.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/quil\/middlewares\/navigation_2d.js","sources":["navigation_2d.cljc"],"lineCount":116,"mappings":";AAAA;;;AAGA,AAAeA,8DACb,6CAAA,yFAAA,kGAAA;AAIF;;;6DAAA,7DAAOC,kIAEJC;AAFH,AAGE,oBAAU,AAAA,sGAAgBA;AAA1B;;AAAA,AACE,MACgB,KAAAC,MAAWH;;;AAE\/B;;;;kDAAA,lDAAOI;AAAP,AAAA,kDAAA,8DAAA,kKAAA,sDAAA,rIAIc,8BAAA,7BAAG,AAACC,kCACJ,+BAAA,9BAAG,AAACC;;AAGlB;;;;8CAAA,9CAAOC,oGAGJC,WAAWC;AAHd,AAIE,IAAMC,qIAAkBD,hCACA,8CAAA,mFAAA,8DAAA,\/LAACE,rFACI,AAACC,0BAAM,AAACR;AAFrC,AAGE,2DAAA,mFAAA,gFAAA,vNAACU,8BAAU,AAACN;kBAAZK;AAAA,AACY,+CAAAA,xCAACD,0BAAMF;;;;AAEvB;;;;+CAAA,\/CAAOK,sGAGJb,MAAMc;AAHT,AAIE,AAACf,qEAA4BC;;AAC7B,IAAMe,KAAG,CAAG,AAAA,kFAAMD,SAAO,AAAA,6EAAIA;IACvBE,KAAG,CAAG,AAAA,iFAAMF,SAAO,AAAA,8EAAIA;IACvBG,OAAK,AAAA,oFAAA,AAAA,sGAAIjB;AAFf,mEAGKA,9BACA,oCAAA,mFAAA,wEAAA,8DAAA,7PAACY,yQAAuCM,iBAAE,CAAGH,KAAGE,rUAChD,4UAAA,mFAAA,wEAAA,8DAAA,9hBAACL,0iBAAuCM,iBAAE,CAAGF,KAAGC;;AAEvD;;;6CAAA,7CAAOE,kGAEJnB,MAAMc;AAFT,AAGE,AAACf,qEAA4BC;;AAC7B,2CAAA,mFAAA,wEAAA,\/LAACY,8BAAUZ,+NAA6BoB,iBAAE,CAAA,MAAK,CAAA,OAAQN;;AAEzD;;;;sCAAA,tCAAOO,oFAGJC,UAAUtB;AAHb,AAIE,AAACD,qEAA4BC;;AAC7B,AAACuB;;AACD,IAAMC,cAAO,AAAA,sGAAgBxB;IACvBiB,YAAK,AAAA,oFAAOO;IACZC,WAAI,AAAA,4FAAWD;AAFrB,AAGE,AAACE,0BAAQT;;AACT,IAAAU,wBAAA,mFAAqB,CAAG,CAAA,8BAAA,7BAAG,AAACxB,oCAAWc,aAAM,AAACa,0BAAML,WAC\/B,CAAG,CAAA,+BAAA,9BAAG,AAACrB,qCAAYa,aAAM,AAACc,2BAAON;AADtD,AAAA,AAAAF;;AAAA,IAAA,AAAA,AAAAK,8BAAAD;;AAEE,AAACL,oBAAUtB;UAFb,AAAA,AAAA6B;;AAGF,OAACA;;AAEH;;;;+CAAA,\/CAAMG,sGAGHC;AAHH,AAIE,IACM1B,gBAAc,AAAA,sGAAgB0B;IAI9BX,YAAU,AAAA,mFAAOW,QAAQ;kBAAKjC;AAAL,AAAA;;;IACzBkC,qBAAmB,AAAA,sGAAgBD,QAAQ;kBAAKjC,MAAMmC;AAAX,AAAcnC;;;IACzDoC,mBAAiB,AAAA,iGAAcH,QAAQ;kBAAKjC,MAAMmC;AAAX,AAAcnC;;;IACrDqC,QAAM,AAAA,qFAAQJ,QAAQ;;AAAA,AAAA;;;AAR5B,AASE,yCAAA,oJAAA,gIAAA,tTAACK,0BAAML,+DAEE,AAACM,4BAAQlC,4CAAagC,MAAM9B,oEAE7B,AAACgC,4BAAQlB,oCAAKC,mFAEL;kBAAKtB,MAAMc;AAAX,AACE,OAACoB,6BAAmB,AAACrB,uDAAcb,MAAMc,OAAOA;;CAPnE,mEAQe;kBAAKd,MAAMc;AAAX,AACE,OAACsB,2BAAiB,AAACjB,qDAAYnB,MAAMc,OAAOA","names":["quil.middlewares.navigation-2d\/missing-navigation-key-error","quil.middlewares.navigation-2d\/assert-state-has-navigation","state","js\/Error","quil.middlewares.navigation-2d\/default-position","quil.core\/width","quil.core\/height","quil.middlewares.navigation-2d\/setup-2d-nav","user-setup","user-settings","initial-state","cljs.core\/select-keys","cljs.core\/merge","p1__9429#","cljs.core\/update-in","quil.middlewares.navigation-2d\/mouse-dragged","event","dx","dy","zoom","cljs.core\/+","quil.middlewares.navigation-2d\/mouse-wheel","cljs.core\/*","quil.middlewares.navigation-2d\/draw","user-draw","quil.core\/push-matrix","nav-2d","pos","quil.core\/scale","tr__9352__auto__","quil.core\/translate","quil.core\/pop-matrix","cljs.core\/first","cljs.core\/second","quil.middlewares.navigation-2d\/navigation-2d","options","user-mouse-dragged","_","user-mouse-wheel","setup","cljs.core\/assoc","cljs.core\/partial"]}
|
188
assets/viz/2/quil/middlewares/navigation_3d.cljc
Normal file
188
assets/viz/2/quil/middlewares/navigation_3d.cljc
Normal file
@ -0,0 +1,188 @@
|
||||
(ns quil.middlewares.navigation-3d
|
||||
(:require [quil.core :as q]))
|
||||
|
||||
(def ^:private missing-navigation-key-error
|
||||
(str "state map is missing :navigation-3d key. "
|
||||
"Did you accidentally removed it from the state in "
|
||||
":update or any other handler?"))
|
||||
|
||||
(defn- assert-state-has-navigation
|
||||
"Asserts that state map contains :navigation-2d object."
|
||||
[state]
|
||||
(when-not (:navigation-3d state)
|
||||
(throw #?(:clj (RuntimeException. missing-navigation-key-error)
|
||||
:cljs (js/Error. missing-navigation-key-error)))))
|
||||
|
||||
(defn- default-position
|
||||
"Default position configuration. Check default configuration in
|
||||
'camera' function."
|
||||
[]
|
||||
{:position [(/ (q/width) 2.0)
|
||||
(/ (q/height) 2.0)
|
||||
(/ (q/height) 2.0 (q/tan (/ (* q/PI 60.0) 360.0)))]
|
||||
:straight [0 0 -1]
|
||||
:up [0 1 0]})
|
||||
|
||||
(defn- rotate-by-axis-and-angle
|
||||
"Rotates vector v by angle with axis.
|
||||
Formula is taken from wiki:
|
||||
http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle"
|
||||
[v axis angle]
|
||||
(let [[a-x a-y a-z] axis
|
||||
[x y z] v
|
||||
cs (q/cos angle)
|
||||
-cs (- 1 cs)
|
||||
sn (q/sin angle)
|
||||
; Matrix is
|
||||
; [a b c]
|
||||
; [d e f]
|
||||
; [g h i]
|
||||
a (+ cs (* a-x a-x -cs))
|
||||
b (- (* a-x a-y -cs)
|
||||
(* a-z sn))
|
||||
c (+ (* a-x a-z -cs)
|
||||
(* a-y sn))
|
||||
d (+ (* a-x a-y -cs)
|
||||
(* a-z sn))
|
||||
e (+ cs (* a-y a-y -cs))
|
||||
f (- (* a-y a-z -cs)
|
||||
(* a-x sn))
|
||||
g (- (* a-x a-z -cs)
|
||||
(* a-y sn))
|
||||
h (+ (* a-y a-z -cs)
|
||||
(* a-x sn))
|
||||
i (+ cs (* a-z a-z -cs))]
|
||||
[(+ (* a x) (* b y) (* c z))
|
||||
(+ (* d x) (* e y) (* f z))
|
||||
(+ (* g x) (* h y) (* i z))]))
|
||||
|
||||
(defn- rotate-lr
|
||||
"Rotates nav-3d configuration left-right. angle positive - rotate right,
|
||||
negative - left."
|
||||
[nav-3d angle]
|
||||
(update-in nav-3d [:straight] rotate-by-axis-and-angle (:up nav-3d) angle))
|
||||
|
||||
(defn- cross-product
|
||||
"Vector cross-product: http://en.wikipedia.org/wiki/Cross_product"
|
||||
[[u1 u2 u3] [v1 v2 v3]]
|
||||
[(- (* u2 v3) (* u3 v2))
|
||||
(- (* u3 v1) (* u1 v3))
|
||||
(- (* u1 v2) (* u2 v1))])
|
||||
|
||||
(defn- v-mult
|
||||
"Multiply vector v by scalar mult."
|
||||
[v mult]
|
||||
(mapv #(* % mult) v))
|
||||
|
||||
(defn- v-plus
|
||||
"Sum of 2 vectors."
|
||||
[v1 v2]
|
||||
(mapv + v1 v2))
|
||||
|
||||
(defn- v-opposite
|
||||
"Returns vector opposite to vector v."
|
||||
[v]
|
||||
(v-mult v -1))
|
||||
|
||||
(defn- v-normalize
|
||||
"Normalize vector, returning vector
|
||||
which has same direction but with norm equals to 1."
|
||||
[v]
|
||||
(let [norm (->> (map q/sq v)
|
||||
(apply +)
|
||||
(q/sqrt))]
|
||||
(v-mult v (/ norm))))
|
||||
|
||||
(defn- rotate-ud
|
||||
"Rotates nav-3d configuration up-down."
|
||||
[nav-3d angle]
|
||||
(let [axis (cross-product (:straight nav-3d) (:up nav-3d))
|
||||
rotate #(rotate-by-axis-and-angle % axis angle)]
|
||||
(-> nav-3d
|
||||
(update-in [:straight] rotate)
|
||||
(update-in [:up] rotate))))
|
||||
|
||||
(defn- rotate
|
||||
"Mouse handler function which rotates nav-3d configuration.
|
||||
It uses mouse from event object and pixels-in-360 to calculate
|
||||
angles to rotate."
|
||||
[state event pixels-in-360]
|
||||
(assert-state-has-navigation state)
|
||||
(if (= 0 (:p-x event) (:p-y event))
|
||||
state
|
||||
(let [dx (- (:p-x event) (:x event))
|
||||
dy (- (:y event) (:p-y event))
|
||||
angle-lr (q/map-range dx 0 pixels-in-360 0 q/TWO-PI)
|
||||
angle-ud (q/map-range dy 0 pixels-in-360 0 q/TWO-PI)]
|
||||
(update-in state [:navigation-3d]
|
||||
#(-> %
|
||||
(rotate-lr angle-lr)
|
||||
(rotate-ud angle-ud))))))
|
||||
|
||||
(def ^:private space (keyword " "))
|
||||
|
||||
(defn- move
|
||||
"Keyboard handler function which moves nav-3d configuration.
|
||||
It uses keyboard key from event object to determing in which
|
||||
direction to move."
|
||||
[state event step-size]
|
||||
(assert-state-has-navigation state)
|
||||
(let [{:keys [up straight]} (:navigation-3d state)]
|
||||
(if-let [dir (condp = (:key event)
|
||||
:w straight
|
||||
:s (v-opposite straight)
|
||||
space (v-opposite up)
|
||||
:z up
|
||||
:d (cross-product straight up)
|
||||
:a (cross-product up straight)
|
||||
nil)]
|
||||
(update-in state [:navigation-3d :position]
|
||||
#(v-plus % (v-mult dir step-size)))
|
||||
state)))
|
||||
|
||||
(defn- setup-3d-nav
|
||||
"Custom 'setup' function which creates initial position
|
||||
configuration and puts it to the state map."
|
||||
[user-setup user-settings]
|
||||
(let [initial-state (-> user-settings
|
||||
(select-keys [:straight :up :position])
|
||||
(->> (merge (default-position)))
|
||||
(update-in [:straight] v-normalize)
|
||||
(update-in [:up] v-normalize))]
|
||||
(update-in (user-setup) [:navigation-3d]
|
||||
#(merge initial-state %))))
|
||||
|
||||
(defn navigation-3d
|
||||
"Enables navigation in 3D space. Similar to how it is done in
|
||||
shooters: WASD navigation, space is go up, z is go down,
|
||||
drag mouse to look around."
|
||||
[options]
|
||||
(let [; 3d-navigation related user settings
|
||||
user-settings (:navigation-3d options)
|
||||
pixels-in-360 (:pixels-in-360 user-settings 1000)
|
||||
step-size (:step-size user-settings 20)
|
||||
rotate-on (:rotate-on user-settings :mouse-dragged)
|
||||
|
||||
; user-provided handlers which will be overridden
|
||||
; by 3d-navigation
|
||||
draw (:draw options (fn [state]))
|
||||
key-pressed (:key-pressed options (fn [state _] state))
|
||||
rotate-on-fn (rotate-on options (fn [state _] state))
|
||||
setup (:setup options (fn [] {}))]
|
||||
(assoc options
|
||||
|
||||
:setup (partial setup-3d-nav setup user-settings)
|
||||
|
||||
:draw (fn [state]
|
||||
(assert-state-has-navigation state)
|
||||
(let [{[c-x c-y c-z] :straight
|
||||
[u-x u-y u-z] :up
|
||||
[p-x p-y p-z] :position} (:navigation-3d state)]
|
||||
(q/camera p-x p-y p-z (+ p-x c-x) (+ p-y c-y) (+ p-z c-z) u-x u-y u-z))
|
||||
(draw state))
|
||||
|
||||
:key-pressed (fn [state event]
|
||||
(key-pressed (move state event step-size) event))
|
||||
|
||||
rotate-on (fn [state event]
|
||||
(rotate-on-fn (rotate state event pixels-in-360) event)) )))
|
File diff suppressed because one or more lines are too long
261
assets/viz/2/quil/middlewares/navigation_3d.js
Normal file
261
assets/viz/2/quil/middlewares/navigation_3d.js
Normal file
@ -0,0 +1,261 @@
|
||||
// Compiled by ClojureScript 1.9.473 {}
|
||||
goog.provide('quil.middlewares.navigation_3d');
|
||||
goog.require('cljs.core');
|
||||
goog.require('quil.core');
|
||||
quil.middlewares.navigation_3d.missing_navigation_key_error = [cljs.core.str.cljs$core$IFn$_invoke$arity$1("state map is missing :navigation-3d key. "),cljs.core.str.cljs$core$IFn$_invoke$arity$1("Did you accidentally removed it from the state in "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(":update or any other handler?")].join('');
|
||||
/**
|
||||
* Asserts that state map contains :navigation-2d object.
|
||||
*/
|
||||
quil.middlewares.navigation_3d.assert_state_has_navigation = (function quil$middlewares$navigation_3d$assert_state_has_navigation(state){
|
||||
if(cljs.core.truth_(new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301).cljs$core$IFn$_invoke$arity$1(state))){
|
||||
return null;
|
||||
} else {
|
||||
throw (new Error(quil.middlewares.navigation_3d.missing_navigation_key_error));
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Default position configuration. Check default configuration in
|
||||
* 'camera' function.
|
||||
*/
|
||||
quil.middlewares.navigation_3d.default_position = (function quil$middlewares$navigation_3d$default_position(){
|
||||
return new cljs.core.PersistentArrayMap(null, 3, [new cljs.core.Keyword(null,"position","position",-2011731912),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [(quil.core.width.call(null) / 2.0),(quil.core.height.call(null) / 2.0),((quil.core.height.call(null) / 2.0) / quil.core.tan.call(null,((quil.core.PI * 60.0) / 360.0)))], null),new cljs.core.Keyword(null,"straight","straight",-1252567854),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(0),(-1)], null),new cljs.core.Keyword(null,"up","up",-269712113),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(1),(0)], null)], null);
|
||||
});
|
||||
/**
|
||||
* Rotates vector v by angle with axis.
|
||||
* Formula is taken from wiki:
|
||||
* http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle
|
||||
*/
|
||||
quil.middlewares.navigation_3d.rotate_by_axis_and_angle = (function quil$middlewares$navigation_3d$rotate_by_axis_and_angle(v,axis,angle){
|
||||
var vec__8901 = axis;
|
||||
var a_x = cljs.core.nth.call(null,vec__8901,(0),null);
|
||||
var a_y = cljs.core.nth.call(null,vec__8901,(1),null);
|
||||
var a_z = cljs.core.nth.call(null,vec__8901,(2),null);
|
||||
var vec__8904 = v;
|
||||
var x = cljs.core.nth.call(null,vec__8904,(0),null);
|
||||
var y = cljs.core.nth.call(null,vec__8904,(1),null);
|
||||
var z = cljs.core.nth.call(null,vec__8904,(2),null);
|
||||
var cs = quil.core.cos.call(null,angle);
|
||||
var _cs = ((1) - cs);
|
||||
var sn = quil.core.sin.call(null,angle);
|
||||
var a = (cs + ((a_x * a_x) * _cs));
|
||||
var b = (((a_x * a_y) * _cs) - (a_z * sn));
|
||||
var c = (((a_x * a_z) * _cs) + (a_y * sn));
|
||||
var d = (((a_x * a_y) * _cs) + (a_z * sn));
|
||||
var e = (cs + ((a_y * a_y) * _cs));
|
||||
var f = (((a_y * a_z) * _cs) - (a_x * sn));
|
||||
var g = (((a_x * a_z) * _cs) - (a_y * sn));
|
||||
var h = (((a_y * a_z) * _cs) + (a_x * sn));
|
||||
var i = (cs + ((a_z * a_z) * _cs));
|
||||
return new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [(((a * x) + (b * y)) + (c * z)),(((d * x) + (e * y)) + (f * z)),(((g * x) + (h * y)) + (i * z))], null);
|
||||
});
|
||||
/**
|
||||
* Rotates nav-3d configuration left-right. angle positive - rotate right,
|
||||
* negative - left.
|
||||
*/
|
||||
quil.middlewares.navigation_3d.rotate_lr = (function quil$middlewares$navigation_3d$rotate_lr(nav_3d,angle){
|
||||
return cljs.core.update_in.call(null,nav_3d,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"straight","straight",-1252567854)], null),quil.middlewares.navigation_3d.rotate_by_axis_and_angle,new cljs.core.Keyword(null,"up","up",-269712113).cljs$core$IFn$_invoke$arity$1(nav_3d),angle);
|
||||
});
|
||||
/**
|
||||
* Vector cross-product: http://en.wikipedia.org/wiki/Cross_product
|
||||
*/
|
||||
quil.middlewares.navigation_3d.cross_product = (function quil$middlewares$navigation_3d$cross_product(p__8907,p__8908){
|
||||
var vec__8915 = p__8907;
|
||||
var u1 = cljs.core.nth.call(null,vec__8915,(0),null);
|
||||
var u2 = cljs.core.nth.call(null,vec__8915,(1),null);
|
||||
var u3 = cljs.core.nth.call(null,vec__8915,(2),null);
|
||||
var vec__8918 = p__8908;
|
||||
var v1 = cljs.core.nth.call(null,vec__8918,(0),null);
|
||||
var v2 = cljs.core.nth.call(null,vec__8918,(1),null);
|
||||
var v3 = cljs.core.nth.call(null,vec__8918,(2),null);
|
||||
return new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [((u2 * v3) - (u3 * v2)),((u3 * v1) - (u1 * v3)),((u1 * v2) - (u2 * v1))], null);
|
||||
});
|
||||
/**
|
||||
* Multiply vector v by scalar mult.
|
||||
*/
|
||||
quil.middlewares.navigation_3d.v_mult = (function quil$middlewares$navigation_3d$v_mult(v,mult){
|
||||
return cljs.core.mapv.call(null,(function (p1__8921_SHARP_){
|
||||
return (p1__8921_SHARP_ * mult);
|
||||
}),v);
|
||||
});
|
||||
/**
|
||||
* Sum of 2 vectors.
|
||||
*/
|
||||
quil.middlewares.navigation_3d.v_plus = (function quil$middlewares$navigation_3d$v_plus(v1,v2){
|
||||
return cljs.core.mapv.call(null,cljs.core._PLUS_,v1,v2);
|
||||
});
|
||||
/**
|
||||
* Returns vector opposite to vector v.
|
||||
*/
|
||||
quil.middlewares.navigation_3d.v_opposite = (function quil$middlewares$navigation_3d$v_opposite(v){
|
||||
return quil.middlewares.navigation_3d.v_mult.call(null,v,(-1));
|
||||
});
|
||||
/**
|
||||
* Normalize vector, returning vector
|
||||
* which has same direction but with norm equals to 1.
|
||||
*/
|
||||
quil.middlewares.navigation_3d.v_normalize = (function quil$middlewares$navigation_3d$v_normalize(v){
|
||||
var norm = quil.core.sqrt.call(null,cljs.core.apply.call(null,cljs.core._PLUS_,cljs.core.map.call(null,quil.core.sq,v)));
|
||||
return quil.middlewares.navigation_3d.v_mult.call(null,v,((1) / norm));
|
||||
});
|
||||
/**
|
||||
* Rotates nav-3d configuration up-down.
|
||||
*/
|
||||
quil.middlewares.navigation_3d.rotate_ud = (function quil$middlewares$navigation_3d$rotate_ud(nav_3d,angle){
|
||||
var axis = quil.middlewares.navigation_3d.cross_product.call(null,new cljs.core.Keyword(null,"straight","straight",-1252567854).cljs$core$IFn$_invoke$arity$1(nav_3d),new cljs.core.Keyword(null,"up","up",-269712113).cljs$core$IFn$_invoke$arity$1(nav_3d));
|
||||
var rotate = ((function (axis){
|
||||
return (function (p1__8922_SHARP_){
|
||||
return quil.middlewares.navigation_3d.rotate_by_axis_and_angle.call(null,p1__8922_SHARP_,axis,angle);
|
||||
});})(axis))
|
||||
;
|
||||
return cljs.core.update_in.call(null,cljs.core.update_in.call(null,nav_3d,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"straight","straight",-1252567854)], null),rotate),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"up","up",-269712113)], null),rotate);
|
||||
});
|
||||
/**
|
||||
* Mouse handler function which rotates nav-3d configuration.
|
||||
* It uses mouse from event object and pixels-in-360 to calculate
|
||||
* angles to rotate.
|
||||
*/
|
||||
quil.middlewares.navigation_3d.rotate = (function quil$middlewares$navigation_3d$rotate(state,event,pixels_in_360){
|
||||
quil.middlewares.navigation_3d.assert_state_has_navigation.call(null,state);
|
||||
|
||||
if(cljs.core._EQ_.call(null,(0),new cljs.core.Keyword(null,"p-x","p-x",-1721211211).cljs$core$IFn$_invoke$arity$1(event),new cljs.core.Keyword(null,"p-y","p-y",-530704830).cljs$core$IFn$_invoke$arity$1(event))){
|
||||
return state;
|
||||
} else {
|
||||
var dx = (new cljs.core.Keyword(null,"p-x","p-x",-1721211211).cljs$core$IFn$_invoke$arity$1(event) - new cljs.core.Keyword(null,"x","x",2099068185).cljs$core$IFn$_invoke$arity$1(event));
|
||||
var dy = (new cljs.core.Keyword(null,"y","y",-1757859776).cljs$core$IFn$_invoke$arity$1(event) - new cljs.core.Keyword(null,"p-y","p-y",-530704830).cljs$core$IFn$_invoke$arity$1(event));
|
||||
var angle_lr = quil.core.map_range.call(null,dx,(0),pixels_in_360,(0),quil.core.TWO_PI);
|
||||
var angle_ud = quil.core.map_range.call(null,dy,(0),pixels_in_360,(0),quil.core.TWO_PI);
|
||||
return cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301)], null),((function (dx,dy,angle_lr,angle_ud){
|
||||
return (function (p1__8923_SHARP_){
|
||||
return quil.middlewares.navigation_3d.rotate_ud.call(null,quil.middlewares.navigation_3d.rotate_lr.call(null,p1__8923_SHARP_,angle_lr),angle_ud);
|
||||
});})(dx,dy,angle_lr,angle_ud))
|
||||
);
|
||||
}
|
||||
});
|
||||
quil.middlewares.navigation_3d.space = cljs.core.keyword.call(null," ");
|
||||
/**
|
||||
* Keyboard handler function which moves nav-3d configuration.
|
||||
* It uses keyboard key from event object to determing in which
|
||||
* direction to move.
|
||||
*/
|
||||
quil.middlewares.navigation_3d.move = (function quil$middlewares$navigation_3d$move(state,event,step_size){
|
||||
quil.middlewares.navigation_3d.assert_state_has_navigation.call(null,state);
|
||||
|
||||
var map__8930 = new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301).cljs$core$IFn$_invoke$arity$1(state);
|
||||
var map__8930__$1 = ((((!((map__8930 == null)))?((((map__8930.cljs$lang$protocol_mask$partition0$ & (64))) || ((cljs.core.PROTOCOL_SENTINEL === map__8930.cljs$core$ISeq$)))?true:false):false))?cljs.core.apply.call(null,cljs.core.hash_map,map__8930):map__8930);
|
||||
var up = cljs.core.get.call(null,map__8930__$1,new cljs.core.Keyword(null,"up","up",-269712113));
|
||||
var straight = cljs.core.get.call(null,map__8930__$1,new cljs.core.Keyword(null,"straight","straight",-1252567854));
|
||||
var temp__4655__auto__ = (function (){var pred__8932 = cljs.core._EQ_;
|
||||
var expr__8933 = new cljs.core.Keyword(null,"key","key",-1516042587).cljs$core$IFn$_invoke$arity$1(event);
|
||||
if(cljs.core.truth_(pred__8932.call(null,new cljs.core.Keyword(null,"w","w",354169001),expr__8933))){
|
||||
return straight;
|
||||
} else {
|
||||
if(cljs.core.truth_(pred__8932.call(null,new cljs.core.Keyword(null,"s","s",1705939918),expr__8933))){
|
||||
return quil.middlewares.navigation_3d.v_opposite.call(null,straight);
|
||||
} else {
|
||||
if(cljs.core.truth_(pred__8932.call(null,quil.middlewares.navigation_3d.space,expr__8933))){
|
||||
return quil.middlewares.navigation_3d.v_opposite.call(null,up);
|
||||
} else {
|
||||
if(cljs.core.truth_(pred__8932.call(null,new cljs.core.Keyword(null,"z","z",-789527183),expr__8933))){
|
||||
return up;
|
||||
} else {
|
||||
if(cljs.core.truth_(pred__8932.call(null,new cljs.core.Keyword(null,"d","d",1972142424),expr__8933))){
|
||||
return quil.middlewares.navigation_3d.cross_product.call(null,straight,up);
|
||||
} else {
|
||||
if(cljs.core.truth_(pred__8932.call(null,new cljs.core.Keyword(null,"a","a",-2123407586),expr__8933))){
|
||||
return quil.middlewares.navigation_3d.cross_product.call(null,up,straight);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
if(cljs.core.truth_(temp__4655__auto__)){
|
||||
var dir = temp__4655__auto__;
|
||||
return cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301),new cljs.core.Keyword(null,"position","position",-2011731912)], null),((function (dir,temp__4655__auto__,map__8930,map__8930__$1,up,straight){
|
||||
return (function (p1__8924_SHARP_){
|
||||
return quil.middlewares.navigation_3d.v_plus.call(null,p1__8924_SHARP_,quil.middlewares.navigation_3d.v_mult.call(null,dir,step_size));
|
||||
});})(dir,temp__4655__auto__,map__8930,map__8930__$1,up,straight))
|
||||
);
|
||||
} else {
|
||||
return state;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Custom 'setup' function which creates initial position
|
||||
* configuration and puts it to the state map.
|
||||
*/
|
||||
quil.middlewares.navigation_3d.setup_3d_nav = (function quil$middlewares$navigation_3d$setup_3d_nav(user_setup,user_settings){
|
||||
var initial_state = cljs.core.update_in.call(null,cljs.core.update_in.call(null,cljs.core.merge.call(null,quil.middlewares.navigation_3d.default_position.call(null),cljs.core.select_keys.call(null,user_settings,new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"straight","straight",-1252567854),new cljs.core.Keyword(null,"up","up",-269712113),new cljs.core.Keyword(null,"position","position",-2011731912)], null))),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"straight","straight",-1252567854)], null),quil.middlewares.navigation_3d.v_normalize),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"up","up",-269712113)], null),quil.middlewares.navigation_3d.v_normalize);
|
||||
return cljs.core.update_in.call(null,user_setup.call(null),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301)], null),((function (initial_state){
|
||||
return (function (p1__8935_SHARP_){
|
||||
return cljs.core.merge.call(null,initial_state,p1__8935_SHARP_);
|
||||
});})(initial_state))
|
||||
);
|
||||
});
|
||||
/**
|
||||
* Enables navigation in 3D space. Similar to how it is done in
|
||||
* shooters: WASD navigation, space is go up, z is go down,
|
||||
* drag mouse to look around.
|
||||
*/
|
||||
quil.middlewares.navigation_3d.navigation_3d = (function quil$middlewares$navigation_3d$navigation_3d(options){
|
||||
var user_settings = new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301).cljs$core$IFn$_invoke$arity$1(options);
|
||||
var pixels_in_360 = new cljs.core.Keyword(null,"pixels-in-360","pixels-in-360",1789567298).cljs$core$IFn$_invoke$arity$2(user_settings,(1000));
|
||||
var step_size = new cljs.core.Keyword(null,"step-size","step-size",1545609922).cljs$core$IFn$_invoke$arity$2(user_settings,(20));
|
||||
var rotate_on = new cljs.core.Keyword(null,"rotate-on","rotate-on",-1282225937).cljs$core$IFn$_invoke$arity$2(user_settings,new cljs.core.Keyword(null,"mouse-dragged","mouse-dragged",-1220073441));
|
||||
var draw = new cljs.core.Keyword(null,"draw","draw",1358331674).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings,pixels_in_360,step_size,rotate_on){
|
||||
return (function (state){
|
||||
return null;
|
||||
});})(user_settings,pixels_in_360,step_size,rotate_on))
|
||||
);
|
||||
var key_pressed = new cljs.core.Keyword(null,"key-pressed","key-pressed",-757100364).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings,pixels_in_360,step_size,rotate_on,draw){
|
||||
return (function (state,_){
|
||||
return state;
|
||||
});})(user_settings,pixels_in_360,step_size,rotate_on,draw))
|
||||
);
|
||||
var rotate_on_fn = rotate_on.call(null,options,((function (user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed){
|
||||
return (function (state,_){
|
||||
return state;
|
||||
});})(user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed))
|
||||
);
|
||||
var setup = new cljs.core.Keyword(null,"setup","setup",1987730512).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn){
|
||||
return (function (){
|
||||
return cljs.core.PersistentArrayMap.EMPTY;
|
||||
});})(user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn))
|
||||
);
|
||||
return cljs.core.assoc.call(null,options,new cljs.core.Keyword(null,"setup","setup",1987730512),cljs.core.partial.call(null,quil.middlewares.navigation_3d.setup_3d_nav,setup,user_settings),new cljs.core.Keyword(null,"draw","draw",1358331674),((function (user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn,setup){
|
||||
return (function (state){
|
||||
quil.middlewares.navigation_3d.assert_state_has_navigation.call(null,state);
|
||||
|
||||
var map__8947_8958 = new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301).cljs$core$IFn$_invoke$arity$1(state);
|
||||
var map__8947_8959__$1 = ((((!((map__8947_8958 == null)))?((((map__8947_8958.cljs$lang$protocol_mask$partition0$ & (64))) || ((cljs.core.PROTOCOL_SENTINEL === map__8947_8958.cljs$core$ISeq$)))?true:false):false))?cljs.core.apply.call(null,cljs.core.hash_map,map__8947_8958):map__8947_8958);
|
||||
var vec__8948_8960 = cljs.core.get.call(null,map__8947_8959__$1,new cljs.core.Keyword(null,"straight","straight",-1252567854));
|
||||
var c_x_8961 = cljs.core.nth.call(null,vec__8948_8960,(0),null);
|
||||
var c_y_8962 = cljs.core.nth.call(null,vec__8948_8960,(1),null);
|
||||
var c_z_8963 = cljs.core.nth.call(null,vec__8948_8960,(2),null);
|
||||
var vec__8951_8964 = cljs.core.get.call(null,map__8947_8959__$1,new cljs.core.Keyword(null,"up","up",-269712113));
|
||||
var u_x_8965 = cljs.core.nth.call(null,vec__8951_8964,(0),null);
|
||||
var u_y_8966 = cljs.core.nth.call(null,vec__8951_8964,(1),null);
|
||||
var u_z_8967 = cljs.core.nth.call(null,vec__8951_8964,(2),null);
|
||||
var vec__8954_8968 = cljs.core.get.call(null,map__8947_8959__$1,new cljs.core.Keyword(null,"position","position",-2011731912));
|
||||
var p_x_8969 = cljs.core.nth.call(null,vec__8954_8968,(0),null);
|
||||
var p_y_8970 = cljs.core.nth.call(null,vec__8954_8968,(1),null);
|
||||
var p_z_8971 = cljs.core.nth.call(null,vec__8954_8968,(2),null);
|
||||
quil.core.camera.call(null,p_x_8969,p_y_8970,p_z_8971,(p_x_8969 + c_x_8961),(p_y_8970 + c_y_8962),(p_z_8971 + c_z_8963),u_x_8965,u_y_8966,u_z_8967);
|
||||
|
||||
return draw.call(null,state);
|
||||
});})(user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn,setup))
|
||||
,new cljs.core.Keyword(null,"key-pressed","key-pressed",-757100364),((function (user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn,setup){
|
||||
return (function (state,event){
|
||||
return key_pressed.call(null,quil.middlewares.navigation_3d.move.call(null,state,event,step_size),event);
|
||||
});})(user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn,setup))
|
||||
,rotate_on,((function (user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn,setup){
|
||||
return (function (state,event){
|
||||
return rotate_on_fn.call(null,quil.middlewares.navigation_3d.rotate.call(null,state,event,pixels_in_360),event);
|
||||
});})(user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn,setup))
|
||||
);
|
||||
});
|
||||
|
||||
//# sourceMappingURL=navigation_3d.js.map
|
1
assets/viz/2/quil/middlewares/navigation_3d.js.map
Normal file
1
assets/viz/2/quil/middlewares/navigation_3d.js.map
Normal file
File diff suppressed because one or more lines are too long
128
assets/viz/2/quil/sketch.cljs
Normal file
128
assets/viz/2/quil/sketch.cljs
Normal file
@ -0,0 +1,128 @@
|
||||
(ns quil.sketch
|
||||
(:require [quil.util :as u :include-macros true]
|
||||
[quil.middlewares.deprecated-options :as do]
|
||||
[goog.dom :as dom]
|
||||
[goog.events :as events]
|
||||
[goog.events.EventType :as EventType])
|
||||
(:require-macros [quil.sketch]))
|
||||
|
||||
(def ^:dynamic
|
||||
*applet* nil)
|
||||
|
||||
(defn current-applet [] *applet*)
|
||||
|
||||
(u/generate-quil-constants :cljs
|
||||
rendering-modes (:java2d :p2d :p3d :opengl))
|
||||
|
||||
(defn resolve-renderer [mode]
|
||||
(u/resolve-constant-key mode rendering-modes))
|
||||
|
||||
(defn size
|
||||
([width height]
|
||||
(.size (current-applet) (int width) (int height)))
|
||||
|
||||
([width height mode]
|
||||
(.size (current-applet) (int width) (int height) (u/resolve-constant-key mode rendering-modes))))
|
||||
|
||||
(defn- bind-handlers [prc opts]
|
||||
(doseq [[processing-name quil-name] {:setup :setup
|
||||
:draw :draw
|
||||
|
||||
:keyPressed :key-pressed
|
||||
:keyReleased :key-released
|
||||
:keyTyped :key-typed
|
||||
|
||||
:mouseClicked :mouse-clicked
|
||||
:mouseDragged :mouse-dragged
|
||||
:mouseMoved :mouse-moved
|
||||
:mousePressed :mouse-pressed
|
||||
:mouseReleased :mouse-released
|
||||
:mouseOut :mouse-exited
|
||||
:mouseOver :mouse-entered
|
||||
:mouseScrolled :mouse-wheel}]
|
||||
(when-let [handler (opts quil-name)]
|
||||
(aset prc (name processing-name)
|
||||
(fn []
|
||||
(quil.sketch/with-sketch prc
|
||||
(handler)))))))
|
||||
|
||||
(defn make-sketch [options]
|
||||
(let [opts (->> (:middleware options [])
|
||||
(cons do/deprecated-options)
|
||||
(apply comp)
|
||||
(#(% options))
|
||||
(merge {:size [500 300]}))
|
||||
|
||||
sketch-size (or (:size opts) [200 200])
|
||||
renderer (:renderer opts)
|
||||
features (set (:features opts))
|
||||
|
||||
setup (fn []
|
||||
(->> (if renderer [renderer] [])
|
||||
(concat sketch-size)
|
||||
(apply size))
|
||||
(when (:settings opts) ((:settings opts)))
|
||||
(when (:setup opts) ((:setup opts))))
|
||||
mouse-wheel (when (:mouse-wheel opts)
|
||||
;; -1 need for compability with Clojure version
|
||||
#((:mouse-wheel opts) (* -1 (.-mouseScroll *applet*))))
|
||||
|
||||
opts (assoc opts
|
||||
:setup setup
|
||||
:mouse-wheel mouse-wheel)
|
||||
attach-function (fn [prc]
|
||||
(bind-handlers prc opts)
|
||||
(set! (.-quil prc) (atom nil))
|
||||
(set! (.-target-frame-rate prc) (atom 60)))
|
||||
sketch (js/Processing.Sketch. attach-function)]
|
||||
(when (contains? features :global-key-events)
|
||||
(aset (aget sketch "options") "globalKeyEvents" true))
|
||||
sketch))
|
||||
|
||||
(defn destroy-previous-sketch [host-elem]
|
||||
(when-let [proc-obj (.-processing-obj host-elem)]
|
||||
(.exit proc-obj)))
|
||||
|
||||
(defn sketch [& opts]
|
||||
(let [opts-map (apply hash-map opts)
|
||||
host-elem (dom/getElement (:host opts-map))
|
||||
renderer (or (:renderer opts-map) :p2d)]
|
||||
(if host-elem
|
||||
(do
|
||||
(if (.-processing-context host-elem)
|
||||
(when-not (= renderer (.-processing-context host-elem))
|
||||
(.warn js/console "WARNING: Using different context on one canvas!"))
|
||||
(set! (.-processing-context host-elem) renderer))
|
||||
(destroy-previous-sketch host-elem)
|
||||
(set! (.-processing-obj host-elem)
|
||||
(js/Processing. host-elem (make-sketch opts-map))))
|
||||
(.error js/console "ERROR: Cannot create sketch. :host is not specified."))))
|
||||
|
||||
(def sketch-init-list (atom (list )))
|
||||
|
||||
(defn empty-body? []
|
||||
(let [child (.-childNodes (.-body js/document))]
|
||||
; seems hacky, we should come up with better way of
|
||||
; checking whether body is empty or not
|
||||
(<= (.-length child) 1)))
|
||||
|
||||
(defn add-canvas [canvas-id]
|
||||
(let [canvas (.createElement js/document "canvas")]
|
||||
(.setAttribute canvas "id" canvas-id)
|
||||
(.appendChild (.-body js/document) canvas)))
|
||||
|
||||
(defn init-sketches []
|
||||
(let [add-elem? (empty-body?)]
|
||||
(doseq [sk @sketch-init-list]
|
||||
(when add-elem?
|
||||
(add-canvas (:host-id sk)))
|
||||
((:fn sk))))
|
||||
(reset! sketch-init-list []))
|
||||
|
||||
(defn add-sketch-to-init-list [sk]
|
||||
(swap! sketch-init-list conj sk)
|
||||
; if page already loaded immediately init sketch we just added
|
||||
(when (= (.-readyState js/document) "complete")
|
||||
(init-sketches)))
|
||||
|
||||
(events/listenOnce js/window EventType/LOAD init-sketches)
|
1
assets/viz/2/quil/sketch.cljs.cache.edn
Normal file
1
assets/viz/2/quil/sketch.cljs.cache.edn
Normal file
File diff suppressed because one or more lines are too long
348
assets/viz/2/quil/sketch.js
Normal file
348
assets/viz/2/quil/sketch.js
Normal file
@ -0,0 +1,348 @@
|
||||
// Compiled by ClojureScript 1.9.473 {}
|
||||
goog.provide('quil.sketch');
|
||||
goog.require('cljs.core');
|
||||
goog.require('quil.util');
|
||||
goog.require('quil.middlewares.deprecated_options');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
quil.sketch._STAR_applet_STAR_ = null;
|
||||
quil.sketch.current_applet = (function quil$sketch$current_applet(){
|
||||
return quil.sketch._STAR_applet_STAR_;
|
||||
});
|
||||
quil.sketch.rendering_modes = new cljs.core.PersistentArrayMap(null, 4, [new cljs.core.Keyword(null,"java2d","java2d",166099237),(Processing.prototype.PConstants["JAVA2D"]),new cljs.core.Keyword(null,"p2d","p2d",-2106175755),(Processing.prototype.PConstants["P2D"]),new cljs.core.Keyword(null,"p3d","p3d",-850380194),(Processing.prototype.PConstants["P3D"]),new cljs.core.Keyword(null,"opengl","opengl",-614998103),(Processing.prototype.PConstants["OPENGL"])], null);
|
||||
quil.sketch.resolve_renderer = (function quil$sketch$resolve_renderer(mode){
|
||||
return quil.util.resolve_constant_key.call(null,mode,quil.sketch.rendering_modes);
|
||||
});
|
||||
quil.sketch.size = (function quil$sketch$size(var_args){
|
||||
var args8190 = [];
|
||||
var len__7927__auto___8193 = arguments.length;
|
||||
var i__7928__auto___8194 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___8194 < len__7927__auto___8193)){
|
||||
args8190.push((arguments[i__7928__auto___8194]));
|
||||
|
||||
var G__8195 = (i__7928__auto___8194 + (1));
|
||||
i__7928__auto___8194 = G__8195;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var G__8192 = args8190.length;
|
||||
switch (G__8192) {
|
||||
case 2:
|
||||
return quil.sketch.size.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
|
||||
|
||||
break;
|
||||
case 3:
|
||||
return quil.sketch.size.cljs$core$IFn$_invoke$arity$3((arguments[(0)]),(arguments[(1)]),(arguments[(2)]));
|
||||
|
||||
break;
|
||||
default:
|
||||
throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid arity: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(args8190.length)].join('')));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
quil.sketch.size.cljs$core$IFn$_invoke$arity$2 = (function (width,height){
|
||||
return quil.sketch.current_applet.call(null).size((width | (0)),(height | (0)));
|
||||
});
|
||||
|
||||
quil.sketch.size.cljs$core$IFn$_invoke$arity$3 = (function (width,height,mode){
|
||||
return quil.sketch.current_applet.call(null).size((width | (0)),(height | (0)),quil.util.resolve_constant_key.call(null,mode,quil.sketch.rendering_modes));
|
||||
});
|
||||
|
||||
quil.sketch.size.cljs$lang$maxFixedArity = 3;
|
||||
|
||||
quil.sketch.bind_handlers = (function quil$sketch$bind_handlers(prc,opts){
|
||||
var seq__8209 = cljs.core.seq.call(null,cljs.core.PersistentHashMap.fromArrays([new cljs.core.Keyword(null,"keyPressed","keyPressed",1791025256),new cljs.core.Keyword(null,"mouseOut","mouseOut",-386669045),new cljs.core.Keyword(null,"mouseScrolled","mouseScrolled",31878252),new cljs.core.Keyword(null,"mouseDragged","mouseDragged",129975181),new cljs.core.Keyword(null,"setup","setup",1987730512),new cljs.core.Keyword(null,"keyReleased","keyReleased",541714964),new cljs.core.Keyword(null,"mouseClicked","mouseClicked",1764302965),new cljs.core.Keyword(null,"mouseReleased","mouseReleased",1116234838),new cljs.core.Keyword(null,"mousePressed","mousePressed",1776186454),new cljs.core.Keyword(null,"mouseMoved","mouseMoved",-1936954058),new cljs.core.Keyword(null,"mouseOver","mouseOver",-1334461930),new cljs.core.Keyword(null,"keyTyped","keyTyped",1437329399),new cljs.core.Keyword(null,"draw","draw",1358331674)],[new cljs.core.Keyword(null,"key-pressed","key-pressed",-757100364),new cljs.core.Keyword(null,"mouse-exited","mouse-exited",-483205244),new cljs.core.Keyword(null,"mouse-wheel","mouse-wheel",1811662439),new cljs.core.Keyword(null,"mouse-dragged","mouse-dragged",-1220073441),new cljs.core.Keyword(null,"setup","setup",1987730512),new cljs.core.Keyword(null,"key-released","key-released",215919828),new cljs.core.Keyword(null,"mouse-clicked","mouse-clicked",-199339421),new cljs.core.Keyword(null,"mouse-released","mouse-released",-664480061),new cljs.core.Keyword(null,"mouse-pressed","mouse-pressed",736955536),new cljs.core.Keyword(null,"mouse-moved","mouse-moved",-1918152310),new cljs.core.Keyword(null,"mouse-entered","mouse-entered",811350322),new cljs.core.Keyword(null,"key-typed","key-typed",-876037597),new cljs.core.Keyword(null,"draw","draw",1358331674)]));
|
||||
var chunk__8210 = null;
|
||||
var count__8211 = (0);
|
||||
var i__8212 = (0);
|
||||
while(true){
|
||||
if((i__8212 < count__8211)){
|
||||
var vec__8213 = cljs.core._nth.call(null,chunk__8210,i__8212);
|
||||
var processing_name = cljs.core.nth.call(null,vec__8213,(0),null);
|
||||
var quil_name = cljs.core.nth.call(null,vec__8213,(1),null);
|
||||
var temp__4657__auto___8221 = opts.call(null,quil_name);
|
||||
if(cljs.core.truth_(temp__4657__auto___8221)){
|
||||
var handler_8222 = temp__4657__auto___8221;
|
||||
(prc[cljs.core.name.call(null,processing_name)] = ((function (seq__8209,chunk__8210,count__8211,i__8212,handler_8222,temp__4657__auto___8221,vec__8213,processing_name,quil_name){
|
||||
return (function (){
|
||||
var _STAR_applet_STAR_8216 = quil.sketch._STAR_applet_STAR_;
|
||||
quil.sketch._STAR_applet_STAR_ = prc;
|
||||
|
||||
try{return handler_8222.call(null);
|
||||
}finally {quil.sketch._STAR_applet_STAR_ = _STAR_applet_STAR_8216;
|
||||
}});})(seq__8209,chunk__8210,count__8211,i__8212,handler_8222,temp__4657__auto___8221,vec__8213,processing_name,quil_name))
|
||||
);
|
||||
} else {
|
||||
}
|
||||
|
||||
var G__8223 = seq__8209;
|
||||
var G__8224 = chunk__8210;
|
||||
var G__8225 = count__8211;
|
||||
var G__8226 = (i__8212 + (1));
|
||||
seq__8209 = G__8223;
|
||||
chunk__8210 = G__8224;
|
||||
count__8211 = G__8225;
|
||||
i__8212 = G__8226;
|
||||
continue;
|
||||
} else {
|
||||
var temp__4657__auto__ = cljs.core.seq.call(null,seq__8209);
|
||||
if(temp__4657__auto__){
|
||||
var seq__8209__$1 = temp__4657__auto__;
|
||||
if(cljs.core.chunked_seq_QMARK_.call(null,seq__8209__$1)){
|
||||
var c__7633__auto__ = cljs.core.chunk_first.call(null,seq__8209__$1);
|
||||
var G__8227 = cljs.core.chunk_rest.call(null,seq__8209__$1);
|
||||
var G__8228 = c__7633__auto__;
|
||||
var G__8229 = cljs.core.count.call(null,c__7633__auto__);
|
||||
var G__8230 = (0);
|
||||
seq__8209 = G__8227;
|
||||
chunk__8210 = G__8228;
|
||||
count__8211 = G__8229;
|
||||
i__8212 = G__8230;
|
||||
continue;
|
||||
} else {
|
||||
var vec__8217 = cljs.core.first.call(null,seq__8209__$1);
|
||||
var processing_name = cljs.core.nth.call(null,vec__8217,(0),null);
|
||||
var quil_name = cljs.core.nth.call(null,vec__8217,(1),null);
|
||||
var temp__4657__auto___8231__$1 = opts.call(null,quil_name);
|
||||
if(cljs.core.truth_(temp__4657__auto___8231__$1)){
|
||||
var handler_8232 = temp__4657__auto___8231__$1;
|
||||
(prc[cljs.core.name.call(null,processing_name)] = ((function (seq__8209,chunk__8210,count__8211,i__8212,handler_8232,temp__4657__auto___8231__$1,vec__8217,processing_name,quil_name,seq__8209__$1,temp__4657__auto__){
|
||||
return (function (){
|
||||
var _STAR_applet_STAR_8220 = quil.sketch._STAR_applet_STAR_;
|
||||
quil.sketch._STAR_applet_STAR_ = prc;
|
||||
|
||||
try{return handler_8232.call(null);
|
||||
}finally {quil.sketch._STAR_applet_STAR_ = _STAR_applet_STAR_8220;
|
||||
}});})(seq__8209,chunk__8210,count__8211,i__8212,handler_8232,temp__4657__auto___8231__$1,vec__8217,processing_name,quil_name,seq__8209__$1,temp__4657__auto__))
|
||||
);
|
||||
} else {
|
||||
}
|
||||
|
||||
var G__8233 = cljs.core.next.call(null,seq__8209__$1);
|
||||
var G__8234 = null;
|
||||
var G__8235 = (0);
|
||||
var G__8236 = (0);
|
||||
seq__8209 = G__8233;
|
||||
chunk__8210 = G__8234;
|
||||
count__8211 = G__8235;
|
||||
i__8212 = G__8236;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
quil.sketch.make_sketch = (function quil$sketch$make_sketch(options){
|
||||
var opts = cljs.core.merge.call(null,new cljs.core.PersistentArrayMap(null, 1, [new cljs.core.Keyword(null,"size","size",1098693007),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(500),(300)], null)], null),(function (p1__8237_SHARP_){
|
||||
return p1__8237_SHARP_.call(null,options);
|
||||
}).call(null,cljs.core.apply.call(null,cljs.core.comp,cljs.core.cons.call(null,quil.middlewares.deprecated_options.deprecated_options,new cljs.core.Keyword(null,"middleware","middleware",1462115504).cljs$core$IFn$_invoke$arity$2(options,cljs.core.PersistentVector.EMPTY)))));
|
||||
var sketch_size = (function (){var or__6814__auto__ = new cljs.core.Keyword(null,"size","size",1098693007).cljs$core$IFn$_invoke$arity$1(opts);
|
||||
if(cljs.core.truth_(or__6814__auto__)){
|
||||
return or__6814__auto__;
|
||||
} else {
|
||||
return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(200),(200)], null);
|
||||
}
|
||||
})();
|
||||
var renderer = new cljs.core.Keyword(null,"renderer","renderer",336841071).cljs$core$IFn$_invoke$arity$1(opts);
|
||||
var features = cljs.core.set.call(null,new cljs.core.Keyword(null,"features","features",-1146962336).cljs$core$IFn$_invoke$arity$1(opts));
|
||||
var setup = ((function (opts,sketch_size,renderer,features){
|
||||
return (function (){
|
||||
cljs.core.apply.call(null,quil.sketch.size,cljs.core.concat.call(null,sketch_size,(cljs.core.truth_(renderer)?new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [renderer], null):cljs.core.PersistentVector.EMPTY)));
|
||||
|
||||
if(cljs.core.truth_(new cljs.core.Keyword(null,"settings","settings",1556144875).cljs$core$IFn$_invoke$arity$1(opts))){
|
||||
new cljs.core.Keyword(null,"settings","settings",1556144875).cljs$core$IFn$_invoke$arity$1(opts).call(null);
|
||||
} else {
|
||||
}
|
||||
|
||||
if(cljs.core.truth_(new cljs.core.Keyword(null,"setup","setup",1987730512).cljs$core$IFn$_invoke$arity$1(opts))){
|
||||
return new cljs.core.Keyword(null,"setup","setup",1987730512).cljs$core$IFn$_invoke$arity$1(opts).call(null);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});})(opts,sketch_size,renderer,features))
|
||||
;
|
||||
var mouse_wheel = (cljs.core.truth_(new cljs.core.Keyword(null,"mouse-wheel","mouse-wheel",1811662439).cljs$core$IFn$_invoke$arity$1(opts))?((function (opts,sketch_size,renderer,features,setup){
|
||||
return (function (){
|
||||
return new cljs.core.Keyword(null,"mouse-wheel","mouse-wheel",1811662439).cljs$core$IFn$_invoke$arity$1(opts).call(null,((-1) * quil.sketch._STAR_applet_STAR_.mouseScroll));
|
||||
});})(opts,sketch_size,renderer,features,setup))
|
||||
:null);
|
||||
var opts__$1 = cljs.core.assoc.call(null,opts,new cljs.core.Keyword(null,"setup","setup",1987730512),setup,new cljs.core.Keyword(null,"mouse-wheel","mouse-wheel",1811662439),mouse_wheel);
|
||||
var attach_function = ((function (opts,sketch_size,renderer,features,setup,mouse_wheel,opts__$1){
|
||||
return (function (prc){
|
||||
quil.sketch.bind_handlers.call(null,prc,opts__$1);
|
||||
|
||||
prc.quil = cljs.core.atom.call(null,null);
|
||||
|
||||
return prc.target_frame_rate = cljs.core.atom.call(null,(60));
|
||||
});})(opts,sketch_size,renderer,features,setup,mouse_wheel,opts__$1))
|
||||
;
|
||||
var sketch = (new Processing.Sketch(attach_function));
|
||||
if(cljs.core.contains_QMARK_.call(null,features,new cljs.core.Keyword(null,"global-key-events","global-key-events",335064944))){
|
||||
((sketch["options"])["globalKeyEvents"] = true);
|
||||
} else {
|
||||
}
|
||||
|
||||
return sketch;
|
||||
});
|
||||
quil.sketch.destroy_previous_sketch = (function quil$sketch$destroy_previous_sketch(host_elem){
|
||||
var temp__4657__auto__ = host_elem.processing_obj;
|
||||
if(cljs.core.truth_(temp__4657__auto__)){
|
||||
var proc_obj = temp__4657__auto__;
|
||||
return proc_obj.exit();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
quil.sketch.sketch = (function quil$sketch$sketch(var_args){
|
||||
var args__7934__auto__ = [];
|
||||
var len__7927__auto___8239 = arguments.length;
|
||||
var i__7928__auto___8240 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___8240 < len__7927__auto___8239)){
|
||||
args__7934__auto__.push((arguments[i__7928__auto___8240]));
|
||||
|
||||
var G__8241 = (i__7928__auto___8240 + (1));
|
||||
i__7928__auto___8240 = G__8241;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var argseq__7935__auto__ = ((((0) < args__7934__auto__.length))?(new cljs.core.IndexedSeq(args__7934__auto__.slice((0)),(0),null)):null);
|
||||
return quil.sketch.sketch.cljs$core$IFn$_invoke$arity$variadic(argseq__7935__auto__);
|
||||
});
|
||||
|
||||
quil.sketch.sketch.cljs$core$IFn$_invoke$arity$variadic = (function (opts){
|
||||
var opts_map = cljs.core.apply.call(null,cljs.core.hash_map,opts);
|
||||
var host_elem = goog.dom.getElement(new cljs.core.Keyword(null,"host","host",-1558485167).cljs$core$IFn$_invoke$arity$1(opts_map));
|
||||
var renderer = (function (){var or__6814__auto__ = new cljs.core.Keyword(null,"renderer","renderer",336841071).cljs$core$IFn$_invoke$arity$1(opts_map);
|
||||
if(cljs.core.truth_(or__6814__auto__)){
|
||||
return or__6814__auto__;
|
||||
} else {
|
||||
return new cljs.core.Keyword(null,"p2d","p2d",-2106175755);
|
||||
}
|
||||
})();
|
||||
if(cljs.core.truth_(host_elem)){
|
||||
if(cljs.core.truth_(host_elem.processing_context)){
|
||||
if(cljs.core._EQ_.call(null,renderer,host_elem.processing_context)){
|
||||
} else {
|
||||
console.warn("WARNING: Using different context on one canvas!");
|
||||
}
|
||||
} else {
|
||||
host_elem.processing_context = renderer;
|
||||
}
|
||||
|
||||
quil.sketch.destroy_previous_sketch.call(null,host_elem);
|
||||
|
||||
return host_elem.processing_obj = (new Processing(host_elem,quil.sketch.make_sketch.call(null,opts_map)));
|
||||
} else {
|
||||
return console.error("ERROR: Cannot create sketch. :host is not specified.");
|
||||
}
|
||||
});
|
||||
|
||||
quil.sketch.sketch.cljs$lang$maxFixedArity = (0);
|
||||
|
||||
quil.sketch.sketch.cljs$lang$applyTo = (function (seq8238){
|
||||
return quil.sketch.sketch.cljs$core$IFn$_invoke$arity$variadic(cljs.core.seq.call(null,seq8238));
|
||||
});
|
||||
|
||||
quil.sketch.sketch_init_list = cljs.core.atom.call(null,cljs.core.List.EMPTY);
|
||||
quil.sketch.empty_body_QMARK_ = (function quil$sketch$empty_body_QMARK_(){
|
||||
var child = document.body.childNodes;
|
||||
return (child.length <= (1));
|
||||
});
|
||||
quil.sketch.add_canvas = (function quil$sketch$add_canvas(canvas_id){
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.setAttribute("id",canvas_id);
|
||||
|
||||
return document.body.appendChild(canvas);
|
||||
});
|
||||
quil.sketch.init_sketches = (function quil$sketch$init_sketches(){
|
||||
var add_elem_QMARK__8250 = quil.sketch.empty_body_QMARK_.call(null);
|
||||
var seq__8246_8251 = cljs.core.seq.call(null,cljs.core.deref.call(null,quil.sketch.sketch_init_list));
|
||||
var chunk__8247_8252 = null;
|
||||
var count__8248_8253 = (0);
|
||||
var i__8249_8254 = (0);
|
||||
while(true){
|
||||
if((i__8249_8254 < count__8248_8253)){
|
||||
var sk_8255 = cljs.core._nth.call(null,chunk__8247_8252,i__8249_8254);
|
||||
if(cljs.core.truth_(add_elem_QMARK__8250)){
|
||||
quil.sketch.add_canvas.call(null,new cljs.core.Keyword(null,"host-id","host-id",742376279).cljs$core$IFn$_invoke$arity$1(sk_8255));
|
||||
} else {
|
||||
}
|
||||
|
||||
new cljs.core.Keyword(null,"fn","fn",-1175266204).cljs$core$IFn$_invoke$arity$1(sk_8255).call(null);
|
||||
|
||||
var G__8256 = seq__8246_8251;
|
||||
var G__8257 = chunk__8247_8252;
|
||||
var G__8258 = count__8248_8253;
|
||||
var G__8259 = (i__8249_8254 + (1));
|
||||
seq__8246_8251 = G__8256;
|
||||
chunk__8247_8252 = G__8257;
|
||||
count__8248_8253 = G__8258;
|
||||
i__8249_8254 = G__8259;
|
||||
continue;
|
||||
} else {
|
||||
var temp__4657__auto___8260 = cljs.core.seq.call(null,seq__8246_8251);
|
||||
if(temp__4657__auto___8260){
|
||||
var seq__8246_8261__$1 = temp__4657__auto___8260;
|
||||
if(cljs.core.chunked_seq_QMARK_.call(null,seq__8246_8261__$1)){
|
||||
var c__7633__auto___8262 = cljs.core.chunk_first.call(null,seq__8246_8261__$1);
|
||||
var G__8263 = cljs.core.chunk_rest.call(null,seq__8246_8261__$1);
|
||||
var G__8264 = c__7633__auto___8262;
|
||||
var G__8265 = cljs.core.count.call(null,c__7633__auto___8262);
|
||||
var G__8266 = (0);
|
||||
seq__8246_8251 = G__8263;
|
||||
chunk__8247_8252 = G__8264;
|
||||
count__8248_8253 = G__8265;
|
||||
i__8249_8254 = G__8266;
|
||||
continue;
|
||||
} else {
|
||||
var sk_8267 = cljs.core.first.call(null,seq__8246_8261__$1);
|
||||
if(cljs.core.truth_(add_elem_QMARK__8250)){
|
||||
quil.sketch.add_canvas.call(null,new cljs.core.Keyword(null,"host-id","host-id",742376279).cljs$core$IFn$_invoke$arity$1(sk_8267));
|
||||
} else {
|
||||
}
|
||||
|
||||
new cljs.core.Keyword(null,"fn","fn",-1175266204).cljs$core$IFn$_invoke$arity$1(sk_8267).call(null);
|
||||
|
||||
var G__8268 = cljs.core.next.call(null,seq__8246_8261__$1);
|
||||
var G__8269 = null;
|
||||
var G__8270 = (0);
|
||||
var G__8271 = (0);
|
||||
seq__8246_8251 = G__8268;
|
||||
chunk__8247_8252 = G__8269;
|
||||
count__8248_8253 = G__8270;
|
||||
i__8249_8254 = G__8271;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return cljs.core.reset_BANG_.call(null,quil.sketch.sketch_init_list,cljs.core.PersistentVector.EMPTY);
|
||||
});
|
||||
quil.sketch.add_sketch_to_init_list = (function quil$sketch$add_sketch_to_init_list(sk){
|
||||
cljs.core.swap_BANG_.call(null,quil.sketch.sketch_init_list,cljs.core.conj,sk);
|
||||
|
||||
if(cljs.core._EQ_.call(null,document.readyState,"complete")){
|
||||
return quil.sketch.init_sketches.call(null);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
goog.events.listenOnce(window,goog.events.EventType.LOAD,quil.sketch.init_sketches);
|
||||
|
||||
//# sourceMappingURL=sketch.js.map
|
1
assets/viz/2/quil/sketch.js.map
Normal file
1
assets/viz/2/quil/sketch.js.map
Normal file
File diff suppressed because one or more lines are too long
109
assets/viz/2/quil/util.cljc
Normal file
109
assets/viz/2/quil/util.cljc
Normal file
@ -0,0 +1,109 @@
|
||||
(ns ^{:doc "Utility fns"}
|
||||
quil.util
|
||||
(:require [clojure.string :as cstr]))
|
||||
|
||||
(defn no-fn
|
||||
"Function that does nothing."
|
||||
[])
|
||||
|
||||
#?(:clj
|
||||
(defn callable? [value]
|
||||
(or (fn? value)
|
||||
(var? value))))
|
||||
|
||||
#?(:clj
|
||||
(defn absolute-path [path]
|
||||
(-> (str path)
|
||||
(java.io.File.)
|
||||
(.getAbsolutePath))))
|
||||
|
||||
#?(:clj
|
||||
(defn int-like?
|
||||
[val]
|
||||
(let [t (type val)]
|
||||
(or (= java.lang.Long t)
|
||||
(= java.lang.Integer t)))))
|
||||
|
||||
(defn resolve-constant-key
|
||||
"Returns the val associated with key in mappings or key directly if it
|
||||
is one of the vals in mappings. Otherwise throws an exception."
|
||||
[key mappings]
|
||||
(cond
|
||||
(get mappings key) (get mappings key)
|
||||
(some #{key} (vals mappings)) key
|
||||
|
||||
:else (throw (#?(:clj Exception.
|
||||
:cljs js/Error.)
|
||||
(str "Expecting a keyword, got: " key ". Expected one of: " (vec (sort (keys mappings))))))))
|
||||
|
||||
(defn- length-of-longest-key
|
||||
"Returns the length of the longest key of map m. Assumes m's keys are strings
|
||||
and returns 0 if map is empty:
|
||||
(length-of-longest-key {\"foo\" 1 \"barr\" 2 \"bazzz\" 3}) ;=> 5
|
||||
(length-of-longest-key {}) ;=> 0"
|
||||
[m]
|
||||
(or (last (sort (map #(.length %) (keys m))))
|
||||
0))
|
||||
|
||||
(defn- gen-padding
|
||||
"Generates a padding string starting concatting s with len times pad:
|
||||
(gen-padding \"\" 5 \"b\") ;=> \"bbbbb\"
|
||||
May be called without starting string s in which case it defaults to the
|
||||
empty string and also without pad in which case it defaults to a single space"
|
||||
([len] (gen-padding "" len " "))
|
||||
([len pad] (gen-padding "" len pad))
|
||||
([s len pad]
|
||||
(if (> len 0)
|
||||
(gen-padding (str s pad) (dec len) pad)
|
||||
s)))
|
||||
|
||||
(defn print-definition-list
|
||||
[definitions]
|
||||
(let [longest-key (length-of-longest-key definitions)]
|
||||
(dorun
|
||||
(map (fn [[k v]]
|
||||
(let [len (.length k)
|
||||
diff (- longest-key len)
|
||||
pad (gen-padding diff)]
|
||||
(println k pad "- " v)))
|
||||
definitions))))
|
||||
|
||||
(defn clj-compilation? []
|
||||
#?(:clj
|
||||
(not
|
||||
(boolean
|
||||
(when-let [n (find-ns 'cljs.analyzer)]
|
||||
(when-let [v (ns-resolve n '*cljs-file*)]
|
||||
@v))))
|
||||
:cljs false))
|
||||
|
||||
|
||||
(defn prepare-quil-name [const-keyword]
|
||||
(cstr/replace
|
||||
(cstr/upper-case (name const-keyword))
|
||||
#"-" "_"))
|
||||
|
||||
(defn prepare-quil-clj-constants [constants]
|
||||
(into {}
|
||||
(map
|
||||
#(vector % (symbol (str "PConstants/" (prepare-quil-name %))))
|
||||
constants)))
|
||||
|
||||
(defn prepare-quil-cljs-constants [constants]
|
||||
(into {}
|
||||
(map
|
||||
#(vector % `(aget js/Processing.prototype.PConstants ~(prepare-quil-name %)))
|
||||
constants)))
|
||||
|
||||
(defn make-quil-constant-map [target const-map-name const-map]
|
||||
`(def ^{:private true}
|
||||
~const-map-name
|
||||
~(if (= target :clj)
|
||||
(prepare-quil-clj-constants const-map)
|
||||
(prepare-quil-cljs-constants const-map))))
|
||||
|
||||
(defmacro generate-quil-constants [target & opts]
|
||||
`(do
|
||||
~@(map
|
||||
#(make-quil-constant-map target (first %) (second %))
|
||||
(partition 2 opts))))
|
1
assets/viz/2/quil/util.cljc.cache.edn
Normal file
1
assets/viz/2/quil/util.cljc.cache.edn
Normal file
File diff suppressed because one or more lines are too long
183
assets/viz/2/quil/util.js
Normal file
183
assets/viz/2/quil/util.js
Normal file
@ -0,0 +1,183 @@
|
||||
// Compiled by ClojureScript 1.9.473 {}
|
||||
goog.provide('quil.util');
|
||||
goog.require('cljs.core');
|
||||
goog.require('clojure.string');
|
||||
/**
|
||||
* Function that does nothing.
|
||||
*/
|
||||
quil.util.no_fn = (function quil$util$no_fn(){
|
||||
return null;
|
||||
});
|
||||
/**
|
||||
* Returns the val associated with key in mappings or key directly if it
|
||||
* is one of the vals in mappings. Otherwise throws an exception.
|
||||
*/
|
||||
quil.util.resolve_constant_key = (function quil$util$resolve_constant_key(key,mappings){
|
||||
if(cljs.core.truth_(cljs.core.get.call(null,mappings,key))){
|
||||
return cljs.core.get.call(null,mappings,key);
|
||||
} else {
|
||||
if(cljs.core.truth_(cljs.core.some.call(null,cljs.core.PersistentHashSet.createAsIfByAssoc([key], true),cljs.core.vals.call(null,mappings)))){
|
||||
return key;
|
||||
} else {
|
||||
throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Expecting a keyword, got: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(key),cljs.core.str.cljs$core$IFn$_invoke$arity$1(". Expected one of: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(cljs.core.vec.call(null,cljs.core.sort.call(null,cljs.core.keys.call(null,mappings))))].join('')));
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Returns the length of the longest key of map m. Assumes m's keys are strings
|
||||
* and returns 0 if map is empty:
|
||||
* (length-of-longest-key {"foo" 1 "barr" 2 "bazzz" 3}) ;=> 5
|
||||
* (length-of-longest-key {}) ;=> 0
|
||||
*/
|
||||
quil.util.length_of_longest_key = (function quil$util$length_of_longest_key(m){
|
||||
var or__6814__auto__ = cljs.core.last.call(null,cljs.core.sort.call(null,cljs.core.map.call(null,(function (p1__8123_SHARP_){
|
||||
return p1__8123_SHARP_.length();
|
||||
}),cljs.core.keys.call(null,m))));
|
||||
if(cljs.core.truth_(or__6814__auto__)){
|
||||
return or__6814__auto__;
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Generates a padding string starting concatting s with len times pad:
|
||||
* (gen-padding "" 5 "b") ;=> "bbbbb"
|
||||
* May be called without starting string s in which case it defaults to the
|
||||
* empty string and also without pad in which case it defaults to a single space
|
||||
*/
|
||||
quil.util.gen_padding = (function quil$util$gen_padding(var_args){
|
||||
var args8124 = [];
|
||||
var len__7927__auto___8127 = arguments.length;
|
||||
var i__7928__auto___8128 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___8128 < len__7927__auto___8127)){
|
||||
args8124.push((arguments[i__7928__auto___8128]));
|
||||
|
||||
var G__8129 = (i__7928__auto___8128 + (1));
|
||||
i__7928__auto___8128 = G__8129;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var G__8126 = args8124.length;
|
||||
switch (G__8126) {
|
||||
case 1:
|
||||
return quil.util.gen_padding.cljs$core$IFn$_invoke$arity$1((arguments[(0)]));
|
||||
|
||||
break;
|
||||
case 2:
|
||||
return quil.util.gen_padding.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
|
||||
|
||||
break;
|
||||
case 3:
|
||||
return quil.util.gen_padding.cljs$core$IFn$_invoke$arity$3((arguments[(0)]),(arguments[(1)]),(arguments[(2)]));
|
||||
|
||||
break;
|
||||
default:
|
||||
throw (new Error([cljs.core.str.cljs$core$IFn$_invoke$arity$1("Invalid arity: "),cljs.core.str.cljs$core$IFn$_invoke$arity$1(args8124.length)].join('')));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
quil.util.gen_padding.cljs$core$IFn$_invoke$arity$1 = (function (len){
|
||||
return quil.util.gen_padding.call(null,"",len," ");
|
||||
});
|
||||
|
||||
quil.util.gen_padding.cljs$core$IFn$_invoke$arity$2 = (function (len,pad){
|
||||
return quil.util.gen_padding.call(null,"",len,pad);
|
||||
});
|
||||
|
||||
quil.util.gen_padding.cljs$core$IFn$_invoke$arity$3 = (function (s,len,pad){
|
||||
if((len > (0))){
|
||||
return quil.util.gen_padding.call(null,[cljs.core.str.cljs$core$IFn$_invoke$arity$1(s),cljs.core.str.cljs$core$IFn$_invoke$arity$1(pad)].join(''),(len - (1)),pad);
|
||||
} else {
|
||||
return s;
|
||||
}
|
||||
});
|
||||
|
||||
quil.util.gen_padding.cljs$lang$maxFixedArity = 3;
|
||||
|
||||
quil.util.print_definition_list = (function quil$util$print_definition_list(definitions){
|
||||
var longest_key = quil.util.length_of_longest_key.call(null,definitions);
|
||||
return cljs.core.dorun.call(null,cljs.core.map.call(null,((function (longest_key){
|
||||
return (function (p__8135){
|
||||
var vec__8136 = p__8135;
|
||||
var k = cljs.core.nth.call(null,vec__8136,(0),null);
|
||||
var v = cljs.core.nth.call(null,vec__8136,(1),null);
|
||||
var len = k.length();
|
||||
var diff = (longest_key - len);
|
||||
var pad = quil.util.gen_padding.call(null,diff);
|
||||
return cljs.core.println.call(null,k,pad,"- ",v);
|
||||
});})(longest_key))
|
||||
,definitions));
|
||||
});
|
||||
quil.util.clj_compilation_QMARK_ = (function quil$util$clj_compilation_QMARK_(){
|
||||
return false;
|
||||
});
|
||||
quil.util.prepare_quil_name = (function quil$util$prepare_quil_name(const_keyword){
|
||||
return clojure.string.replace.call(null,clojure.string.upper_case.call(null,cljs.core.name.call(null,const_keyword)),/-/,"_");
|
||||
});
|
||||
quil.util.prepare_quil_clj_constants = (function quil$util$prepare_quil_clj_constants(constants){
|
||||
return cljs.core.into.call(null,cljs.core.PersistentArrayMap.EMPTY,cljs.core.map.call(null,(function (p1__8139_SHARP_){
|
||||
return (new cljs.core.PersistentVector(null,2,(5),cljs.core.PersistentVector.EMPTY_NODE,[p1__8139_SHARP_,cljs.core.symbol.call(null,[cljs.core.str.cljs$core$IFn$_invoke$arity$1("PConstants/"),cljs.core.str.cljs$core$IFn$_invoke$arity$1(quil.util.prepare_quil_name.call(null,p1__8139_SHARP_))].join(''))],null));
|
||||
}),constants));
|
||||
});
|
||||
quil.util.prepare_quil_cljs_constants = (function quil$util$prepare_quil_cljs_constants(constants){
|
||||
return cljs.core.into.call(null,cljs.core.PersistentArrayMap.EMPTY,cljs.core.map.call(null,(function (p1__8140_SHARP_){
|
||||
return (new cljs.core.PersistentVector(null,2,(5),cljs.core.PersistentVector.EMPTY_NODE,[p1__8140_SHARP_,cljs.core.sequence.call(null,cljs.core.seq.call(null,cljs.core.concat.call(null,cljs.core._conj.call(null,cljs.core.List.EMPTY,new cljs.core.Symbol("cljs.core","aget","cljs.core/aget",6345791,null)),cljs.core._conj.call(null,cljs.core.List.EMPTY,new cljs.core.Symbol("js","Processing.prototype.PConstants","js/Processing.prototype.PConstants",2034048972,null)),(function (){var x__7656__auto__ = quil.util.prepare_quil_name.call(null,p1__8140_SHARP_);
|
||||
return cljs.core._conj.call(null,cljs.core.List.EMPTY,x__7656__auto__);
|
||||
})())))],null));
|
||||
}),constants));
|
||||
});
|
||||
quil.util.make_quil_constant_map = (function quil$util$make_quil_constant_map(target,const_map_name,const_map){
|
||||
return cljs.core.sequence.call(null,cljs.core.seq.call(null,cljs.core.concat.call(null,cljs.core._conj.call(null,cljs.core.List.EMPTY,new cljs.core.Symbol(null,"def","def",597100991,null)),(function (){var x__7656__auto__ = const_map_name;
|
||||
return cljs.core._conj.call(null,cljs.core.List.EMPTY,x__7656__auto__);
|
||||
})(),(function (){var x__7656__auto__ = ((cljs.core._EQ_.call(null,target,new cljs.core.Keyword(null,"clj","clj",-660495428)))?quil.util.prepare_quil_clj_constants.call(null,const_map):quil.util.prepare_quil_cljs_constants.call(null,const_map));
|
||||
return cljs.core._conj.call(null,cljs.core.List.EMPTY,x__7656__auto__);
|
||||
})())));
|
||||
});
|
||||
quil.util.generate_quil_constants = (function quil$util$generate_quil_constants(var_args){
|
||||
var args__7934__auto__ = [];
|
||||
var len__7927__auto___8146 = arguments.length;
|
||||
var i__7928__auto___8147 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___8147 < len__7927__auto___8146)){
|
||||
args__7934__auto__.push((arguments[i__7928__auto___8147]));
|
||||
|
||||
var G__8148 = (i__7928__auto___8147 + (1));
|
||||
i__7928__auto___8147 = G__8148;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var argseq__7935__auto__ = ((((3) < args__7934__auto__.length))?(new cljs.core.IndexedSeq(args__7934__auto__.slice((3)),(0),null)):null);
|
||||
return quil.util.generate_quil_constants.cljs$core$IFn$_invoke$arity$variadic((arguments[(0)]),(arguments[(1)]),(arguments[(2)]),argseq__7935__auto__);
|
||||
});
|
||||
|
||||
quil.util.generate_quil_constants.cljs$core$IFn$_invoke$arity$variadic = (function (_AMPERSAND_form,_AMPERSAND_env,target,opts){
|
||||
return cljs.core.sequence.call(null,cljs.core.seq.call(null,cljs.core.concat.call(null,cljs.core._conj.call(null,cljs.core.List.EMPTY,new cljs.core.Symbol(null,"do","do",1686842252,null)),cljs.core.map.call(null,(function (p1__8141_SHARP_){
|
||||
return quil.util.make_quil_constant_map.call(null,target,cljs.core.first.call(null,p1__8141_SHARP_),cljs.core.second.call(null,p1__8141_SHARP_));
|
||||
}),cljs.core.partition.call(null,(2),opts)))));
|
||||
});
|
||||
|
||||
quil.util.generate_quil_constants.cljs$lang$maxFixedArity = (3);
|
||||
|
||||
quil.util.generate_quil_constants.cljs$lang$applyTo = (function (seq8142){
|
||||
var G__8143 = cljs.core.first.call(null,seq8142);
|
||||
var seq8142__$1 = cljs.core.next.call(null,seq8142);
|
||||
var G__8144 = cljs.core.first.call(null,seq8142__$1);
|
||||
var seq8142__$2 = cljs.core.next.call(null,seq8142__$1);
|
||||
var G__8145 = cljs.core.first.call(null,seq8142__$2);
|
||||
var seq8142__$3 = cljs.core.next.call(null,seq8142__$2);
|
||||
return quil.util.generate_quil_constants.cljs$core$IFn$_invoke$arity$variadic(G__8143,G__8144,G__8145,seq8142__$3);
|
||||
});
|
||||
|
||||
|
||||
quil.util.generate_quil_constants.cljs$lang$macro = true;
|
||||
|
||||
//# sourceMappingURL=util.js.map
|
1
assets/viz/2/quil/util.js.map
Normal file
1
assets/viz/2/quil/util.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/quil\/util.js","sources":["util.cljc"],"lineCount":183,"mappings":";AAAA;;;AAIA;;;kBAAA,lBAAMA;AAAN,AAAA;;AAsBA;;;;iCAAA,jCAAMC,0EAGHC,IAAIC;AAHP,AAIE,oBACE,AAACC,wBAAID,SAASD;AAAgB,OAACE,wBAAID,SAASD;;AAD9C,oBAEE,yBAAA,zBAACG,wEAAOH,YAAK,AAACI,yBAAKH;AAAWD;;AAFhC,AAIgC,MAAO,KAAAK,MAEC,6CAAA,2HAAA,jDAAkCL,oHAA0B,AAACM,wBAAI,AAACC,yBAAK,AAACC,yBAAKP;;;;;AAEvH;;;;;;kCAAA,lCAAOQ,4EAKJC;AALH,AAME,IAAAC,mBAAI,AAACC,yBAAK,AAACL,yBAAK,wBAAA,WAAAM,nCAACC;AAAD,AAAM,OAAAD;GAAY,AAACL,yBAAKE;AAAxC,AAAA,oBAAAC;AAAAA;;AAAA;;;AAGF,AAAA;;;;;;wBAAA,gCAAAI,xDAAOK;AAAP,AAAA,IAAAJ,WAAA;AAAA,AAAA,IAAAC,yBAAA,AAAA;AAAA,AAAA,IAAAC,uBAAA;;AAAA,AAAA,GAAA,CAAAA,uBAAAD;AAAA,AAAA,AAAAD,cAAA,CAAA,UAAAE;;AAAA,cAAA,CAAAA,uBAAA;;;;AAAA;;;;AAAA,IAAAC,UAAA,AAAAH;AAAA,AAAA,QAAAG;KAAA;AAAA,OAAAC,oDAAA,CAAA,UAAA;;;KAAA;AAAA,OAAAA,oDAAA,CAAA,UAAA,MAAA,CAAA,UAAA;;;KAAA;AAAA,OAAAA,oDAAA,CAAA,UAAA,MAAA,CAAA,UAAA,MAAA,CAAA,UAAA;;;;AAAA,MAAA,KAAAf,MAAA,6CAAA,+DAAA,AAAAW;;;;;AAAA,AAAA,sDAAA,tDAAOI,iEAKHC;AALJ,AAKS,uCAAA,OAAA,vCAACD,mCAAeC;;;AALzB,AAAA,sDAAA,tDAAOD,iEAMHC,IAAIC;AANR,AAMa,uCAAA,hCAACF,mCAAeC,IAAIC;;;AANjC,AAAA,sDAAA,tDAAOF,iEAOHG,EAAEF,IAAIC;AAPV,AAQK,GAAI,OAAA,NAAGD;AACL,OAACD,gCAAY,6CAAKG,+CAAED,eAAK,OAAA,NAAKD,WAAKC;;AACnCC;;;;AAVP,AAAA,gDAAA,hDAAOH;;AAAP,AAYA,kCAAA,lCAAMI,4EACHC;AADH,AAEE,IAAMC,cAAY,AAACjB,0CAAsBgB;AAAzC,AACE,OAACE,0BACA,AAACb,wBAAI;kBAAAc;AAAA,AAAA,IAAAC,YAAAD;QAAA,AAAAE,wBAAAD,UAAA,IAAA,1CAAME;QAAN,AAAAD,wBAAAD,UAAA,IAAA,1CAAQG;AAAR,AACE,IAAMX,MAAI,AAASU;IACbE,OAAK,CAAGP,cAAYL;IACpBC,MAAI,AAACF,gCAAYa;AAFvB,AAGE,yCAAA,lCAACC,4BAAQH,EAAET,SAASU;;CACxBP;;AAEV,mCAAA,nCAAMU;AAAN,AAAA;;AAUA,8BAAA,9BAAMC,oEAAmBC;AAAzB,AACE,qHAAA,IAAA,lHAACC,iCACA,AAACC,oCAAgB,AAACC,yBAAKH;;AAG1B,uCAAA,vCAAMI,sFAA4BC;AAAlC,AACE,gCAAA,zBAACC,4DACK,wBAAA,WAAAC,nCAAC9B;AAAD,AACE,YAAA+B,2BAAA,KAAA,EAAA,IAAA,AAAAA,sCAAA,CAAAD,uNAAA,vMAAU,AAACE,2BAAO,6CAAA,2DAAmB,sCAAAF,tCAACR;GACvCM;;AAET,wCAAA,xCAAMK,wFAA6BL;AAAnC,AACE,gCAAA,zBAACC,4DACK,wBAAA,WAAAK,nCAAClC;AAAD,AACE,YAAA+B,2BAAA,KAAA,EAAA,IAAA,AAAAA,sCAAA,CAAAG,gBAAA,AAAAC,6BAAA,AAAAC,wBAAA,AAAAC,2BAAA,AAAAC,+CAAA,wEAAA,AAAAA,+CAAA,mHAAA,iBAAAC,kBAAqD,sCAAAL,tCAACZ,lSAiyE5D,AAAAuC,uHAAA,AAAAA;AAjyEM,AAAA,OAAAvB,+CAAAC,rBAiyEN,AAAAsB;SAjyEM;GACDjC;;AAET,mCAAA,nCAAMY,8EAAwBC,OAAOC,eAAeC;AAApD,AAAA,OAAAR,6BAAA,AAAAC,wBAAA,AAAAC,2BAAA,AAAAC,+CAAA,uDAAA,iBAAAC,kBAEMG,\/GA4xEF,AAAAmB;AA9xEJ,AAAA,OAAAvB,+CAAAC,rBA8xEI,AAAAsB;KA9xEJ,iBAAAtB,kBAGM,EAAI,gCAAA,hCAACK,yBAAEH,4DACL,AAACd,+CAA2BgB,WAC5B,AAACV,gDAA4BU;AALrC,AAAA,OAAAL,+CAAAC,rBA8xEI,AAAAsB;;;AAvxEJ,AAAA,AAAA,oCAAA,4CAAA5D,hFAAU+C;AAAV,AAAA,IAAAH,qBAAA;AAAA,AAAA,IAAA1C,yBAAA,AAAA;AAAA,AAAA,IAAAC,uBAAA;;AAAA,AAAA,GAAA,CAAAA,uBAAAD;AAAA,AAAA,AAAA0C,wBAAA,CAAA,UAAAzC;;AAAA,cAAA,CAAAA,uBAAA;;;;AAAA;;;;AAAA,IAAA0C,uBAAA,EAAA,CAAA,MAAA,AAAAD,4BAAA,AAAA,KAAAE,qBAAA,AAAAF,yBAAA,KAAA,IAAA,OAAA;AAAA,AAAA,OAAAG,uEAAA,CAAA,UAAA,MAAA,CAAA,UAAA,MAAA,CAAA,UAAA,MAAAF;;;AAAA,AAAA,AAAA,AAAAE,yEAAA,WAAAC,gBAAAC,eAAmCT,OAASgB;AAA5C,AAAA,OAAAtB,6BAAA,AAAAC,wBAAA,AAAAC,2BAAA,AAAAC,+CAAA,sDAEO,wBAAA,WAAAoB,nCAAC1D,3EAqxEJ,AAAA6D;AArxEG,AACE,OAACrB,2CAAuBC,OAAO,0BAAAiB,1BAACL,2CAAS,2BAAAK,3BAACC;GAC3C,8BAAA,9BAACC,kCAAYH;;;AAJrB,AAAA,AAAAT,4DAAA;;AAAA,AAAA,AAAAA,sDAAA,WAAAG;AAAA,AAAA,IAAAC,UAAA,AAAAC,0BAAAF;IAAAA,cAAA,AAAAG,yBAAAH;IAAAI,UAAA,AAAAF,0BAAAF;IAAAA,cAAA,AAAAG,yBAAAH;IAAAK,UAAA,AAAAH,0BAAAF;IAAAA,cAAA,AAAAG,yBAAAH;AAAA,AAAA,OAAAH,uEAAAI,QAAAG,QAAAC,QAAAL;;;AAAA;AAAA,AAAA,oDAAA,pDAAUH","names":["quil.util\/no-fn","quil.util\/resolve-constant-key","key","mappings","cljs.core\/get","cljs.core\/some","cljs.core\/vals","js\/Error","cljs.core\/vec","cljs.core\/sort","cljs.core\/keys","quil.util\/length-of-longest-key","m","or__6814__auto__","cljs.core\/last","p1__8123#","cljs.core\/map","var_args","args8124","len__7927__auto__","i__7928__auto__","G__8126","quil.util\/gen-padding","len","pad","s","quil.util\/print-definition-list","definitions","longest-key","cljs.core\/dorun","p__8135","vec__8136","cljs.core\/nth","k","v","diff","cljs.core\/println","quil.util\/clj-compilation?","quil.util\/prepare-quil-name","const-keyword","clojure.string\/replace","clojure.string\/upper-case","cljs.core\/name","quil.util\/prepare-quil-clj-constants","constants","cljs.core\/into","p1__8139#","cljs.core\/PersistentVector","cljs.core\/symbol","quil.util\/prepare-quil-cljs-constants","p1__8140#","cljs.core\/sequence","cljs.core\/seq","cljs.core\/concat","cljs.core\/-conj","x__7656__auto__","quil.util\/make-quil-constant-map","target","const-map-name","const-map","cljs.core\/=","args__7934__auto__","argseq__7935__auto__","cljs.core\/IndexedSeq","quil.util\/generate-quil-constants","&form","&env","seq8142","G__8143","cljs.core\/first","cljs.core\/next","G__8144","G__8145","opts","p1__8141#","cljs.core\/second","cljs.core\/partition","cljs.core\/List"]}
|
346
assets/viz/2/viz/core.cljs
Normal file
346
assets/viz/2/viz/core.cljs
Normal file
@ -0,0 +1,346 @@
|
||||
(ns viz.core
|
||||
(:require [quil.core :as q]
|
||||
[quil.middleware :as m]
|
||||
[viz.forest :as forest]
|
||||
[viz.grid :as grid]
|
||||
[viz.ghost :as ghost]
|
||||
[viz.dial :as dial]
|
||||
[goog.string :as gstring]
|
||||
[goog.string.format]
|
||||
;[gil.core :as gil]
|
||||
))
|
||||
|
||||
(defn- debug [& args]
|
||||
(.log js/console (clojure.string/join " " (map str args))))
|
||||
|
||||
(defn- positive [n] (if (> 0 n) (- n) n))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; initialization
|
||||
|
||||
;; TODO move all code specific to drawing ghosts into the ghost package
|
||||
;; TODO make two ghosts, one opposite the color of the other
|
||||
|
||||
(defn- window-partial [k]
|
||||
(int (* (aget js/document "documentElement" k) 0.95)))
|
||||
|
||||
(def window-size [ (min 1025 (window-partial "clientWidth"))
|
||||
(int (* (window-partial "clientHeight") 0.75))
|
||||
])
|
||||
(def window-half-size (apply vector (map #(float (/ %1 2)) window-size)))
|
||||
|
||||
(def frame-rate 15)
|
||||
|
||||
(defn- new-state []
|
||||
{:frame-rate frame-rate
|
||||
:color-cycle-period 2
|
||||
:exit-wait-frames 40
|
||||
:tail-length 7
|
||||
:frame 0
|
||||
:dial (dial/new-dial)
|
||||
; 0.86 is roughly the beat period of a human heart
|
||||
:heartbeat-plot (dial/new-plot frame-rate 0.86 [[0.5 0.5] [0.7 0] [0.8 1]])
|
||||
:gif-seconds 0
|
||||
:grid-width 35 ; from the center
|
||||
:forest (forest/new-forest grid/isometric)
|
||||
:ghost (-> (ghost/new-ghost)
|
||||
(assoc :color (q/color 0 1 1))
|
||||
)
|
||||
})
|
||||
|
||||
(defn new-active-node [state pos]
|
||||
(let [[forest id] (forest/add-node (:forest state) pos)
|
||||
ghost (ghost/add-active-node (:ghost state) id)]
|
||||
(assoc state :ghost ghost :forest forest)))
|
||||
|
||||
(defn- frames-per-color-cycle [state]
|
||||
(* (:color-cycle-period state) (:frame-rate state)))
|
||||
|
||||
(defn setup []
|
||||
(q/color-mode :hsb 10 1 1)
|
||||
(let [state (-> (new-state)
|
||||
(new-active-node [10 10])
|
||||
)]
|
||||
(q/frame-rate (:frame-rate state))
|
||||
;; use frame-rate as the range of possibly hue values, so we can cycle all
|
||||
;; colors in a second
|
||||
(q/color-mode :hsb (frames-per-color-cycle state) 1 1)
|
||||
state))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; scaling and unit conversion related
|
||||
|
||||
(defn- curr-second [state]
|
||||
(float (/ (:frame state) (:frame-rate state))))
|
||||
|
||||
(defn- grid-size [state]
|
||||
(let [h (int (* (window-size 1)
|
||||
(float (/ (:grid-width state) (window-size 0)))))]
|
||||
[(:grid-width state) h]))
|
||||
|
||||
(defn- scale [state xy]
|
||||
(map-indexed #(* %2 (float (/ (window-half-size %1)
|
||||
((grid-size state) %1)))) xy))
|
||||
|
||||
(def bounds-buffer 1)
|
||||
|
||||
(defn- in-bounds? [state pos]
|
||||
(let [[w h] (apply vector (map #(- % bounds-buffer) (grid-size state)))
|
||||
min-bound [(- w) (- h)]
|
||||
max-bound [w h]
|
||||
pos-k (keep-indexed #(let [mini (min-bound %1)
|
||||
maxi (max-bound %1)]
|
||||
(when (and (>= %2 mini) (<= %2 maxi)) %2)) pos)]
|
||||
(= (count pos) (count pos-k))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; dials
|
||||
|
||||
(defn- ceil-one [x]
|
||||
(if (> x 0) 1 0))
|
||||
|
||||
(defn- set-dial [state]
|
||||
(update-in state [:dial] dial/by-plot (:heartbeat-plot state) (:frame state)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; poss-fn
|
||||
|
||||
(defn- dist-from-sqr [pos1 pos2]
|
||||
(reduce + (map #(* % %) (map - pos1 pos2))))
|
||||
|
||||
(defn- dist-from [pos1 pos2]
|
||||
(q/sqrt (dist-from-sqr pos1 pos2)))
|
||||
|
||||
(def order-adj-poss-fns
|
||||
{:random (fn [state]
|
||||
(fn [pos adj-poss] (shuffle adj-poss)))
|
||||
|
||||
:centered (fn [state]
|
||||
(fn [pos adj-poss]
|
||||
(sort-by #(dist-from-sqr % [0 0]) adj-poss)))
|
||||
})
|
||||
|
||||
(defn- mk-order-adj-poss-fn [& ks]
|
||||
(fn [state]
|
||||
(let [fns (map #(% state)
|
||||
(map order-adj-poss-fns ks))
|
||||
]
|
||||
(fn [pos adj-poss]
|
||||
(reduce
|
||||
(fn [inner-adj-poss next-fn] (next-fn pos inner-adj-poss))
|
||||
adj-poss
|
||||
fns))
|
||||
)))
|
||||
|
||||
(def take-adj-poss-fns
|
||||
{:random (fn [state]
|
||||
(fn [pos adj-poss]
|
||||
(q/map-range (rand) 0 1 0.75 1)))
|
||||
:dial (fn [state]
|
||||
(fn [pos adj-poss]
|
||||
(-> (:dial state)
|
||||
(dial/scaled -0.25 1.75)
|
||||
(:val)
|
||||
)))
|
||||
:centered (fn [state]
|
||||
(fn [pos adj-poss]
|
||||
(let [d (dist-from [0 0] pos)
|
||||
max-d (state :grid-width)
|
||||
norm-d (/ d max-d)
|
||||
]
|
||||
(- 1 norm-d)
|
||||
)))
|
||||
})
|
||||
|
||||
(defn- mk-take-adj-poss-fn [& ks]
|
||||
(fn [state]
|
||||
(let [fns (map #(% state)
|
||||
(map take-adj-poss-fns ks))
|
||||
]
|
||||
(fn [pos adj-poss]
|
||||
(let [mults (map #(% pos adj-poss) fns)
|
||||
mult (reduce * 1 mults)
|
||||
to-take (int (* mult (count adj-poss)))
|
||||
]
|
||||
(take to-take adj-poss)))
|
||||
)))
|
||||
|
||||
(def order-adj-poss-fn (mk-order-adj-poss-fn :centered))
|
||||
(def take-adj-poss-fn (mk-take-adj-poss-fn :centered :random))
|
||||
|
||||
(defn- mk-poss-fn [state]
|
||||
(let [order-inner-fn (order-adj-poss-fn state)
|
||||
take-inner-fn (take-adj-poss-fn state)
|
||||
]
|
||||
(fn [pos adj-poss]
|
||||
(let [adj-poss (filter #(in-bounds? state %) adj-poss)
|
||||
adj-poss-ordered (order-inner-fn pos adj-poss)
|
||||
to-take (take-inner-fn pos adj-poss)
|
||||
]
|
||||
(take-inner-fn pos adj-poss-ordered)))
|
||||
))
|
||||
|
||||
;; ghost
|
||||
|
||||
(defn- ghost-incr [state poss-fn]
|
||||
(let [[ghost forest] (ghost/incr (:ghost state) (:forest state) poss-fn)]
|
||||
(assoc state :ghost ghost :forest forest)))
|
||||
|
||||
(defn- maybe-remove-roots [state]
|
||||
(if (>= (:tail-length state) (:frame state)) state
|
||||
(let [roots (forest/roots (:forest state))
|
||||
root-ids (map :id roots)
|
||||
]
|
||||
(-> state
|
||||
(update-in [:ghost] #(reduce ghost/rm-active-node % root-ids))
|
||||
(update-in [:forest] #(reduce forest/remove-node % root-ids))
|
||||
))))
|
||||
|
||||
(defn- update-node-meta [state id f]
|
||||
(update-in state [:forest] forest/update-node-meta id f))
|
||||
|
||||
(defn- ghost-set-active-nodes-color [state]
|
||||
(let [color (q/color (mod (:frame state) (frames-per-color-cycle state)) 1 1)]
|
||||
(reduce
|
||||
(fn [state id] (update-node-meta state id #(assoc % :color color)))
|
||||
state
|
||||
(get-in state [:ghost :active-node-ids]))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; update
|
||||
|
||||
(defn- maybe-exit [state]
|
||||
(if (empty? (get-in state [:ghost :active-node-ids]))
|
||||
(if (zero? (:exit-wait-frames state)) (new-state)
|
||||
(update-in state [:exit-wait-frames] dec))
|
||||
state))
|
||||
|
||||
(defn update-state [state]
|
||||
(let [poss-fn (mk-poss-fn state)]
|
||||
(-> state
|
||||
;(set-dial)
|
||||
(ghost-incr poss-fn)
|
||||
(ghost-set-active-nodes-color)
|
||||
(maybe-remove-roots)
|
||||
(update-in [:frame] inc)
|
||||
(maybe-exit)
|
||||
)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; draw
|
||||
|
||||
(defn- draw-ellipse [state pos size] ; size is [w h]
|
||||
(let [scaled-pos (scale state pos)
|
||||
scaled-size (map int (scale state size))]
|
||||
(apply q/ellipse (concat scaled-pos scaled-size))))
|
||||
|
||||
(defn- in-line? [& nodes]
|
||||
(apply = (map #(apply map - %1)
|
||||
(partition 2 1 (map :pos nodes)))))
|
||||
|
||||
(defn- draw-node [state node active?]
|
||||
(let [pos (:pos node)
|
||||
stroke (get-in node [:meta :color])
|
||||
fill (if active? stroke 0xFFFFFFFF)
|
||||
size (:val (dial/scaled (:dial state) 0.25 0.45))
|
||||
]
|
||||
(q/stroke stroke)
|
||||
(q/fill fill)
|
||||
(draw-ellipse state pos [size size])))
|
||||
|
||||
(defn- draw-line [state node parent]
|
||||
(let [node-color (get-in node [:meta :color])
|
||||
parent-color (get-in node [:meta :color])
|
||||
color (q/lerp-color node-color parent-color 0.5)
|
||||
weight (:val (dial/scaled (:dial state) -1 3))
|
||||
]
|
||||
(q/stroke color)
|
||||
(q/stroke-weight weight)
|
||||
(apply q/line (map #(scale state %) (map :pos (list parent node))))))
|
||||
|
||||
(defn draw-lines [state forest parent node]
|
||||
"Draws the lines of all children leading from the node, recursively"
|
||||
(let [children (map #(forest/get-node forest %) (:child-ids node))]
|
||||
|
||||
(if-not parent
|
||||
(doseq [child children] (draw-lines state forest node child))
|
||||
(let [in-line-child (some #(if (in-line? parent node %) %) children)
|
||||
]
|
||||
(doseq [child children]
|
||||
(if (and in-line-child (= in-line-child child))
|
||||
(draw-lines state forest parent child)
|
||||
(draw-lines state forest node child)))
|
||||
(when-not in-line-child
|
||||
(draw-line state node parent))
|
||||
))
|
||||
|
||||
; we also take the opportunity to draw the leaves
|
||||
(when (empty? children)
|
||||
(draw-node state node false))
|
||||
|
||||
))
|
||||
|
||||
(defn draw-dial [state dial posL posR]
|
||||
(let [dial-norm (q/norm (:val dial) (:min dial) (:max dial))
|
||||
dial-pos (map #(q/lerp %1 %2 dial-norm) posL posR)]
|
||||
(q/stroke 0xFF000000)
|
||||
(q/stroke-weight 1)
|
||||
(q/fill 0xFF000000)
|
||||
(apply q/line (concat posL posR))
|
||||
(apply q/ellipse (concat dial-pos [5 5]))
|
||||
))
|
||||
|
||||
(defn draw-state [state]
|
||||
; Clear the sketch by filling it with light-grey color.
|
||||
(q/background 0xFFFFFFFF)
|
||||
(q/with-translation [(/ (window-size 0) 2)
|
||||
(/ (window-size 1) 2)]
|
||||
(let [lines (forest/lines (:forest state))
|
||||
leaves (forest/leaves (:forest state))
|
||||
active (ghost/active-nodes (:ghost state) (:forest state))
|
||||
roots (forest/roots (:forest state))
|
||||
]
|
||||
|
||||
;(q/stroke 0xFF000000)
|
||||
(doseq [root roots]
|
||||
(draw-lines state (:forest state) nil root))
|
||||
|
||||
;(q/stroke 0xFF000000)
|
||||
;(q/fill 0xFF000000)
|
||||
(doseq [active-node active]
|
||||
(draw-node state active-node true))
|
||||
))
|
||||
|
||||
;(draw-dial state (:dial state) [30 30] [100 30])
|
||||
|
||||
;(when-not (zero? (:gif-seconds state))
|
||||
; (let [anim-frames (* (:gif-seconds state) (:frame-rate state))]
|
||||
; (gil/save-animation "quil.gif" anim-frames 0)
|
||||
; (when (> (:frame state) anim-frames) (q/exit))))
|
||||
|
||||
;(q/text (clojure.string/join
|
||||
; "\n"
|
||||
; (list
|
||||
; (gstring/format "frame:%d" (:frame state))
|
||||
; (gstring/format "second:%f" (curr-second state))
|
||||
; (gstring/format "spawn-chance:%d" (spawn-chance state))))
|
||||
; 30 30)
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; def
|
||||
|
||||
(q/defsketch viz
|
||||
:title ""
|
||||
:host "viz"
|
||||
:size window-size
|
||||
; setup function called only once, during sketch initialization.
|
||||
:setup setup
|
||||
; update-state is called on each iteration before draw-state.
|
||||
:update update-state
|
||||
:draw draw-state
|
||||
:features [:keep-on-top]
|
||||
; This sketch uses functional-mode middleware.
|
||||
; Check quil wiki for more info about middlewares and particularly
|
||||
; fun-mode.
|
||||
:middleware [m/fun-mode])
|
1
assets/viz/2/viz/core.cljs.cache.edn
Normal file
1
assets/viz/2/viz/core.cljs.cache.edn
Normal file
File diff suppressed because one or more lines are too long
771
assets/viz/2/viz/core.js
Normal file
771
assets/viz/2/viz/core.js
Normal file
@ -0,0 +1,771 @@
|
||||
// Compiled by ClojureScript 1.9.473 {}
|
||||
goog.provide('viz.core');
|
||||
goog.require('cljs.core');
|
||||
goog.require('quil.core');
|
||||
goog.require('quil.middleware');
|
||||
goog.require('viz.forest');
|
||||
goog.require('viz.grid');
|
||||
goog.require('viz.ghost');
|
||||
goog.require('viz.dial');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.format');
|
||||
viz.core.debug = (function viz$core$debug(var_args){
|
||||
var args__7934__auto__ = [];
|
||||
var len__7927__auto___15474 = arguments.length;
|
||||
var i__7928__auto___15475 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___15475 < len__7927__auto___15474)){
|
||||
args__7934__auto__.push((arguments[i__7928__auto___15475]));
|
||||
|
||||
var G__15476 = (i__7928__auto___15475 + (1));
|
||||
i__7928__auto___15475 = G__15476;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var argseq__7935__auto__ = ((((0) < args__7934__auto__.length))?(new cljs.core.IndexedSeq(args__7934__auto__.slice((0)),(0),null)):null);
|
||||
return viz.core.debug.cljs$core$IFn$_invoke$arity$variadic(argseq__7935__auto__);
|
||||
});
|
||||
|
||||
viz.core.debug.cljs$core$IFn$_invoke$arity$variadic = (function (args){
|
||||
return console.log(clojure.string.join.call(null," ",cljs.core.map.call(null,cljs.core.str,args)));
|
||||
});
|
||||
|
||||
viz.core.debug.cljs$lang$maxFixedArity = (0);
|
||||
|
||||
viz.core.debug.cljs$lang$applyTo = (function (seq15473){
|
||||
return viz.core.debug.cljs$core$IFn$_invoke$arity$variadic(cljs.core.seq.call(null,seq15473));
|
||||
});
|
||||
|
||||
viz.core.positive = (function viz$core$positive(n){
|
||||
if(((0) > n)){
|
||||
return (- n);
|
||||
} else {
|
||||
return n;
|
||||
}
|
||||
});
|
||||
viz.core.window_partial = (function viz$core$window_partial(k){
|
||||
return (((document["documentElement"][k]) * 0.95) | (0));
|
||||
});
|
||||
viz.core.window_size = new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(function (){var x__7157__auto__ = (1025);
|
||||
var y__7158__auto__ = viz.core.window_partial.call(null,"clientWidth");
|
||||
return ((x__7157__auto__ < y__7158__auto__) ? x__7157__auto__ : y__7158__auto__);
|
||||
})(),((viz.core.window_partial.call(null,"clientHeight") * 0.75) | (0))], null);
|
||||
viz.core.window_half_size = cljs.core.apply.call(null,cljs.core.vector,cljs.core.map.call(null,(function (p1__15477_SHARP_){
|
||||
return (p1__15477_SHARP_ / (2));
|
||||
}),viz.core.window_size));
|
||||
viz.core.frame_rate = (15);
|
||||
viz.core.new_state = (function viz$core$new_state(){
|
||||
return cljs.core.PersistentHashMap.fromArrays([new cljs.core.Keyword(null,"grid-width","grid-width",837583106),new cljs.core.Keyword(null,"frame-rate","frame-rate",-994918942),new cljs.core.Keyword(null,"color-cycle-period","color-cycle-period",1656886882),new cljs.core.Keyword(null,"frame","frame",-1711082588),new cljs.core.Keyword(null,"heartbeat-plot","heartbeat-plot",-98284443),new cljs.core.Keyword(null,"exit-wait-frames","exit-wait-frames",1417213098),new cljs.core.Keyword(null,"gif-seconds","gif-seconds",1861397548),new cljs.core.Keyword(null,"tail-length","tail-length",-2007115089),new cljs.core.Keyword(null,"forest","forest",278860306),new cljs.core.Keyword(null,"dial","dial",1238392184),new cljs.core.Keyword(null,"ghost","ghost",-1531157576)],[(35),viz.core.frame_rate,(2),(0),viz.dial.new_plot.call(null,viz.core.frame_rate,0.86,new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [0.5,0.5], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [0.7,(0)], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [0.8,(1)], null)], null)),(40),(0),(7),viz.forest.new_forest.call(null,viz.grid.isometric),viz.dial.new_dial.call(null),cljs.core.assoc.call(null,viz.ghost.new_ghost.call(null),new cljs.core.Keyword(null,"color","color",1011675173),quil.core.color.call(null,(0),(1),(1)))]);
|
||||
});
|
||||
viz.core.new_active_node = (function viz$core$new_active_node(state,pos){
|
||||
var vec__15481 = viz.forest.add_node.call(null,new cljs.core.Keyword(null,"forest","forest",278860306).cljs$core$IFn$_invoke$arity$1(state),pos);
|
||||
var forest = cljs.core.nth.call(null,vec__15481,(0),null);
|
||||
var id = cljs.core.nth.call(null,vec__15481,(1),null);
|
||||
var ghost = viz.ghost.add_active_node.call(null,new cljs.core.Keyword(null,"ghost","ghost",-1531157576).cljs$core$IFn$_invoke$arity$1(state),id);
|
||||
return cljs.core.assoc.call(null,state,new cljs.core.Keyword(null,"ghost","ghost",-1531157576),ghost,new cljs.core.Keyword(null,"forest","forest",278860306),forest);
|
||||
});
|
||||
viz.core.frames_per_color_cycle = (function viz$core$frames_per_color_cycle(state){
|
||||
return (new cljs.core.Keyword(null,"color-cycle-period","color-cycle-period",1656886882).cljs$core$IFn$_invoke$arity$1(state) * new cljs.core.Keyword(null,"frame-rate","frame-rate",-994918942).cljs$core$IFn$_invoke$arity$1(state));
|
||||
});
|
||||
viz.core.setup = (function viz$core$setup(){
|
||||
quil.core.color_mode.call(null,new cljs.core.Keyword(null,"hsb","hsb",-753472031),(10),(1),(1));
|
||||
|
||||
var state = viz.core.new_active_node.call(null,viz.core.new_state.call(null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(10),(10)], null));
|
||||
quil.core.frame_rate.call(null,new cljs.core.Keyword(null,"frame-rate","frame-rate",-994918942).cljs$core$IFn$_invoke$arity$1(state));
|
||||
|
||||
quil.core.color_mode.call(null,new cljs.core.Keyword(null,"hsb","hsb",-753472031),viz.core.frames_per_color_cycle.call(null,state),(1),(1));
|
||||
|
||||
return state;
|
||||
});
|
||||
viz.core.curr_second = (function viz$core$curr_second(state){
|
||||
return (new cljs.core.Keyword(null,"frame","frame",-1711082588).cljs$core$IFn$_invoke$arity$1(state) / new cljs.core.Keyword(null,"frame-rate","frame-rate",-994918942).cljs$core$IFn$_invoke$arity$1(state));
|
||||
});
|
||||
viz.core.grid_size = (function viz$core$grid_size(state){
|
||||
var h = ((viz.core.window_size.call(null,(1)) * (new cljs.core.Keyword(null,"grid-width","grid-width",837583106).cljs$core$IFn$_invoke$arity$1(state) / viz.core.window_size.call(null,(0)))) | (0));
|
||||
return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"grid-width","grid-width",837583106).cljs$core$IFn$_invoke$arity$1(state),h], null);
|
||||
});
|
||||
viz.core.scale = (function viz$core$scale(state,xy){
|
||||
return cljs.core.map_indexed.call(null,(function (p1__15485_SHARP_,p2__15484_SHARP_){
|
||||
return (p2__15484_SHARP_ * (viz.core.window_half_size.call(null,p1__15485_SHARP_) / viz.core.grid_size.call(null,state).call(null,p1__15485_SHARP_)));
|
||||
}),xy);
|
||||
});
|
||||
viz.core.bounds_buffer = (1);
|
||||
viz.core.in_bounds_QMARK_ = (function viz$core$in_bounds_QMARK_(state,pos){
|
||||
var vec__15492 = cljs.core.apply.call(null,cljs.core.vector,cljs.core.map.call(null,(function (p1__15486_SHARP_){
|
||||
return (p1__15486_SHARP_ - viz.core.bounds_buffer);
|
||||
}),viz.core.grid_size.call(null,state)));
|
||||
var w = cljs.core.nth.call(null,vec__15492,(0),null);
|
||||
var h = cljs.core.nth.call(null,vec__15492,(1),null);
|
||||
var min_bound = new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(- w),(- h)], null);
|
||||
var max_bound = new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [w,h], null);
|
||||
var pos_k = cljs.core.keep_indexed.call(null,((function (vec__15492,w,h,min_bound,max_bound){
|
||||
return (function (p1__15487_SHARP_,p2__15488_SHARP_){
|
||||
var mini = min_bound.call(null,p1__15487_SHARP_);
|
||||
var maxi = max_bound.call(null,p1__15487_SHARP_);
|
||||
if(((p2__15488_SHARP_ >= mini)) && ((p2__15488_SHARP_ <= maxi))){
|
||||
return p2__15488_SHARP_;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});})(vec__15492,w,h,min_bound,max_bound))
|
||||
,pos);
|
||||
return cljs.core._EQ_.call(null,cljs.core.count.call(null,pos),cljs.core.count.call(null,pos_k));
|
||||
});
|
||||
viz.core.ceil_one = (function viz$core$ceil_one(x){
|
||||
if((x > (0))){
|
||||
return (1);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
});
|
||||
viz.core.set_dial = (function viz$core$set_dial(state){
|
||||
return cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"dial","dial",1238392184)], null),viz.dial.by_plot,new cljs.core.Keyword(null,"heartbeat-plot","heartbeat-plot",-98284443).cljs$core$IFn$_invoke$arity$1(state),new cljs.core.Keyword(null,"frame","frame",-1711082588).cljs$core$IFn$_invoke$arity$1(state));
|
||||
});
|
||||
viz.core.dist_from_sqr = (function viz$core$dist_from_sqr(pos1,pos2){
|
||||
return cljs.core.reduce.call(null,cljs.core._PLUS_,cljs.core.map.call(null,(function (p1__15495_SHARP_){
|
||||
return (p1__15495_SHARP_ * p1__15495_SHARP_);
|
||||
}),cljs.core.map.call(null,cljs.core._,pos1,pos2)));
|
||||
});
|
||||
viz.core.dist_from = (function viz$core$dist_from(pos1,pos2){
|
||||
return quil.core.sqrt.call(null,viz.core.dist_from_sqr.call(null,pos1,pos2));
|
||||
});
|
||||
viz.core.order_adj_poss_fns = new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"random","random",-557811113),(function (state){
|
||||
return (function (pos,adj_poss){
|
||||
return cljs.core.shuffle.call(null,adj_poss);
|
||||
});
|
||||
}),new cljs.core.Keyword(null,"centered","centered",-515171141),(function (state){
|
||||
return (function (pos,adj_poss){
|
||||
return cljs.core.sort_by.call(null,(function (p1__15496_SHARP_){
|
||||
return viz.core.dist_from_sqr.call(null,p1__15496_SHARP_,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(0)], null));
|
||||
}),adj_poss);
|
||||
});
|
||||
})], null);
|
||||
viz.core.mk_order_adj_poss_fn = (function viz$core$mk_order_adj_poss_fn(var_args){
|
||||
var args__7934__auto__ = [];
|
||||
var len__7927__auto___15499 = arguments.length;
|
||||
var i__7928__auto___15500 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___15500 < len__7927__auto___15499)){
|
||||
args__7934__auto__.push((arguments[i__7928__auto___15500]));
|
||||
|
||||
var G__15501 = (i__7928__auto___15500 + (1));
|
||||
i__7928__auto___15500 = G__15501;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var argseq__7935__auto__ = ((((0) < args__7934__auto__.length))?(new cljs.core.IndexedSeq(args__7934__auto__.slice((0)),(0),null)):null);
|
||||
return viz.core.mk_order_adj_poss_fn.cljs$core$IFn$_invoke$arity$variadic(argseq__7935__auto__);
|
||||
});
|
||||
|
||||
viz.core.mk_order_adj_poss_fn.cljs$core$IFn$_invoke$arity$variadic = (function (ks){
|
||||
return (function (state){
|
||||
var fns = cljs.core.map.call(null,(function (p1__15497_SHARP_){
|
||||
return p1__15497_SHARP_.call(null,state);
|
||||
}),cljs.core.map.call(null,viz.core.order_adj_poss_fns,ks));
|
||||
return ((function (fns){
|
||||
return (function (pos,adj_poss){
|
||||
return cljs.core.reduce.call(null,((function (fns){
|
||||
return (function (inner_adj_poss,next_fn){
|
||||
return next_fn.call(null,pos,inner_adj_poss);
|
||||
});})(fns))
|
||||
,adj_poss,fns);
|
||||
});
|
||||
;})(fns))
|
||||
});
|
||||
});
|
||||
|
||||
viz.core.mk_order_adj_poss_fn.cljs$lang$maxFixedArity = (0);
|
||||
|
||||
viz.core.mk_order_adj_poss_fn.cljs$lang$applyTo = (function (seq15498){
|
||||
return viz.core.mk_order_adj_poss_fn.cljs$core$IFn$_invoke$arity$variadic(cljs.core.seq.call(null,seq15498));
|
||||
});
|
||||
|
||||
viz.core.take_adj_poss_fns = new cljs.core.PersistentArrayMap(null, 3, [new cljs.core.Keyword(null,"random","random",-557811113),(function (state){
|
||||
return (function (pos,adj_poss){
|
||||
return quil.core.map_range.call(null,cljs.core.rand.call(null),(0),(1),0.75,(1));
|
||||
});
|
||||
}),new cljs.core.Keyword(null,"dial","dial",1238392184),(function (state){
|
||||
return (function (pos,adj_poss){
|
||||
return new cljs.core.Keyword(null,"val","val",128701612).cljs$core$IFn$_invoke$arity$1(viz.dial.scaled.call(null,new cljs.core.Keyword(null,"dial","dial",1238392184).cljs$core$IFn$_invoke$arity$1(state),-0.25,1.75));
|
||||
});
|
||||
}),new cljs.core.Keyword(null,"centered","centered",-515171141),(function (state){
|
||||
return (function (pos,adj_poss){
|
||||
var d = viz.core.dist_from.call(null,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(0)], null),pos);
|
||||
var max_d = state.call(null,new cljs.core.Keyword(null,"grid-width","grid-width",837583106));
|
||||
var norm_d = (d / max_d);
|
||||
return ((1) - norm_d);
|
||||
});
|
||||
})], null);
|
||||
viz.core.mk_take_adj_poss_fn = (function viz$core$mk_take_adj_poss_fn(var_args){
|
||||
var args__7934__auto__ = [];
|
||||
var len__7927__auto___15505 = arguments.length;
|
||||
var i__7928__auto___15506 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___15506 < len__7927__auto___15505)){
|
||||
args__7934__auto__.push((arguments[i__7928__auto___15506]));
|
||||
|
||||
var G__15507 = (i__7928__auto___15506 + (1));
|
||||
i__7928__auto___15506 = G__15507;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var argseq__7935__auto__ = ((((0) < args__7934__auto__.length))?(new cljs.core.IndexedSeq(args__7934__auto__.slice((0)),(0),null)):null);
|
||||
return viz.core.mk_take_adj_poss_fn.cljs$core$IFn$_invoke$arity$variadic(argseq__7935__auto__);
|
||||
});
|
||||
|
||||
viz.core.mk_take_adj_poss_fn.cljs$core$IFn$_invoke$arity$variadic = (function (ks){
|
||||
return (function (state){
|
||||
var fns = cljs.core.map.call(null,(function (p1__15502_SHARP_){
|
||||
return p1__15502_SHARP_.call(null,state);
|
||||
}),cljs.core.map.call(null,viz.core.take_adj_poss_fns,ks));
|
||||
return ((function (fns){
|
||||
return (function (pos,adj_poss){
|
||||
var mults = cljs.core.map.call(null,((function (fns){
|
||||
return (function (p1__15503_SHARP_){
|
||||
return p1__15503_SHARP_.call(null,pos,adj_poss);
|
||||
});})(fns))
|
||||
,fns);
|
||||
var mult = cljs.core.reduce.call(null,cljs.core._STAR_,(1),mults);
|
||||
var to_take = ((mult * cljs.core.count.call(null,adj_poss)) | (0));
|
||||
return cljs.core.take.call(null,to_take,adj_poss);
|
||||
});
|
||||
;})(fns))
|
||||
});
|
||||
});
|
||||
|
||||
viz.core.mk_take_adj_poss_fn.cljs$lang$maxFixedArity = (0);
|
||||
|
||||
viz.core.mk_take_adj_poss_fn.cljs$lang$applyTo = (function (seq15504){
|
||||
return viz.core.mk_take_adj_poss_fn.cljs$core$IFn$_invoke$arity$variadic(cljs.core.seq.call(null,seq15504));
|
||||
});
|
||||
|
||||
viz.core.order_adj_poss_fn = viz.core.mk_order_adj_poss_fn.call(null,new cljs.core.Keyword(null,"centered","centered",-515171141));
|
||||
viz.core.take_adj_poss_fn = viz.core.mk_take_adj_poss_fn.call(null,new cljs.core.Keyword(null,"centered","centered",-515171141),new cljs.core.Keyword(null,"random","random",-557811113));
|
||||
viz.core.mk_poss_fn = (function viz$core$mk_poss_fn(state){
|
||||
var order_inner_fn = viz.core.order_adj_poss_fn.call(null,state);
|
||||
var take_inner_fn = viz.core.take_adj_poss_fn.call(null,state);
|
||||
return ((function (order_inner_fn,take_inner_fn){
|
||||
return (function (pos,adj_poss){
|
||||
var adj_poss__$1 = cljs.core.filter.call(null,((function (order_inner_fn,take_inner_fn){
|
||||
return (function (p1__15508_SHARP_){
|
||||
return viz.core.in_bounds_QMARK_.call(null,state,p1__15508_SHARP_);
|
||||
});})(order_inner_fn,take_inner_fn))
|
||||
,adj_poss);
|
||||
var adj_poss_ordered = order_inner_fn.call(null,pos,adj_poss__$1);
|
||||
var to_take = take_inner_fn.call(null,pos,adj_poss__$1);
|
||||
return take_inner_fn.call(null,pos,adj_poss_ordered);
|
||||
});
|
||||
;})(order_inner_fn,take_inner_fn))
|
||||
});
|
||||
viz.core.ghost_incr = (function viz$core$ghost_incr(state,poss_fn){
|
||||
var vec__15512 = viz.ghost.incr.call(null,new cljs.core.Keyword(null,"ghost","ghost",-1531157576).cljs$core$IFn$_invoke$arity$1(state),new cljs.core.Keyword(null,"forest","forest",278860306).cljs$core$IFn$_invoke$arity$1(state),poss_fn);
|
||||
var ghost = cljs.core.nth.call(null,vec__15512,(0),null);
|
||||
var forest = cljs.core.nth.call(null,vec__15512,(1),null);
|
||||
return cljs.core.assoc.call(null,state,new cljs.core.Keyword(null,"ghost","ghost",-1531157576),ghost,new cljs.core.Keyword(null,"forest","forest",278860306),forest);
|
||||
});
|
||||
viz.core.maybe_remove_roots = (function viz$core$maybe_remove_roots(state){
|
||||
if((new cljs.core.Keyword(null,"tail-length","tail-length",-2007115089).cljs$core$IFn$_invoke$arity$1(state) >= new cljs.core.Keyword(null,"frame","frame",-1711082588).cljs$core$IFn$_invoke$arity$1(state))){
|
||||
return state;
|
||||
} else {
|
||||
var roots = viz.forest.roots.call(null,new cljs.core.Keyword(null,"forest","forest",278860306).cljs$core$IFn$_invoke$arity$1(state));
|
||||
var root_ids = cljs.core.map.call(null,new cljs.core.Keyword(null,"id","id",-1388402092),roots);
|
||||
return cljs.core.update_in.call(null,cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"ghost","ghost",-1531157576)], null),((function (roots,root_ids){
|
||||
return (function (p1__15515_SHARP_){
|
||||
return cljs.core.reduce.call(null,viz.ghost.rm_active_node,p1__15515_SHARP_,root_ids);
|
||||
});})(roots,root_ids))
|
||||
),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"forest","forest",278860306)], null),((function (roots,root_ids){
|
||||
return (function (p1__15516_SHARP_){
|
||||
return cljs.core.reduce.call(null,viz.forest.remove_node,p1__15516_SHARP_,root_ids);
|
||||
});})(roots,root_ids))
|
||||
);
|
||||
}
|
||||
});
|
||||
viz.core.update_node_meta = (function viz$core$update_node_meta(state,id,f){
|
||||
return cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"forest","forest",278860306)], null),viz.forest.update_node_meta,id,f);
|
||||
});
|
||||
viz.core.ghost_set_active_nodes_color = (function viz$core$ghost_set_active_nodes_color(state){
|
||||
var color = quil.core.color.call(null,cljs.core.mod.call(null,new cljs.core.Keyword(null,"frame","frame",-1711082588).cljs$core$IFn$_invoke$arity$1(state),viz.core.frames_per_color_cycle.call(null,state)),(1),(1));
|
||||
return cljs.core.reduce.call(null,((function (color){
|
||||
return (function (state__$1,id){
|
||||
return viz.core.update_node_meta.call(null,state__$1,id,((function (color){
|
||||
return (function (p1__15517_SHARP_){
|
||||
return cljs.core.assoc.call(null,p1__15517_SHARP_,new cljs.core.Keyword(null,"color","color",1011675173),color);
|
||||
});})(color))
|
||||
);
|
||||
});})(color))
|
||||
,state,cljs.core.get_in.call(null,state,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"ghost","ghost",-1531157576),new cljs.core.Keyword(null,"active-node-ids","active-node-ids",-398210751)], null)));
|
||||
});
|
||||
viz.core.maybe_exit = (function viz$core$maybe_exit(state){
|
||||
if(cljs.core.empty_QMARK_.call(null,cljs.core.get_in.call(null,state,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"ghost","ghost",-1531157576),new cljs.core.Keyword(null,"active-node-ids","active-node-ids",-398210751)], null)))){
|
||||
if((new cljs.core.Keyword(null,"exit-wait-frames","exit-wait-frames",1417213098).cljs$core$IFn$_invoke$arity$1(state) === (0))){
|
||||
return viz.core.new_state.call(null);
|
||||
} else {
|
||||
return cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"exit-wait-frames","exit-wait-frames",1417213098)], null),cljs.core.dec);
|
||||
}
|
||||
} else {
|
||||
return state;
|
||||
}
|
||||
});
|
||||
viz.core.update_state = (function viz$core$update_state(state){
|
||||
var poss_fn = viz.core.mk_poss_fn.call(null,state);
|
||||
return viz.core.maybe_exit.call(null,cljs.core.update_in.call(null,viz.core.maybe_remove_roots.call(null,viz.core.ghost_set_active_nodes_color.call(null,viz.core.ghost_incr.call(null,state,poss_fn))),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"frame","frame",-1711082588)], null),cljs.core.inc));
|
||||
});
|
||||
viz.core.draw_ellipse = (function viz$core$draw_ellipse(state,pos,size){
|
||||
var scaled_pos = viz.core.scale.call(null,state,pos);
|
||||
var scaled_size = cljs.core.map.call(null,cljs.core.int$,viz.core.scale.call(null,state,size));
|
||||
return cljs.core.apply.call(null,quil.core.ellipse,cljs.core.concat.call(null,scaled_pos,scaled_size));
|
||||
});
|
||||
viz.core.in_line_QMARK_ = (function viz$core$in_line_QMARK_(var_args){
|
||||
var args__7934__auto__ = [];
|
||||
var len__7927__auto___15520 = arguments.length;
|
||||
var i__7928__auto___15521 = (0);
|
||||
while(true){
|
||||
if((i__7928__auto___15521 < len__7927__auto___15520)){
|
||||
args__7934__auto__.push((arguments[i__7928__auto___15521]));
|
||||
|
||||
var G__15522 = (i__7928__auto___15521 + (1));
|
||||
i__7928__auto___15521 = G__15522;
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var argseq__7935__auto__ = ((((0) < args__7934__auto__.length))?(new cljs.core.IndexedSeq(args__7934__auto__.slice((0)),(0),null)):null);
|
||||
return viz.core.in_line_QMARK_.cljs$core$IFn$_invoke$arity$variadic(argseq__7935__auto__);
|
||||
});
|
||||
|
||||
viz.core.in_line_QMARK_.cljs$core$IFn$_invoke$arity$variadic = (function (nodes){
|
||||
return cljs.core.apply.call(null,cljs.core._EQ_,cljs.core.map.call(null,(function (p1__15518_SHARP_){
|
||||
return cljs.core.apply.call(null,cljs.core.map,cljs.core._,p1__15518_SHARP_);
|
||||
}),cljs.core.partition.call(null,(2),(1),cljs.core.map.call(null,new cljs.core.Keyword(null,"pos","pos",-864607220),nodes))));
|
||||
});
|
||||
|
||||
viz.core.in_line_QMARK_.cljs$lang$maxFixedArity = (0);
|
||||
|
||||
viz.core.in_line_QMARK_.cljs$lang$applyTo = (function (seq15519){
|
||||
return viz.core.in_line_QMARK_.cljs$core$IFn$_invoke$arity$variadic(cljs.core.seq.call(null,seq15519));
|
||||
});
|
||||
|
||||
viz.core.draw_node = (function viz$core$draw_node(state,node,active_QMARK_){
|
||||
var pos = new cljs.core.Keyword(null,"pos","pos",-864607220).cljs$core$IFn$_invoke$arity$1(node);
|
||||
var stroke = cljs.core.get_in.call(null,node,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"meta","meta",1499536964),new cljs.core.Keyword(null,"color","color",1011675173)], null));
|
||||
var fill = (cljs.core.truth_(active_QMARK_)?stroke:(4294967295));
|
||||
var size = new cljs.core.Keyword(null,"val","val",128701612).cljs$core$IFn$_invoke$arity$1(viz.dial.scaled.call(null,new cljs.core.Keyword(null,"dial","dial",1238392184).cljs$core$IFn$_invoke$arity$1(state),0.25,0.45));
|
||||
quil.core.stroke.call(null,stroke);
|
||||
|
||||
quil.core.fill.call(null,fill);
|
||||
|
||||
return viz.core.draw_ellipse.call(null,state,pos,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [size,size], null));
|
||||
});
|
||||
viz.core.draw_line = (function viz$core$draw_line(state,node,parent){
|
||||
var node_color = cljs.core.get_in.call(null,node,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"meta","meta",1499536964),new cljs.core.Keyword(null,"color","color",1011675173)], null));
|
||||
var parent_color = cljs.core.get_in.call(null,node,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"meta","meta",1499536964),new cljs.core.Keyword(null,"color","color",1011675173)], null));
|
||||
var color = quil.core.lerp_color.call(null,node_color,parent_color,0.5);
|
||||
var weight = new cljs.core.Keyword(null,"val","val",128701612).cljs$core$IFn$_invoke$arity$1(viz.dial.scaled.call(null,new cljs.core.Keyword(null,"dial","dial",1238392184).cljs$core$IFn$_invoke$arity$1(state),(-1),(3)));
|
||||
quil.core.stroke.call(null,color);
|
||||
|
||||
quil.core.stroke_weight.call(null,weight);
|
||||
|
||||
return cljs.core.apply.call(null,quil.core.line,cljs.core.map.call(null,((function (node_color,parent_color,color,weight){
|
||||
return (function (p1__15523_SHARP_){
|
||||
return viz.core.scale.call(null,state,p1__15523_SHARP_);
|
||||
});})(node_color,parent_color,color,weight))
|
||||
,cljs.core.map.call(null,new cljs.core.Keyword(null,"pos","pos",-864607220),(function (){var x__7656__auto__ = parent;
|
||||
return cljs.core._conj.call(null,(function (){var x__7656__auto____$1 = node;
|
||||
return cljs.core._conj.call(null,cljs.core.List.EMPTY,x__7656__auto____$1);
|
||||
})(),x__7656__auto__);
|
||||
})())));
|
||||
});
|
||||
viz.core.draw_lines = (function viz$core$draw_lines(state,forest,parent,node){
|
||||
|
||||
var children = cljs.core.map.call(null,(function (p1__15524_SHARP_){
|
||||
return viz.forest.get_node.call(null,forest,p1__15524_SHARP_);
|
||||
}),new cljs.core.Keyword(null,"child-ids","child-ids",-604525861).cljs$core$IFn$_invoke$arity$1(node));
|
||||
if(cljs.core.not.call(null,parent)){
|
||||
var seq__15534_15542 = cljs.core.seq.call(null,children);
|
||||
var chunk__15535_15543 = null;
|
||||
var count__15536_15544 = (0);
|
||||
var i__15537_15545 = (0);
|
||||
while(true){
|
||||
if((i__15537_15545 < count__15536_15544)){
|
||||
var child_15546 = cljs.core._nth.call(null,chunk__15535_15543,i__15537_15545);
|
||||
viz.core.draw_lines.call(null,state,forest,node,child_15546);
|
||||
|
||||
var G__15547 = seq__15534_15542;
|
||||
var G__15548 = chunk__15535_15543;
|
||||
var G__15549 = count__15536_15544;
|
||||
var G__15550 = (i__15537_15545 + (1));
|
||||
seq__15534_15542 = G__15547;
|
||||
chunk__15535_15543 = G__15548;
|
||||
count__15536_15544 = G__15549;
|
||||
i__15537_15545 = G__15550;
|
||||
continue;
|
||||
} else {
|
||||
var temp__4657__auto___15551 = cljs.core.seq.call(null,seq__15534_15542);
|
||||
if(temp__4657__auto___15551){
|
||||
var seq__15534_15552__$1 = temp__4657__auto___15551;
|
||||
if(cljs.core.chunked_seq_QMARK_.call(null,seq__15534_15552__$1)){
|
||||
var c__7633__auto___15553 = cljs.core.chunk_first.call(null,seq__15534_15552__$1);
|
||||
var G__15554 = cljs.core.chunk_rest.call(null,seq__15534_15552__$1);
|
||||
var G__15555 = c__7633__auto___15553;
|
||||
var G__15556 = cljs.core.count.call(null,c__7633__auto___15553);
|
||||
var G__15557 = (0);
|
||||
seq__15534_15542 = G__15554;
|
||||
chunk__15535_15543 = G__15555;
|
||||
count__15536_15544 = G__15556;
|
||||
i__15537_15545 = G__15557;
|
||||
continue;
|
||||
} else {
|
||||
var child_15558 = cljs.core.first.call(null,seq__15534_15552__$1);
|
||||
viz.core.draw_lines.call(null,state,forest,node,child_15558);
|
||||
|
||||
var G__15559 = cljs.core.next.call(null,seq__15534_15552__$1);
|
||||
var G__15560 = null;
|
||||
var G__15561 = (0);
|
||||
var G__15562 = (0);
|
||||
seq__15534_15542 = G__15559;
|
||||
chunk__15535_15543 = G__15560;
|
||||
count__15536_15544 = G__15561;
|
||||
i__15537_15545 = G__15562;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
var in_line_child_15563 = cljs.core.some.call(null,((function (children){
|
||||
return (function (p1__15525_SHARP_){
|
||||
if(cljs.core.truth_(viz.core.in_line_QMARK_.call(null,parent,node,p1__15525_SHARP_))){
|
||||
return p1__15525_SHARP_;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});})(children))
|
||||
,children);
|
||||
var seq__15538_15564 = cljs.core.seq.call(null,children);
|
||||
var chunk__15539_15565 = null;
|
||||
var count__15540_15566 = (0);
|
||||
var i__15541_15567 = (0);
|
||||
while(true){
|
||||
if((i__15541_15567 < count__15540_15566)){
|
||||
var child_15568 = cljs.core._nth.call(null,chunk__15539_15565,i__15541_15567);
|
||||
if(cljs.core.truth_((function (){var and__6802__auto__ = in_line_child_15563;
|
||||
if(cljs.core.truth_(and__6802__auto__)){
|
||||
return cljs.core._EQ_.call(null,in_line_child_15563,child_15568);
|
||||
} else {
|
||||
return and__6802__auto__;
|
||||
}
|
||||
})())){
|
||||
viz.core.draw_lines.call(null,state,forest,parent,child_15568);
|
||||
} else {
|
||||
viz.core.draw_lines.call(null,state,forest,node,child_15568);
|
||||
}
|
||||
|
||||
var G__15569 = seq__15538_15564;
|
||||
var G__15570 = chunk__15539_15565;
|
||||
var G__15571 = count__15540_15566;
|
||||
var G__15572 = (i__15541_15567 + (1));
|
||||
seq__15538_15564 = G__15569;
|
||||
chunk__15539_15565 = G__15570;
|
||||
count__15540_15566 = G__15571;
|
||||
i__15541_15567 = G__15572;
|
||||
continue;
|
||||
} else {
|
||||
var temp__4657__auto___15573 = cljs.core.seq.call(null,seq__15538_15564);
|
||||
if(temp__4657__auto___15573){
|
||||
var seq__15538_15574__$1 = temp__4657__auto___15573;
|
||||
if(cljs.core.chunked_seq_QMARK_.call(null,seq__15538_15574__$1)){
|
||||
var c__7633__auto___15575 = cljs.core.chunk_first.call(null,seq__15538_15574__$1);
|
||||
var G__15576 = cljs.core.chunk_rest.call(null,seq__15538_15574__$1);
|
||||
var G__15577 = c__7633__auto___15575;
|
||||
var G__15578 = cljs.core.count.call(null,c__7633__auto___15575);
|
||||
var G__15579 = (0);
|
||||
seq__15538_15564 = G__15576;
|
||||
chunk__15539_15565 = G__15577;
|
||||
count__15540_15566 = G__15578;
|
||||
i__15541_15567 = G__15579;
|
||||
continue;
|
||||
} else {
|
||||
var child_15580 = cljs.core.first.call(null,seq__15538_15574__$1);
|
||||
if(cljs.core.truth_((function (){var and__6802__auto__ = in_line_child_15563;
|
||||
if(cljs.core.truth_(and__6802__auto__)){
|
||||
return cljs.core._EQ_.call(null,in_line_child_15563,child_15580);
|
||||
} else {
|
||||
return and__6802__auto__;
|
||||
}
|
||||
})())){
|
||||
viz.core.draw_lines.call(null,state,forest,parent,child_15580);
|
||||
} else {
|
||||
viz.core.draw_lines.call(null,state,forest,node,child_15580);
|
||||
}
|
||||
|
||||
var G__15581 = cljs.core.next.call(null,seq__15538_15574__$1);
|
||||
var G__15582 = null;
|
||||
var G__15583 = (0);
|
||||
var G__15584 = (0);
|
||||
seq__15538_15564 = G__15581;
|
||||
chunk__15539_15565 = G__15582;
|
||||
count__15540_15566 = G__15583;
|
||||
i__15541_15567 = G__15584;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(cljs.core.truth_(in_line_child_15563)){
|
||||
} else {
|
||||
viz.core.draw_line.call(null,state,node,parent);
|
||||
}
|
||||
}
|
||||
|
||||
if(cljs.core.empty_QMARK_.call(null,children)){
|
||||
return viz.core.draw_node.call(null,state,node,false);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
viz.core.draw_dial = (function viz$core$draw_dial(state,dial,posL,posR){
|
||||
var dial_norm = quil.core.norm.call(null,new cljs.core.Keyword(null,"val","val",128701612).cljs$core$IFn$_invoke$arity$1(dial),new cljs.core.Keyword(null,"min","min",444991522).cljs$core$IFn$_invoke$arity$1(dial),new cljs.core.Keyword(null,"max","max",61366548).cljs$core$IFn$_invoke$arity$1(dial));
|
||||
var dial_pos = cljs.core.map.call(null,((function (dial_norm){
|
||||
return (function (p1__15585_SHARP_,p2__15586_SHARP_){
|
||||
return quil.core.lerp.call(null,p1__15585_SHARP_,p2__15586_SHARP_,dial_norm);
|
||||
});})(dial_norm))
|
||||
,posL,posR);
|
||||
quil.core.stroke.call(null,(4278190080));
|
||||
|
||||
quil.core.stroke_weight.call(null,(1));
|
||||
|
||||
quil.core.fill.call(null,(4278190080));
|
||||
|
||||
cljs.core.apply.call(null,quil.core.line,cljs.core.concat.call(null,posL,posR));
|
||||
|
||||
return cljs.core.apply.call(null,quil.core.ellipse,cljs.core.concat.call(null,dial_pos,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(5),(5)], null)));
|
||||
});
|
||||
viz.core.draw_state = (function viz$core$draw_state(state){
|
||||
quil.core.background.call(null,(4294967295));
|
||||
|
||||
var tr__8398__auto__ = new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(viz.core.window_size.call(null,(0)) / (2)),(viz.core.window_size.call(null,(1)) / (2))], null);
|
||||
quil.core.push_matrix.call(null);
|
||||
|
||||
try{quil.core.translate.call(null,tr__8398__auto__);
|
||||
|
||||
var lines = viz.forest.lines.call(null,new cljs.core.Keyword(null,"forest","forest",278860306).cljs$core$IFn$_invoke$arity$1(state));
|
||||
var leaves = viz.forest.leaves.call(null,new cljs.core.Keyword(null,"forest","forest",278860306).cljs$core$IFn$_invoke$arity$1(state));
|
||||
var active = viz.ghost.active_nodes.call(null,new cljs.core.Keyword(null,"ghost","ghost",-1531157576).cljs$core$IFn$_invoke$arity$1(state),new cljs.core.Keyword(null,"forest","forest",278860306).cljs$core$IFn$_invoke$arity$1(state));
|
||||
var roots = viz.forest.roots.call(null,new cljs.core.Keyword(null,"forest","forest",278860306).cljs$core$IFn$_invoke$arity$1(state));
|
||||
var seq__15595_15603 = cljs.core.seq.call(null,roots);
|
||||
var chunk__15596_15604 = null;
|
||||
var count__15597_15605 = (0);
|
||||
var i__15598_15606 = (0);
|
||||
while(true){
|
||||
if((i__15598_15606 < count__15597_15605)){
|
||||
var root_15607 = cljs.core._nth.call(null,chunk__15596_15604,i__15598_15606);
|
||||
viz.core.draw_lines.call(null,state,new cljs.core.Keyword(null,"forest","forest",278860306).cljs$core$IFn$_invoke$arity$1(state),null,root_15607);
|
||||
|
||||
var G__15608 = seq__15595_15603;
|
||||
var G__15609 = chunk__15596_15604;
|
||||
var G__15610 = count__15597_15605;
|
||||
var G__15611 = (i__15598_15606 + (1));
|
||||
seq__15595_15603 = G__15608;
|
||||
chunk__15596_15604 = G__15609;
|
||||
count__15597_15605 = G__15610;
|
||||
i__15598_15606 = G__15611;
|
||||
continue;
|
||||
} else {
|
||||
var temp__4657__auto___15612 = cljs.core.seq.call(null,seq__15595_15603);
|
||||
if(temp__4657__auto___15612){
|
||||
var seq__15595_15613__$1 = temp__4657__auto___15612;
|
||||
if(cljs.core.chunked_seq_QMARK_.call(null,seq__15595_15613__$1)){
|
||||
var c__7633__auto___15614 = cljs.core.chunk_first.call(null,seq__15595_15613__$1);
|
||||
var G__15615 = cljs.core.chunk_rest.call(null,seq__15595_15613__$1);
|
||||
var G__15616 = c__7633__auto___15614;
|
||||
var G__15617 = cljs.core.count.call(null,c__7633__auto___15614);
|
||||
var G__15618 = (0);
|
||||
seq__15595_15603 = G__15615;
|
||||
chunk__15596_15604 = G__15616;
|
||||
count__15597_15605 = G__15617;
|
||||
i__15598_15606 = G__15618;
|
||||
continue;
|
||||
} else {
|
||||
var root_15619 = cljs.core.first.call(null,seq__15595_15613__$1);
|
||||
viz.core.draw_lines.call(null,state,new cljs.core.Keyword(null,"forest","forest",278860306).cljs$core$IFn$_invoke$arity$1(state),null,root_15619);
|
||||
|
||||
var G__15620 = cljs.core.next.call(null,seq__15595_15613__$1);
|
||||
var G__15621 = null;
|
||||
var G__15622 = (0);
|
||||
var G__15623 = (0);
|
||||
seq__15595_15603 = G__15620;
|
||||
chunk__15596_15604 = G__15621;
|
||||
count__15597_15605 = G__15622;
|
||||
i__15598_15606 = G__15623;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var seq__15599 = cljs.core.seq.call(null,active);
|
||||
var chunk__15600 = null;
|
||||
var count__15601 = (0);
|
||||
var i__15602 = (0);
|
||||
while(true){
|
||||
if((i__15602 < count__15601)){
|
||||
var active_node = cljs.core._nth.call(null,chunk__15600,i__15602);
|
||||
viz.core.draw_node.call(null,state,active_node,true);
|
||||
|
||||
var G__15624 = seq__15599;
|
||||
var G__15625 = chunk__15600;
|
||||
var G__15626 = count__15601;
|
||||
var G__15627 = (i__15602 + (1));
|
||||
seq__15599 = G__15624;
|
||||
chunk__15600 = G__15625;
|
||||
count__15601 = G__15626;
|
||||
i__15602 = G__15627;
|
||||
continue;
|
||||
} else {
|
||||
var temp__4657__auto__ = cljs.core.seq.call(null,seq__15599);
|
||||
if(temp__4657__auto__){
|
||||
var seq__15599__$1 = temp__4657__auto__;
|
||||
if(cljs.core.chunked_seq_QMARK_.call(null,seq__15599__$1)){
|
||||
var c__7633__auto__ = cljs.core.chunk_first.call(null,seq__15599__$1);
|
||||
var G__15628 = cljs.core.chunk_rest.call(null,seq__15599__$1);
|
||||
var G__15629 = c__7633__auto__;
|
||||
var G__15630 = cljs.core.count.call(null,c__7633__auto__);
|
||||
var G__15631 = (0);
|
||||
seq__15599 = G__15628;
|
||||
chunk__15600 = G__15629;
|
||||
count__15601 = G__15630;
|
||||
i__15602 = G__15631;
|
||||
continue;
|
||||
} else {
|
||||
var active_node = cljs.core.first.call(null,seq__15599__$1);
|
||||
viz.core.draw_node.call(null,state,active_node,true);
|
||||
|
||||
var G__15632 = cljs.core.next.call(null,seq__15599__$1);
|
||||
var G__15633 = null;
|
||||
var G__15634 = (0);
|
||||
var G__15635 = (0);
|
||||
seq__15599 = G__15632;
|
||||
chunk__15600 = G__15633;
|
||||
count__15601 = G__15634;
|
||||
i__15602 = G__15635;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}finally {quil.core.pop_matrix.call(null);
|
||||
}});
|
||||
viz.core.viz = (function viz$core$viz(){
|
||||
return quil.sketch.sketch.call(null,new cljs.core.Keyword(null,"host","host",-1558485167),"viz",new cljs.core.Keyword(null,"features","features",-1146962336),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"keep-on-top","keep-on-top",-970284267)], null),new cljs.core.Keyword(null,"update","update",1045576396),((cljs.core.fn_QMARK_.call(null,viz.core.update_state))?(function() {
|
||||
var G__15636__delegate = function (args){
|
||||
return cljs.core.apply.call(null,viz.core.update_state,args);
|
||||
};
|
||||
var G__15636 = function (var_args){
|
||||
var args = null;
|
||||
if (arguments.length > 0) {
|
||||
var G__15637__i = 0, G__15637__a = new Array(arguments.length - 0);
|
||||
while (G__15637__i < G__15637__a.length) {G__15637__a[G__15637__i] = arguments[G__15637__i + 0]; ++G__15637__i;}
|
||||
args = new cljs.core.IndexedSeq(G__15637__a,0);
|
||||
}
|
||||
return G__15636__delegate.call(this,args);};
|
||||
G__15636.cljs$lang$maxFixedArity = 0;
|
||||
G__15636.cljs$lang$applyTo = (function (arglist__15638){
|
||||
var args = cljs.core.seq(arglist__15638);
|
||||
return G__15636__delegate(args);
|
||||
});
|
||||
G__15636.cljs$core$IFn$_invoke$arity$variadic = G__15636__delegate;
|
||||
return G__15636;
|
||||
})()
|
||||
:viz.core.update_state),new cljs.core.Keyword(null,"size","size",1098693007),((cljs.core.fn_QMARK_.call(null,viz.core.window_size))?(function() {
|
||||
var G__15639__delegate = function (args){
|
||||
return cljs.core.apply.call(null,viz.core.window_size,args);
|
||||
};
|
||||
var G__15639 = function (var_args){
|
||||
var args = null;
|
||||
if (arguments.length > 0) {
|
||||
var G__15640__i = 0, G__15640__a = new Array(arguments.length - 0);
|
||||
while (G__15640__i < G__15640__a.length) {G__15640__a[G__15640__i] = arguments[G__15640__i + 0]; ++G__15640__i;}
|
||||
args = new cljs.core.IndexedSeq(G__15640__a,0);
|
||||
}
|
||||
return G__15639__delegate.call(this,args);};
|
||||
G__15639.cljs$lang$maxFixedArity = 0;
|
||||
G__15639.cljs$lang$applyTo = (function (arglist__15641){
|
||||
var args = cljs.core.seq(arglist__15641);
|
||||
return G__15639__delegate(args);
|
||||
});
|
||||
G__15639.cljs$core$IFn$_invoke$arity$variadic = G__15639__delegate;
|
||||
return G__15639;
|
||||
})()
|
||||
:viz.core.window_size),new cljs.core.Keyword(null,"title","title",636505583),"",new cljs.core.Keyword(null,"setup","setup",1987730512),((cljs.core.fn_QMARK_.call(null,viz.core.setup))?(function() {
|
||||
var G__15642__delegate = function (args){
|
||||
return cljs.core.apply.call(null,viz.core.setup,args);
|
||||
};
|
||||
var G__15642 = function (var_args){
|
||||
var args = null;
|
||||
if (arguments.length > 0) {
|
||||
var G__15643__i = 0, G__15643__a = new Array(arguments.length - 0);
|
||||
while (G__15643__i < G__15643__a.length) {G__15643__a[G__15643__i] = arguments[G__15643__i + 0]; ++G__15643__i;}
|
||||
args = new cljs.core.IndexedSeq(G__15643__a,0);
|
||||
}
|
||||
return G__15642__delegate.call(this,args);};
|
||||
G__15642.cljs$lang$maxFixedArity = 0;
|
||||
G__15642.cljs$lang$applyTo = (function (arglist__15644){
|
||||
var args = cljs.core.seq(arglist__15644);
|
||||
return G__15642__delegate(args);
|
||||
});
|
||||
G__15642.cljs$core$IFn$_invoke$arity$variadic = G__15642__delegate;
|
||||
return G__15642;
|
||||
})()
|
||||
:viz.core.setup),new cljs.core.Keyword(null,"middleware","middleware",1462115504),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [quil.middleware.fun_mode], null),new cljs.core.Keyword(null,"draw","draw",1358331674),((cljs.core.fn_QMARK_.call(null,viz.core.draw_state))?(function() {
|
||||
var G__15645__delegate = function (args){
|
||||
return cljs.core.apply.call(null,viz.core.draw_state,args);
|
||||
};
|
||||
var G__15645 = function (var_args){
|
||||
var args = null;
|
||||
if (arguments.length > 0) {
|
||||
var G__15646__i = 0, G__15646__a = new Array(arguments.length - 0);
|
||||
while (G__15646__i < G__15646__a.length) {G__15646__a[G__15646__i] = arguments[G__15646__i + 0]; ++G__15646__i;}
|
||||
args = new cljs.core.IndexedSeq(G__15646__a,0);
|
||||
}
|
||||
return G__15645__delegate.call(this,args);};
|
||||
G__15645.cljs$lang$maxFixedArity = 0;
|
||||
G__15645.cljs$lang$applyTo = (function (arglist__15647){
|
||||
var args = cljs.core.seq(arglist__15647);
|
||||
return G__15645__delegate(args);
|
||||
});
|
||||
G__15645.cljs$core$IFn$_invoke$arity$variadic = G__15645__delegate;
|
||||
return G__15645;
|
||||
})()
|
||||
:viz.core.draw_state));
|
||||
});
|
||||
goog.exportSymbol('viz.core.viz', viz.core.viz);
|
||||
|
||||
if(cljs.core.truth_(cljs.core.some.call(null,(function (p1__8011__8012__auto__){
|
||||
return cljs.core._EQ_.call(null,new cljs.core.Keyword(null,"no-start","no-start",1381488856),p1__8011__8012__auto__);
|
||||
}),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"keep-on-top","keep-on-top",-970284267)], null)))){
|
||||
} else {
|
||||
quil.sketch.add_sketch_to_init_list.call(null,new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"fn","fn",-1175266204),viz.core.viz,new cljs.core.Keyword(null,"host-id","host-id",742376279),"viz"], null));
|
||||
}
|
||||
|
||||
//# sourceMappingURL=core.js.map
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user