diff --git a/resources/celerity/map.php b/resources/celerity/map.php
index d11174a1d2..89425d6cc4 100644
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -1,2443 +1,2443 @@
 <?php
 
 /**
  * This file is automatically generated. Use 'bin/celerity map' to rebuild it.
  *
  * @generated
  */
 return array(
   'names' => array(
     'conpherence.pkg.css' => '0e3cf785',
     'conpherence.pkg.js' => '020aebcf',
-    'core.pkg.css' => 'bb377509',
+    'core.pkg.css' => '6590cb9f',
     'core.pkg.js' => '66c49ca1',
     'dark-console.pkg.js' => '187792c2',
     'differential.pkg.css' => '609e63d4',
     'differential.pkg.js' => 'c60bec1b',
     'diffusion.pkg.css' => '42c75c37',
     'diffusion.pkg.js' => '78c9885d',
     'maniphest.pkg.css' => '35995d6d',
     'maniphest.pkg.js' => 'c9308721',
     'rsrc/audio/basic/alert.mp3' => '17889334',
     'rsrc/audio/basic/bing.mp3' => 'a817a0c3',
     'rsrc/audio/basic/pock.mp3' => '0fa843d0',
     'rsrc/audio/basic/tap.mp3' => '02d16994',
     'rsrc/audio/basic/ting.mp3' => 'a6b6540e',
     'rsrc/css/aphront/aphront-bars.css' => '4a327b4a',
     'rsrc/css/aphront/dark-console.css' => '7f06cda2',
     'rsrc/css/aphront/dialog-view.css' => '6f4ea703',
     'rsrc/css/aphront/list-filter-view.css' => 'feb64255',
     'rsrc/css/aphront/multi-column.css' => 'fbc00ba3',
     'rsrc/css/aphront/notification.css' => '30240bd2',
     'rsrc/css/aphront/panel-view.css' => '46923d46',
     'rsrc/css/aphront/phabricator-nav-view.css' => '423f92cc',
     'rsrc/css/aphront/table-view.css' => '0bb61df1',
     'rsrc/css/aphront/tokenizer.css' => '34e2a838',
     'rsrc/css/aphront/tooltip.css' => 'e3f2412f',
     'rsrc/css/aphront/typeahead-browse.css' => 'b7ed02d2',
     'rsrc/css/aphront/typeahead.css' => '8779483d',
     'rsrc/css/application/almanac/almanac.css' => '2e050f4f',
     'rsrc/css/application/auth/auth.css' => 'c2f23d74',
     'rsrc/css/application/base/main-menu-view.css' => '89fc16b6',
     'rsrc/css/application/base/notification-menu.css' => '4df1ee30',
     'rsrc/css/application/base/phui-theme.css' => '35883b37',
     'rsrc/css/application/base/standard-page-view.css' => 'a374f94c',
     'rsrc/css/application/chatlog/chatlog.css' => 'abdc76ee',
     'rsrc/css/application/conduit/conduit-api.css' => 'ce2cfc41',
     'rsrc/css/application/config/config-options.css' => '16c920ae',
     'rsrc/css/application/config/config-template.css' => 'e689dbbd',
     'rsrc/css/application/config/setup-issue.css' => '5eed85b2',
     'rsrc/css/application/config/unhandled-exception.css' => '9ecfc00d',
     'rsrc/css/application/conpherence/color.css' => 'b17746b0',
     'rsrc/css/application/conpherence/durable-column.css' => '2d57072b',
     'rsrc/css/application/conpherence/header-pane.css' => 'c9a3db8e',
     'rsrc/css/application/conpherence/menu.css' => '67f4680d',
     'rsrc/css/application/conpherence/message-pane.css' => 'd244db1e',
     'rsrc/css/application/conpherence/notification.css' => '6a3d4e58',
     'rsrc/css/application/conpherence/participant-pane.css' => '69e0058a',
     'rsrc/css/application/conpherence/transaction.css' => '3a3f5e7e',
     'rsrc/css/application/contentsource/content-source-view.css' => 'cdf0d579',
     'rsrc/css/application/countdown/timer.css' => 'bff8012f',
     'rsrc/css/application/daemon/bulk-job.css' => '73af99f5',
     'rsrc/css/application/dashboard/dashboard.css' => '5a205b9d',
     'rsrc/css/application/diff/diff-tree-view.css' => 'e2d3e222',
     'rsrc/css/application/diff/inline-comment-summary.css' => '81eb368d',
     'rsrc/css/application/differential/add-comment.css' => '7e5900d9',
     'rsrc/css/application/differential/changeset-view.css' => 'bf159129',
     'rsrc/css/application/differential/core.css' => '7300a73e',
     'rsrc/css/application/differential/phui-inline-comment.css' => 'a864426f',
     'rsrc/css/application/differential/revision-comment.css' => '7dbc8d1d',
     'rsrc/css/application/differential/revision-history.css' => '237a2979',
     'rsrc/css/application/differential/revision-list.css' => '93d2df7d',
     'rsrc/css/application/differential/table-of-contents.css' => 'bba788b9',
     'rsrc/css/application/diffusion/diffusion-icons.css' => '23b31a1b',
     'rsrc/css/application/diffusion/diffusion-readme.css' => 'b68a76e4',
     'rsrc/css/application/diffusion/diffusion-repository.css' => 'b89e8c6c',
     'rsrc/css/application/diffusion/diffusion.css' => 'e46232d6',
     'rsrc/css/application/feed/feed.css' => 'd8b6e3f8',
     'rsrc/css/application/files/global-drag-and-drop.css' => '1d2713a4',
     'rsrc/css/application/flag/flag.css' => '2b77be8d',
     'rsrc/css/application/harbormaster/harbormaster.css' => 'd98decda',
     'rsrc/css/application/herald/herald-test.css' => '7e7bbdae',
     'rsrc/css/application/herald/herald.css' => '648d39e2',
     'rsrc/css/application/maniphest/report.css' => '3d53188b',
     'rsrc/css/application/maniphest/task-edit.css' => '272daa84',
     'rsrc/css/application/maniphest/task-summary.css' => '61d1667e',
     'rsrc/css/application/objectselector/object-selector.css' => 'ee77366f',
     'rsrc/css/application/owners/owners-path-editor.css' => 'fa7c13ef',
     'rsrc/css/application/paste/paste.css' => 'b37bcd38',
     'rsrc/css/application/people/people-picture-menu-item.css' => 'fe8e07cf',
     'rsrc/css/application/people/people-profile.css' => '2ea2daa1',
     'rsrc/css/application/phame/phame.css' => 'bb442327',
     'rsrc/css/application/pholio/pholio-edit.css' => '4df55b3b',
     'rsrc/css/application/pholio/pholio-inline-comments.css' => '722b48c2',
     'rsrc/css/application/pholio/pholio.css' => '88ef5ef1',
     'rsrc/css/application/phortune/phortune-credit-card-form.css' => '3b9868a8',
     'rsrc/css/application/phortune/phortune-invoice.css' => '4436b241',
     'rsrc/css/application/phortune/phortune.css' => '508a1a5e',
     'rsrc/css/application/phrequent/phrequent.css' => 'bd79cc67',
     'rsrc/css/application/phriction/phriction-document-css.css' => '03380da0',
     'rsrc/css/application/policy/policy-edit.css' => '8794e2ed',
     'rsrc/css/application/policy/policy-transaction-detail.css' => 'c02b8384',
     'rsrc/css/application/policy/policy.css' => 'ceb56a08',
     'rsrc/css/application/ponder/ponder-view.css' => '05a09d0a',
     'rsrc/css/application/project/project-card-view.css' => 'c1200da7',
     'rsrc/css/application/project/project-triggers.css' => 'cd9c8bb9',
     'rsrc/css/application/project/project-view.css' => '2f7caa20',
     'rsrc/css/application/search/application-search-view.css' => '0f7c06d8',
     'rsrc/css/application/search/search-results.css' => '9ea70ace',
     'rsrc/css/application/slowvote/slowvote.css' => '1694baed',
     'rsrc/css/application/tokens/tokens.css' => 'ce5a50bd',
     'rsrc/css/application/uiexample/example.css' => 'b4795059',
     'rsrc/css/core/core.css' => 'a708bd25',
     'rsrc/css/core/remarkup.css' => '5baa3bd9',
     'rsrc/css/core/syntax.css' => '548567f6',
     'rsrc/css/core/z-index.css' => 'ac3bfcd4',
     'rsrc/css/diviner/diviner-shared.css' => '4bd263b0',
     'rsrc/css/font/font-awesome.css' => '3883938a',
     'rsrc/css/font/font-lato.css' => '23631304',
     'rsrc/css/font/phui-font-icon-base.css' => '303c9b87',
     'rsrc/css/fuel/fuel-grid.css' => '66697240',
     'rsrc/css/fuel/fuel-handle-list.css' => '2c4cbeca',
     'rsrc/css/fuel/fuel-map.css' => 'd6e31510',
     'rsrc/css/fuel/fuel-menu.css' => '21f5d199',
     'rsrc/css/layout/phabricator-source-code-view.css' => '6b31244f',
     'rsrc/css/phui/button/phui-button-bar.css' => 'a4aa75c4',
     'rsrc/css/phui/button/phui-button-simple.css' => '1ff278aa',
     'rsrc/css/phui/button/phui-button.css' => 'e434f171',
     'rsrc/css/phui/calendar/phui-calendar-day.css' => '9597d706',
     'rsrc/css/phui/calendar/phui-calendar-list.css' => 'ccd7e4e2',
     'rsrc/css/phui/calendar/phui-calendar-month.css' => 'cb758c42',
     'rsrc/css/phui/calendar/phui-calendar.css' => 'f11073aa',
     'rsrc/css/phui/object-item/phui-oi-big-ui.css' => 'fa74cc35',
     'rsrc/css/phui/object-item/phui-oi-color.css' => 'b517bfa0',
     'rsrc/css/phui/object-item/phui-oi-drag-ui.css' => 'da15d3dc',
     'rsrc/css/phui/object-item/phui-oi-flush-ui.css' => '490e2e2e',
     'rsrc/css/phui/object-item/phui-oi-list-view.css' => 'af98a277',
     'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => '6a30fa46',
     'rsrc/css/phui/phui-action-list.css' => '1b0085b2',
     'rsrc/css/phui/phui-action-panel.css' => '6c386cbf',
     'rsrc/css/phui/phui-badge.css' => '666e25ad',
     'rsrc/css/phui/phui-basic-nav-view.css' => '56ebd66d',
     'rsrc/css/phui/phui-big-info-view.css' => '362ad37b',
     'rsrc/css/phui/phui-box.css' => '5ed3b8cb',
     'rsrc/css/phui/phui-bulk-editor.css' => '374d5e30',
     'rsrc/css/phui/phui-chart.css' => 'fe8f87a7',
     'rsrc/css/phui/phui-cms.css' => '8c05c41e',
     'rsrc/css/phui/phui-comment-form.css' => '68a2d99a',
     'rsrc/css/phui/phui-comment-panel.css' => 'ec4e31c0',
     'rsrc/css/phui/phui-crumbs-view.css' => '614f43cf',
     'rsrc/css/phui/phui-curtain-object-ref-view.css' => '51d93266',
     'rsrc/css/phui/phui-curtain-view.css' => '68c5efb6',
     'rsrc/css/phui/phui-document-pro.css' => 'b9613a10',
     'rsrc/css/phui/phui-document-summary.css' => 'b068eed1',
     'rsrc/css/phui/phui-document.css' => '52b748a5',
     'rsrc/css/phui/phui-feed-story.css' => 'a0c05029',
     'rsrc/css/phui/phui-fontkit.css' => '1ec937e5',
     'rsrc/css/phui/phui-form-view.css' => '7536aef9',
     'rsrc/css/phui/phui-form.css' => 'd1adb52c',
     'rsrc/css/phui/phui-formation-view.css' => 'd2dec8ed',
     'rsrc/css/phui/phui-head-thing.css' => 'd7f293df',
     'rsrc/css/phui/phui-header-view.css' => '36c86a58',
     'rsrc/css/phui/phui-hovercard.css' => '6ca90fa0',
     'rsrc/css/phui/phui-icon-set-selector.css' => '7aa5f3ec',
     'rsrc/css/phui/phui-icon.css' => '4cbc684a',
     'rsrc/css/phui/phui-image-mask.css' => '62c7f4d2',
     'rsrc/css/phui/phui-info-view.css' => 'a10a909b',
     'rsrc/css/phui/phui-invisible-character-view.css' => 'c694c4a4',
     'rsrc/css/phui/phui-left-right.css' => '68513c34',
     'rsrc/css/phui/phui-lightbox.css' => '4ebf22da',
     'rsrc/css/phui/phui-list.css' => '0c04affd',
     'rsrc/css/phui/phui-object-box.css' => 'fdffed5c',
     'rsrc/css/phui/phui-pager.css' => 'd022c7ad',
     'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8',
     'rsrc/css/phui/phui-policy-section-view.css' => '139fdc64',
     'rsrc/css/phui/phui-property-list-view.css' => '5adf7078',
     'rsrc/css/phui/phui-remarkup-preview.css' => '91767007',
     'rsrc/css/phui/phui-segment-bar-view.css' => '5166b370',
     'rsrc/css/phui/phui-spacing.css' => 'b05cadc3',
     'rsrc/css/phui/phui-status.css' => '293b5dad',
     'rsrc/css/phui/phui-tag-view.css' => 'fb811341',
-    'rsrc/css/phui/phui-timeline-view.css' => '2d32d7a9',
+    'rsrc/css/phui/phui-timeline-view.css' => 'cc554a79',
     'rsrc/css/phui/phui-two-column-view.css' => 'f96d319f',
     'rsrc/css/phui/workboards/phui-workboard-color.css' => '3a1c21ff',
     'rsrc/css/phui/workboards/phui-workboard.css' => '74fc9d98',
     'rsrc/css/phui/workboards/phui-workcard.css' => '913441b6',
     'rsrc/css/phui/workboards/phui-workpanel.css' => '3ae89b20',
     'rsrc/css/sprite-login.css' => '35d1510c',
     'rsrc/css/sprite-tokens.css' => 'f1896dc5',
     'rsrc/css/syntax/syntax-default.css' => '055fc231',
     'rsrc/externals/d3/d3.min.js' => '9d068042',
     'rsrc/externals/font/fontawesome/fontawesome-webfont.eot' => '23f8c698',
     'rsrc/externals/font/fontawesome/fontawesome-webfont.ttf' => '70983df0',
     'rsrc/externals/font/fontawesome/fontawesome-webfont.woff' => 'cd02f93b',
     'rsrc/externals/font/fontawesome/fontawesome-webfont.woff2' => '351fd46a',
     'rsrc/externals/font/lato/lato-bold.eot' => '7367aa5e',
     'rsrc/externals/font/lato/lato-bold.svg' => '681aa4f5',
     'rsrc/externals/font/lato/lato-bold.ttf' => '66d3c296',
     'rsrc/externals/font/lato/lato-bold.woff' => '89d9fba7',
     'rsrc/externals/font/lato/lato-bold.woff2' => '389fcdb1',
     'rsrc/externals/font/lato/lato-bolditalic.eot' => '03eeb4da',
     'rsrc/externals/font/lato/lato-bolditalic.svg' => 'f56fa11c',
     'rsrc/externals/font/lato/lato-bolditalic.ttf' => '9c3aec21',
     'rsrc/externals/font/lato/lato-bolditalic.woff' => 'bfbd0616',
     'rsrc/externals/font/lato/lato-bolditalic.woff2' => 'bc7d1274',
     'rsrc/externals/font/lato/lato-italic.eot' => '7db5b247',
     'rsrc/externals/font/lato/lato-italic.svg' => 'b1ae496f',
     'rsrc/externals/font/lato/lato-italic.ttf' => '43eed813',
     'rsrc/externals/font/lato/lato-italic.woff' => 'c28975e1',
     'rsrc/externals/font/lato/lato-italic.woff2' => 'fffc0d8c',
     'rsrc/externals/font/lato/lato-regular.eot' => '06e0c291',
     'rsrc/externals/font/lato/lato-regular.svg' => '3ad95f53',
     'rsrc/externals/font/lato/lato-regular.ttf' => 'e2e9c398',
     'rsrc/externals/font/lato/lato-regular.woff' => '0b13d332',
     'rsrc/externals/font/lato/lato-regular.woff2' => '8f846797',
     'rsrc/externals/javelin/core/Event.js' => 'c03f2fb4',
     'rsrc/externals/javelin/core/Stratcom.js' => '0889b835',
     'rsrc/externals/javelin/core/__tests__/event-stop-and-kill.js' => '048472d2',
     'rsrc/externals/javelin/core/__tests__/install.js' => '14a7e671',
     'rsrc/externals/javelin/core/__tests__/stratcom.js' => 'a28464bb',
     'rsrc/externals/javelin/core/__tests__/util.js' => 'e29a4354',
     'rsrc/externals/javelin/core/init.js' => '98e6504a',
     'rsrc/externals/javelin/core/init_node.js' => '16961339',
     'rsrc/externals/javelin/core/install.js' => '5902260c',
     'rsrc/externals/javelin/core/util.js' => 'edb4d8c9',
     'rsrc/externals/javelin/docs/Base.js' => '5a401d7d',
     'rsrc/externals/javelin/docs/onload.js' => 'ee58fb62',
     'rsrc/externals/javelin/ext/fx/Color.js' => '78f811c9',
     'rsrc/externals/javelin/ext/fx/FX.js' => '34450586',
     'rsrc/externals/javelin/ext/reactor/core/DynVal.js' => '202a2e85',
     'rsrc/externals/javelin/ext/reactor/core/Reactor.js' => '1c850a26',
     'rsrc/externals/javelin/ext/reactor/core/ReactorNode.js' => '72960bc1',
     'rsrc/externals/javelin/ext/reactor/core/ReactorNodeCalmer.js' => '225bbb98',
     'rsrc/externals/javelin/ext/reactor/dom/RDOM.js' => '6cfa0008',
     'rsrc/externals/javelin/ext/view/HTMLView.js' => 'f8c4e135',
     'rsrc/externals/javelin/ext/view/View.js' => '289bf236',
     'rsrc/externals/javelin/ext/view/ViewInterpreter.js' => '876506b6',
     'rsrc/externals/javelin/ext/view/ViewPlaceholder.js' => 'a9942052',
     'rsrc/externals/javelin/ext/view/ViewRenderer.js' => '9aae2b66',
     'rsrc/externals/javelin/ext/view/ViewVisitor.js' => '308f9fe4',
     'rsrc/externals/javelin/ext/view/__tests__/HTMLView.js' => '6e50a13f',
     'rsrc/externals/javelin/ext/view/__tests__/View.js' => 'd284be5d',
     'rsrc/externals/javelin/ext/view/__tests__/ViewInterpreter.js' => 'a9f35511',
     'rsrc/externals/javelin/ext/view/__tests__/ViewRenderer.js' => '3a1b81f6',
     'rsrc/externals/javelin/lib/Cookie.js' => '05d290ef',
     'rsrc/externals/javelin/lib/DOM.js' => 'e4c7622a',
     'rsrc/externals/javelin/lib/History.js' => '030b4f7a',
     'rsrc/externals/javelin/lib/JSON.js' => '541f81c3',
     'rsrc/externals/javelin/lib/Leader.js' => '0d2490ce',
     'rsrc/externals/javelin/lib/Mask.js' => '7c4d8998',
     'rsrc/externals/javelin/lib/Quicksand.js' => 'd3799cb4',
     'rsrc/externals/javelin/lib/Request.js' => '84e6891f',
     'rsrc/externals/javelin/lib/Resource.js' => '20514cc2',
     'rsrc/externals/javelin/lib/Routable.js' => '6a18c42e',
     'rsrc/externals/javelin/lib/Router.js' => '32755edb',
     'rsrc/externals/javelin/lib/Scrollbar.js' => 'a43ae2ae',
     'rsrc/externals/javelin/lib/Sound.js' => 'd4cc2d2a',
     'rsrc/externals/javelin/lib/URI.js' => '2e255291',
     'rsrc/externals/javelin/lib/Vector.js' => 'e9c80beb',
     'rsrc/externals/javelin/lib/WebSocket.js' => 'fdc13e4e',
     'rsrc/externals/javelin/lib/Workflow.js' => 'cc1553f3',
     'rsrc/externals/javelin/lib/__tests__/Cookie.js' => 'ca686f71',
     'rsrc/externals/javelin/lib/__tests__/DOM.js' => '4566e249',
     'rsrc/externals/javelin/lib/__tests__/JSON.js' => '710377ae',
     'rsrc/externals/javelin/lib/__tests__/URI.js' => '6fff0c2b',
     'rsrc/externals/javelin/lib/__tests__/behavior.js' => '8426ebeb',
     'rsrc/externals/javelin/lib/behavior.js' => '1b6acc2a',
     'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => '89a1ae3a',
     'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => '0507519c',
     'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => 'a241536a',
     'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '22ee68a5',
     'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => '23387297',
     'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js' => '5a79f6c3',
     'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '8badee71',
     'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => '80bff3af',
     'rsrc/favicons/favicon-16x16.png' => '4c51a03a',
     'rsrc/favicons/mask-icon.svg' => 'db699fe1',
     'rsrc/image/BFCFDA.png' => '74b5c88b',
     'rsrc/image/actions/edit.png' => 'fd987dff',
     'rsrc/image/avatar.png' => '0d17c6c4',
     'rsrc/image/checker_dark.png' => '7fc8fa7b',
     'rsrc/image/checker_light.png' => '3157a202',
     'rsrc/image/checker_lighter.png' => 'c45928c1',
     'rsrc/image/chevron-in.png' => '1aa2f88f',
     'rsrc/image/chevron-out.png' => 'c815e272',
     'rsrc/image/controls/checkbox-checked.png' => '1770d7a0',
     'rsrc/image/controls/checkbox-unchecked.png' => 'e1deba0a',
     'rsrc/image/d5d8e1.png' => '6764616e',
     'rsrc/image/darkload.gif' => '5bd41a89',
     'rsrc/image/divot.png' => '0fbe2453',
     'rsrc/image/examples/hero.png' => '5d8c4b21',
     'rsrc/image/grippy_texture.png' => 'a7d222b5',
     'rsrc/image/icon/fatcow/arrow_branch.png' => '98149d9f',
     'rsrc/image/icon/fatcow/arrow_merge.png' => 'e142f4f8',
     'rsrc/image/icon/fatcow/calendar_edit.png' => '5ff44a08',
     'rsrc/image/icon/fatcow/document_black.png' => 'd3515fa5',
     'rsrc/image/icon/fatcow/flag_blue.png' => '54db2e5c',
     'rsrc/image/icon/fatcow/flag_finish.png' => '2953a51b',
     'rsrc/image/icon/fatcow/flag_ghost.png' => '7d9ada92',
     'rsrc/image/icon/fatcow/flag_green.png' => '010f7161',
     'rsrc/image/icon/fatcow/flag_orange.png' => '6c384ca5',
     'rsrc/image/icon/fatcow/flag_pink.png' => '11ac6b12',
     'rsrc/image/icon/fatcow/flag_purple.png' => 'c4f423a4',
     'rsrc/image/icon/fatcow/flag_red.png' => '9e6d8817',
     'rsrc/image/icon/fatcow/flag_yellow.png' => '906733f4',
     'rsrc/image/icon/fatcow/key_question.png' => 'c10c26db',
     'rsrc/image/icon/fatcow/link.png' => '8edbf327',
     'rsrc/image/icon/fatcow/page_white_edit.png' => '17ef5625',
     'rsrc/image/icon/fatcow/page_white_put.png' => '82430c91',
     'rsrc/image/icon/fatcow/source/conduit.png' => '5b55130c',
     'rsrc/image/icon/fatcow/source/email.png' => '8a32b77f',
     'rsrc/image/icon/fatcow/source/fax.png' => '8bc2a49b',
     'rsrc/image/icon/fatcow/source/mobile.png' => '0a918412',
     'rsrc/image/icon/fatcow/source/tablet.png' => 'fc50b050',
     'rsrc/image/icon/fatcow/source/web.png' => '70433af3',
     'rsrc/image/icon/subscribe.png' => '07ef454e',
     'rsrc/image/icon/tango/attachment.png' => 'bac9032d',
     'rsrc/image/icon/tango/edit.png' => 'e6296206',
     'rsrc/image/icon/tango/go-down.png' => '0b903712',
     'rsrc/image/icon/tango/log.png' => '86b6a6f4',
     'rsrc/image/icon/tango/upload.png' => '3fe6b92d',
     'rsrc/image/icon/unsubscribe.png' => 'db04378a',
     'rsrc/image/lightblue-header.png' => 'e6d483c6',
     'rsrc/image/logo/project-logo.png' => '019d256f',
     'rsrc/image/main_texture.png' => '894d03c4',
     'rsrc/image/menu_texture.png' => '896c9ade',
     'rsrc/image/people/harding.png' => '95b2db63',
     'rsrc/image/people/jefferson.png' => 'e883a3a2',
     'rsrc/image/people/lincoln.png' => 'be2c07c5',
     'rsrc/image/people/mckinley.png' => '6af510a0',
     'rsrc/image/people/taft.png' => 'b15ab07e',
     'rsrc/image/people/user0.png' => '4bc64b40',
     'rsrc/image/people/user1.png' => '8063f445',
     'rsrc/image/people/user2.png' => 'd28246c0',
     'rsrc/image/people/user3.png' => 'fb1ac12d',
     'rsrc/image/people/user4.png' => 'fe4fac8f',
     'rsrc/image/people/user5.png' => '3d07065c',
     'rsrc/image/people/user6.png' => 'e4bd47c8',
     'rsrc/image/people/user7.png' => '71d8fe8b',
     'rsrc/image/people/user8.png' => '85f86bf7',
     'rsrc/image/people/user9.png' => '523db8aa',
     'rsrc/image/people/washington.png' => '86159e68',
     'rsrc/image/phrequent_active.png' => 'de66dc50',
     'rsrc/image/phrequent_inactive.png' => '79c61baf',
     'rsrc/image/resize.png' => '9cc83373',
     'rsrc/image/sprite-login-X2.png' => '269800ec',
     'rsrc/image/sprite-login.png' => 'a843f146',
     'rsrc/image/sprite-tokens-X2.png' => '21621dd9',
     'rsrc/image/sprite-tokens.png' => 'bede2580',
     'rsrc/image/texture/card-gradient.png' => 'e6892cb4',
     'rsrc/image/texture/dark-menu-hover.png' => '390a4fa1',
     'rsrc/image/texture/dark-menu.png' => '542f699c',
     'rsrc/image/texture/grip.png' => 'bc80753a',
     'rsrc/image/texture/panel-header-gradient.png' => '65004dbf',
     'rsrc/image/texture/phlnx-bg.png' => '6c9cd31d',
     'rsrc/image/texture/pholio-background.gif' => '84910bfc',
     'rsrc/image/texture/table_header.png' => '7652d1ad',
     'rsrc/image/texture/table_header_hover.png' => '12ea5236',
     'rsrc/image/texture/table_header_tall.png' => '5cc420c4',
     'rsrc/js/application/aphlict/Aphlict.js' => '022516b4',
     'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => 'e9a2940f',
     'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => '4e61fa88',
     'rsrc/js/application/aphlict/behavior-aphlict-status.js' => 'c3703a16',
     'rsrc/js/application/aphlict/behavior-desktop-notifications-control.js' => '070679fe',
     'rsrc/js/application/calendar/behavior-day-view.js' => '727a5a61',
     'rsrc/js/application/calendar/behavior-event-all-day.js' => '0b1bc990',
     'rsrc/js/application/calendar/behavior-month-view.js' => '158c64e0',
     'rsrc/js/application/config/behavior-reorder-fields.js' => '2539f834',
     'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => 'aec8e38c',
     'rsrc/js/application/conpherence/behavior-conpherence-search.js' => '91befbcc',
     'rsrc/js/application/conpherence/behavior-durable-column.js' => 'fa6f30b2',
     'rsrc/js/application/conpherence/behavior-menu.js' => '8c2ed2bf',
     'rsrc/js/application/conpherence/behavior-participant-pane.js' => '43ba89a2',
     'rsrc/js/application/conpherence/behavior-pontificate.js' => '4ae58b5a',
     'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '5a6f6a06',
     'rsrc/js/application/conpherence/behavior-toggle-widget.js' => '8f959ad0',
     'rsrc/js/application/countdown/timer.js' => '6a162524',
     'rsrc/js/application/daemon/behavior-bulk-job-reload.js' => '3829a3cf',
     'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '9c01e364',
     'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => 'a2ab19be',
     'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '1e413dc9',
     'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => '0116d3e8',
     'rsrc/js/application/diff/DiffChangeset.js' => 'd7d3ba75',
     'rsrc/js/application/diff/DiffChangesetList.js' => 'cc2c5de5',
     'rsrc/js/application/diff/DiffInline.js' => '9c775532',
     'rsrc/js/application/diff/DiffInlineContentState.js' => 'aa51efb4',
     'rsrc/js/application/diff/DiffPathView.js' => '8207abf9',
     'rsrc/js/application/diff/DiffTreeView.js' => '5d83623b',
     'rsrc/js/application/differential/behavior-diff-radios.js' => '925fe8cd',
     'rsrc/js/application/differential/behavior-populate.js' => 'b86ef6c2',
     'rsrc/js/application/diffusion/DiffusionLocateFileSource.js' => '94243d89',
     'rsrc/js/application/diffusion/ExternalEditorLinkEngine.js' => '48a8641f',
     'rsrc/js/application/diffusion/behavior-audit-preview.js' => 'b7b73831',
     'rsrc/js/application/diffusion/behavior-commit-branches.js' => '4b671572',
     'rsrc/js/application/diffusion/behavior-commit-graph.js' => 'ac10c917',
     'rsrc/js/application/diffusion/behavior-locate-file.js' => '87428eb2',
     'rsrc/js/application/diffusion/behavior-pull-lastmodified.js' => 'c715c123',
     'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => '6a85bc5a',
     'rsrc/js/application/drydock/drydock-live-operation-status.js' => '47a0728b',
     'rsrc/js/application/fact/Chart.js' => '52e3ff03',
     'rsrc/js/application/fact/ChartCurtainView.js' => '86954222',
     'rsrc/js/application/fact/ChartFunctionLabel.js' => '81de1dab',
     'rsrc/js/application/files/behavior-document-engine.js' => '243d6c22',
     'rsrc/js/application/files/behavior-icon-composer.js' => '38a6cedb',
     'rsrc/js/application/files/behavior-launch-icon-composer.js' => 'a17b84f1',
     'rsrc/js/application/harbormaster/behavior-harbormaster-log.js' => 'b347a301',
     'rsrc/js/application/herald/HeraldRuleEditor.js' => '2633bef7',
     'rsrc/js/application/herald/PathTypeahead.js' => 'ad486db3',
     'rsrc/js/application/herald/herald-rule-editor.js' => '0922e81d',
     'rsrc/js/application/maniphest/behavior-batch-selector.js' => '139ef688',
     'rsrc/js/application/maniphest/behavior-line-chart.js' => 'ad258e28',
     'rsrc/js/application/maniphest/behavior-list-edit.js' => 'c687e867',
     'rsrc/js/application/owners/OwnersPathEditor.js' => '2a8b62d9',
     'rsrc/js/application/owners/owners-path-editor.js' => 'ff688a7a',
     'rsrc/js/application/passphrase/passphrase-credential-control.js' => '48fe33d0',
     'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => '3eed1f2b',
     'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => '5aa1544e',
     'rsrc/js/application/phortune/behavior-stripe-payment-form.js' => '02cb4398',
     'rsrc/js/application/phortune/behavior-test-payment-form.js' => '4a7fb02b',
     'rsrc/js/application/phortune/phortune-credit-card-form.js' => 'd12d214f',
     'rsrc/js/application/policy/behavior-policy-control.js' => '0eaa33a9',
     'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '9347f172',
     'rsrc/js/application/projects/WorkboardBoard.js' => 'b46d88c5',
     'rsrc/js/application/projects/WorkboardCard.js' => '0392a5d8',
     'rsrc/js/application/projects/WorkboardCardTemplate.js' => '84f82dad',
     'rsrc/js/application/projects/WorkboardColumn.js' => 'c3d24e63',
     'rsrc/js/application/projects/WorkboardController.js' => '7474d31f',
     'rsrc/js/application/projects/WorkboardDropEffect.js' => '8e0aa661',
     'rsrc/js/application/projects/WorkboardHeader.js' => '111bfd2d',
     'rsrc/js/application/projects/WorkboardHeaderTemplate.js' => 'ebe83a6b',
     'rsrc/js/application/projects/WorkboardOrderTemplate.js' => '03e8891f',
     'rsrc/js/application/projects/behavior-project-boards.js' => '58cb6a88',
     'rsrc/js/application/projects/behavior-project-create.js' => '34c53422',
     'rsrc/js/application/projects/behavior-reorder-columns.js' => '8ac32fd9',
     'rsrc/js/application/repository/repository-crossreference.js' => '44d48cd1',
     'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e5bdb730',
     'rsrc/js/application/search/behavior-reorder-queries.js' => 'b86f297f',
     'rsrc/js/application/transactions/behavior-comment-actions.js' => '4dffaeb2',
     'rsrc/js/application/transactions/behavior-reorder-configs.js' => '4842f137',
     'rsrc/js/application/transactions/behavior-reorder-fields.js' => '0ad8d31f',
     'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '8b5c7d65',
     'rsrc/js/application/transactions/behavior-transaction-comment-form.js' => '2bdadf1a',
     'rsrc/js/application/transactions/behavior-transaction-list.js' => '9cec214e',
     'rsrc/js/application/trigger/TriggerRule.js' => '41b7b4f6',
     'rsrc/js/application/trigger/TriggerRuleControl.js' => '5faf27b9',
     'rsrc/js/application/trigger/TriggerRuleEditor.js' => 'b49fd60c',
     'rsrc/js/application/trigger/TriggerRuleType.js' => '4feea7d3',
     'rsrc/js/application/trigger/trigger-rule-editor.js' => '398fdf13',
     'rsrc/js/application/typeahead/behavior-typeahead-browse.js' => '70245195',
     'rsrc/js/application/typeahead/behavior-typeahead-search.js' => '7b139193',
     'rsrc/js/application/uiexample/gesture-example.js' => '242dedd0',
     'rsrc/js/application/uiexample/notification-example.js' => '29819b75',
     'rsrc/js/core/Busy.js' => '5202e831',
     'rsrc/js/core/DragAndDropFileUpload.js' => '4370900d',
     'rsrc/js/core/DraggableList.js' => '0169e425',
     'rsrc/js/core/Favicon.js' => '7930776a',
     'rsrc/js/core/FileUpload.js' => '331676ea',
     'rsrc/js/core/Hovercard.js' => '6199f752',
     'rsrc/js/core/HovercardList.js' => 'de4b4919',
     'rsrc/js/core/KeyboardShortcut.js' => '1a844c06',
     'rsrc/js/core/KeyboardShortcutManager.js' => '81debc48',
     'rsrc/js/core/MultirowRowManager.js' => '5b54c823',
     'rsrc/js/core/Notification.js' => 'a9b91e3f',
     'rsrc/js/core/Prefab.js' => '5793d835',
     'rsrc/js/core/ShapedRequest.js' => '995f5102',
     'rsrc/js/core/TextAreaUtils.js' => 'f340a484',
     'rsrc/js/core/Title.js' => '43bc9360',
     'rsrc/js/core/ToolTip.js' => '83754533',
     'rsrc/js/core/behavior-audio-source.js' => '3dc5ad43',
     'rsrc/js/core/behavior-autofocus.js' => '65bb0011',
     'rsrc/js/core/behavior-badge-view.js' => '92cdd7b6',
     'rsrc/js/core/behavior-bulk-editor.js' => 'aa6d2308',
     'rsrc/js/core/behavior-choose-control.js' => '04f8a1e3',
     'rsrc/js/core/behavior-copy.js' => 'cf32921f',
     'rsrc/js/core/behavior-detect-timezone.js' => '78bc5d94',
     'rsrc/js/core/behavior-device.js' => 'ac2b1e01',
     'rsrc/js/core/behavior-drag-and-drop-textarea.js' => '3277c62d',
     'rsrc/js/core/behavior-fancy-datepicker.js' => 'b545d0a0',
     'rsrc/js/core/behavior-form.js' => '55d7b788',
     'rsrc/js/core/behavior-gesture.js' => 'b58d1a2a',
     'rsrc/js/core/behavior-global-drag-and-drop.js' => '1cab0e9a',
     'rsrc/js/core/behavior-high-security-warning.js' => 'dae2d55b',
     'rsrc/js/core/behavior-history-install.js' => '6a1583a8',
     'rsrc/js/core/behavior-hovercard.js' => '183738e6',
     'rsrc/js/core/behavior-keyboard-pager.js' => '1325b731',
     'rsrc/js/core/behavior-keyboard-shortcuts.js' => '42c44e8b',
     'rsrc/js/core/behavior-lightbox-attachments.js' => '14c7ab36',
     'rsrc/js/core/behavior-line-linker.js' => '0d915ff5',
     'rsrc/js/core/behavior-linked-container.js' => '74446546',
     'rsrc/js/core/behavior-more.js' => '506aa3f4',
     'rsrc/js/core/behavior-object-selector.js' => '98ef467f',
     'rsrc/js/core/behavior-oncopy.js' => 'da8f5259',
     'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => '54262396',
     'rsrc/js/core/behavior-read-only-warning.js' => 'b9109f8f',
     'rsrc/js/core/behavior-redirect.js' => '407ee861',
     'rsrc/js/core/behavior-refresh-csrf.js' => '46116c01',
     'rsrc/js/core/behavior-remarkup-load-image.js' => '202bfa3f',
     'rsrc/js/core/behavior-remarkup-preview.js' => 'd8a86cfb',
     'rsrc/js/core/behavior-reorder-applications.js' => 'aa371860',
     'rsrc/js/core/behavior-reveal-content.js' => 'b105a3a6',
     'rsrc/js/core/behavior-scrollbar.js' => '92388bae',
     'rsrc/js/core/behavior-search-typeahead.js' => '1cb7d027',
     'rsrc/js/core/behavior-select-content.js' => 'e8240b50',
     'rsrc/js/core/behavior-select-on-click.js' => '66365ee2',
     'rsrc/js/core/behavior-setup-check-https.js' => '01384686',
     'rsrc/js/core/behavior-time-typeahead.js' => '5803b9e7',
     'rsrc/js/core/behavior-toggle-class.js' => '32db8374',
     'rsrc/js/core/behavior-tokenizer.js' => '3b4899b0',
     'rsrc/js/core/behavior-tooltip.js' => '73ecc1f8',
     'rsrc/js/core/behavior-user-menu.js' => '60cd9241',
     'rsrc/js/core/behavior-watch-anchor.js' => 'a77e2cbd',
     'rsrc/js/core/behavior-workflow.js' => '9623adc1',
     'rsrc/js/core/darkconsole/DarkLog.js' => '3b869402',
     'rsrc/js/core/darkconsole/DarkMessage.js' => '26cd4b73',
     'rsrc/js/core/darkconsole/behavior-dark-console.js' => '457f4d16',
     'rsrc/js/core/phtize.js' => '2f1db1ed',
     'rsrc/js/phui/behavior-phui-dropdown-menu.js' => '5cf0501a',
     'rsrc/js/phui/behavior-phui-file-upload.js' => 'e150bd50',
     'rsrc/js/phui/behavior-phui-selectable-list.js' => 'b26a41e4',
     'rsrc/js/phui/behavior-phui-submenu.js' => 'b5e9bff9',
     'rsrc/js/phui/behavior-phui-tab-group.js' => '242aa08b',
     'rsrc/js/phui/behavior-phui-timer-control.js' => 'f84bcbf4',
     'rsrc/js/phuix/PHUIXActionListView.js' => 'c68f183f',
     'rsrc/js/phuix/PHUIXActionView.js' => 'a8f573a9',
     'rsrc/js/phuix/PHUIXAutocomplete.js' => '2fbe234d',
     'rsrc/js/phuix/PHUIXButtonView.js' => '55a24e84',
     'rsrc/js/phuix/PHUIXDropdownMenu.js' => 'b557770a',
     'rsrc/js/phuix/PHUIXExample.js' => 'c2c500a7',
     'rsrc/js/phuix/PHUIXFormControl.js' => '38c1f3fb',
     'rsrc/js/phuix/PHUIXFormationColumnView.js' => '4bcc1f78',
     'rsrc/js/phuix/PHUIXFormationFlankView.js' => '6648270a',
     'rsrc/js/phuix/PHUIXFormationView.js' => 'cef53b3e',
     'rsrc/js/phuix/PHUIXIconView.js' => 'a5257c4e',
   ),
   'symbols' => array(
     'almanac-css' => '2e050f4f',
     'aphront-bars' => '4a327b4a',
     'aphront-dark-console-css' => '7f06cda2',
     'aphront-dialog-view-css' => '6f4ea703',
     'aphront-list-filter-view-css' => 'feb64255',
     'aphront-multi-column-view-css' => 'fbc00ba3',
     'aphront-panel-view-css' => '46923d46',
     'aphront-table-view-css' => '0bb61df1',
     'aphront-tokenizer-control-css' => '34e2a838',
     'aphront-tooltip-css' => 'e3f2412f',
     'aphront-typeahead-control-css' => '8779483d',
     'application-search-view-css' => '0f7c06d8',
     'auth-css' => 'c2f23d74',
     'bulk-job-css' => '73af99f5',
     'conduit-api-css' => 'ce2cfc41',
     'config-options-css' => '16c920ae',
     'conpherence-color-css' => 'b17746b0',
     'conpherence-durable-column-view' => '2d57072b',
     'conpherence-header-pane-css' => 'c9a3db8e',
     'conpherence-menu-css' => '67f4680d',
     'conpherence-message-pane-css' => 'd244db1e',
     'conpherence-notification-css' => '6a3d4e58',
     'conpherence-participant-pane-css' => '69e0058a',
     'conpherence-thread-manager' => 'aec8e38c',
     'conpherence-transaction-css' => '3a3f5e7e',
     'd3' => '9d068042',
     'diff-tree-view-css' => 'e2d3e222',
     'differential-changeset-view-css' => 'bf159129',
     'differential-core-view-css' => '7300a73e',
     'differential-revision-add-comment-css' => '7e5900d9',
     'differential-revision-comment-css' => '7dbc8d1d',
     'differential-revision-history-css' => '237a2979',
     'differential-revision-list-css' => '93d2df7d',
     'differential-table-of-contents-css' => 'bba788b9',
     'diffusion-css' => 'e46232d6',
     'diffusion-icons-css' => '23b31a1b',
     'diffusion-readme-css' => 'b68a76e4',
     'diffusion-repository-css' => 'b89e8c6c',
     'diviner-shared-css' => '4bd263b0',
     'font-fontawesome' => '3883938a',
     'font-lato' => '23631304',
     'fuel-grid-css' => '66697240',
     'fuel-handle-list-css' => '2c4cbeca',
     'fuel-map-css' => 'd6e31510',
     'fuel-menu-css' => '21f5d199',
     'global-drag-and-drop-css' => '1d2713a4',
     'harbormaster-css' => 'd98decda',
     'herald-css' => '648d39e2',
     'herald-rule-editor' => '2633bef7',
     'herald-test-css' => '7e7bbdae',
     'inline-comment-summary-css' => '81eb368d',
     'javelin-aphlict' => '022516b4',
     'javelin-behavior' => '1b6acc2a',
     'javelin-behavior-aphlict-dropdown' => 'e9a2940f',
     'javelin-behavior-aphlict-listen' => '4e61fa88',
     'javelin-behavior-aphlict-status' => 'c3703a16',
     'javelin-behavior-aphront-basic-tokenizer' => '3b4899b0',
     'javelin-behavior-aphront-drag-and-drop-textarea' => '3277c62d',
     'javelin-behavior-aphront-form-disable-on-submit' => '55d7b788',
     'javelin-behavior-aphront-more' => '506aa3f4',
     'javelin-behavior-audio-source' => '3dc5ad43',
     'javelin-behavior-audit-preview' => 'b7b73831',
     'javelin-behavior-badge-view' => '92cdd7b6',
     'javelin-behavior-bulk-editor' => 'aa6d2308',
     'javelin-behavior-bulk-job-reload' => '3829a3cf',
     'javelin-behavior-calendar-month-view' => '158c64e0',
     'javelin-behavior-choose-control' => '04f8a1e3',
     'javelin-behavior-comment-actions' => '4dffaeb2',
     'javelin-behavior-config-reorder-fields' => '2539f834',
     'javelin-behavior-conpherence-menu' => '8c2ed2bf',
     'javelin-behavior-conpherence-participant-pane' => '43ba89a2',
     'javelin-behavior-conpherence-pontificate' => '4ae58b5a',
     'javelin-behavior-conpherence-search' => '91befbcc',
     'javelin-behavior-countdown-timer' => '6a162524',
     'javelin-behavior-dark-console' => '457f4d16',
     'javelin-behavior-dashboard-async-panel' => '9c01e364',
     'javelin-behavior-dashboard-move-panels' => 'a2ab19be',
     'javelin-behavior-dashboard-query-panel-select' => '1e413dc9',
     'javelin-behavior-dashboard-tab-panel' => '0116d3e8',
     'javelin-behavior-day-view' => '727a5a61',
     'javelin-behavior-desktop-notifications-control' => '070679fe',
     'javelin-behavior-detect-timezone' => '78bc5d94',
     'javelin-behavior-device' => 'ac2b1e01',
     'javelin-behavior-differential-diff-radios' => '925fe8cd',
     'javelin-behavior-differential-populate' => 'b86ef6c2',
     'javelin-behavior-diffusion-commit-branches' => '4b671572',
     'javelin-behavior-diffusion-commit-graph' => 'ac10c917',
     'javelin-behavior-diffusion-locate-file' => '87428eb2',
     'javelin-behavior-diffusion-pull-lastmodified' => 'c715c123',
     'javelin-behavior-document-engine' => '243d6c22',
     'javelin-behavior-doorkeeper-tag' => '6a85bc5a',
     'javelin-behavior-drydock-live-operation-status' => '47a0728b',
     'javelin-behavior-durable-column' => 'fa6f30b2',
     'javelin-behavior-editengine-reorder-configs' => '4842f137',
     'javelin-behavior-editengine-reorder-fields' => '0ad8d31f',
     'javelin-behavior-event-all-day' => '0b1bc990',
     'javelin-behavior-fancy-datepicker' => 'b545d0a0',
     'javelin-behavior-global-drag-and-drop' => '1cab0e9a',
     'javelin-behavior-harbormaster-log' => 'b347a301',
     'javelin-behavior-herald-rule-editor' => '0922e81d',
     'javelin-behavior-high-security-warning' => 'dae2d55b',
     'javelin-behavior-history-install' => '6a1583a8',
     'javelin-behavior-icon-composer' => '38a6cedb',
     'javelin-behavior-launch-icon-composer' => 'a17b84f1',
     'javelin-behavior-lightbox-attachments' => '14c7ab36',
     'javelin-behavior-line-chart' => 'ad258e28',
     'javelin-behavior-linked-container' => '74446546',
     'javelin-behavior-maniphest-batch-selector' => '139ef688',
     'javelin-behavior-maniphest-list-editor' => 'c687e867',
     'javelin-behavior-owners-path-editor' => 'ff688a7a',
     'javelin-behavior-passphrase-credential-control' => '48fe33d0',
     'javelin-behavior-phabricator-autofocus' => '65bb0011',
     'javelin-behavior-phabricator-clipboard-copy' => 'cf32921f',
     'javelin-behavior-phabricator-gesture' => 'b58d1a2a',
     'javelin-behavior-phabricator-gesture-example' => '242dedd0',
     'javelin-behavior-phabricator-keyboard-pager' => '1325b731',
     'javelin-behavior-phabricator-keyboard-shortcuts' => '42c44e8b',
     'javelin-behavior-phabricator-line-linker' => '0d915ff5',
     'javelin-behavior-phabricator-notification-example' => '29819b75',
     'javelin-behavior-phabricator-object-selector' => '98ef467f',
     'javelin-behavior-phabricator-oncopy' => 'da8f5259',
     'javelin-behavior-phabricator-remarkup-assist' => '54262396',
     'javelin-behavior-phabricator-reveal-content' => 'b105a3a6',
     'javelin-behavior-phabricator-search-typeahead' => '1cb7d027',
     'javelin-behavior-phabricator-show-older-transactions' => '8b5c7d65',
     'javelin-behavior-phabricator-tooltips' => '73ecc1f8',
     'javelin-behavior-phabricator-transaction-comment-form' => '2bdadf1a',
     'javelin-behavior-phabricator-transaction-list' => '9cec214e',
     'javelin-behavior-phabricator-watch-anchor' => 'a77e2cbd',
     'javelin-behavior-pholio-mock-edit' => '3eed1f2b',
     'javelin-behavior-pholio-mock-view' => '5aa1544e',
     'javelin-behavior-phui-dropdown-menu' => '5cf0501a',
     'javelin-behavior-phui-file-upload' => 'e150bd50',
     'javelin-behavior-phui-hovercards' => '183738e6',
     'javelin-behavior-phui-selectable-list' => 'b26a41e4',
     'javelin-behavior-phui-submenu' => 'b5e9bff9',
     'javelin-behavior-phui-tab-group' => '242aa08b',
     'javelin-behavior-phui-timer-control' => 'f84bcbf4',
     'javelin-behavior-phuix-example' => 'c2c500a7',
     'javelin-behavior-policy-control' => '0eaa33a9',
     'javelin-behavior-policy-rule-editor' => '9347f172',
     'javelin-behavior-project-boards' => '58cb6a88',
     'javelin-behavior-project-create' => '34c53422',
     'javelin-behavior-quicksand-blacklist' => '5a6f6a06',
     'javelin-behavior-read-only-warning' => 'b9109f8f',
     'javelin-behavior-redirect' => '407ee861',
     'javelin-behavior-refresh-csrf' => '46116c01',
     'javelin-behavior-remarkup-load-image' => '202bfa3f',
     'javelin-behavior-remarkup-preview' => 'd8a86cfb',
     'javelin-behavior-reorder-applications' => 'aa371860',
     'javelin-behavior-reorder-columns' => '8ac32fd9',
     'javelin-behavior-reorder-profile-menu-items' => 'e5bdb730',
     'javelin-behavior-repository-crossreference' => '44d48cd1',
     'javelin-behavior-scrollbar' => '92388bae',
     'javelin-behavior-search-reorder-queries' => 'b86f297f',
     'javelin-behavior-select-content' => 'e8240b50',
     'javelin-behavior-select-on-click' => '66365ee2',
     'javelin-behavior-setup-check-https' => '01384686',
     'javelin-behavior-stripe-payment-form' => '02cb4398',
     'javelin-behavior-test-payment-form' => '4a7fb02b',
     'javelin-behavior-time-typeahead' => '5803b9e7',
     'javelin-behavior-toggle-class' => '32db8374',
     'javelin-behavior-toggle-widget' => '8f959ad0',
     'javelin-behavior-trigger-rule-editor' => '398fdf13',
     'javelin-behavior-typeahead-browse' => '70245195',
     'javelin-behavior-typeahead-search' => '7b139193',
     'javelin-behavior-user-menu' => '60cd9241',
     'javelin-behavior-view-placeholder' => 'a9942052',
     'javelin-behavior-workflow' => '9623adc1',
     'javelin-chart' => '52e3ff03',
     'javelin-chart-curtain-view' => '86954222',
     'javelin-chart-function-label' => '81de1dab',
     'javelin-color' => '78f811c9',
     'javelin-cookie' => '05d290ef',
     'javelin-diffusion-locate-file-source' => '94243d89',
     'javelin-dom' => 'e4c7622a',
     'javelin-dynval' => '202a2e85',
     'javelin-event' => 'c03f2fb4',
     'javelin-external-editor-link-engine' => '48a8641f',
     'javelin-fx' => '34450586',
     'javelin-history' => '030b4f7a',
     'javelin-install' => '5902260c',
     'javelin-json' => '541f81c3',
     'javelin-leader' => '0d2490ce',
     'javelin-magical-init' => '98e6504a',
     'javelin-mask' => '7c4d8998',
     'javelin-quicksand' => 'd3799cb4',
     'javelin-reactor' => '1c850a26',
     'javelin-reactor-dom' => '6cfa0008',
     'javelin-reactor-node-calmer' => '225bbb98',
     'javelin-reactornode' => '72960bc1',
     'javelin-request' => '84e6891f',
     'javelin-resource' => '20514cc2',
     'javelin-routable' => '6a18c42e',
     'javelin-router' => '32755edb',
     'javelin-scrollbar' => 'a43ae2ae',
     'javelin-sound' => 'd4cc2d2a',
     'javelin-stratcom' => '0889b835',
     'javelin-tokenizer' => '89a1ae3a',
     'javelin-typeahead' => '0507519c',
     'javelin-typeahead-composite-source' => '22ee68a5',
     'javelin-typeahead-normalizer' => 'a241536a',
     'javelin-typeahead-ondemand-source' => '23387297',
     'javelin-typeahead-preloaded-source' => '5a79f6c3',
     'javelin-typeahead-source' => '8badee71',
     'javelin-typeahead-static-source' => '80bff3af',
     'javelin-uri' => '2e255291',
     'javelin-util' => 'edb4d8c9',
     'javelin-vector' => 'e9c80beb',
     'javelin-view' => '289bf236',
     'javelin-view-html' => 'f8c4e135',
     'javelin-view-interpreter' => '876506b6',
     'javelin-view-renderer' => '9aae2b66',
     'javelin-view-visitor' => '308f9fe4',
     'javelin-websocket' => 'fdc13e4e',
     'javelin-workboard-board' => 'b46d88c5',
     'javelin-workboard-card' => '0392a5d8',
     'javelin-workboard-card-template' => '84f82dad',
     'javelin-workboard-column' => 'c3d24e63',
     'javelin-workboard-controller' => '7474d31f',
     'javelin-workboard-drop-effect' => '8e0aa661',
     'javelin-workboard-header' => '111bfd2d',
     'javelin-workboard-header-template' => 'ebe83a6b',
     'javelin-workboard-order-template' => '03e8891f',
     'javelin-workflow' => 'cc1553f3',
     'maniphest-report-css' => '3d53188b',
     'maniphest-task-edit-css' => '272daa84',
     'maniphest-task-summary-css' => '61d1667e',
     'multirow-row-manager' => '5b54c823',
     'owners-path-editor' => '2a8b62d9',
     'owners-path-editor-css' => 'fa7c13ef',
     'paste-css' => 'b37bcd38',
     'path-typeahead' => 'ad486db3',
     'people-picture-menu-item-css' => 'fe8e07cf',
     'people-profile-css' => '2ea2daa1',
     'phabricator-action-list-view-css' => '1b0085b2',
     'phabricator-busy' => '5202e831',
     'phabricator-chatlog-css' => 'abdc76ee',
     'phabricator-content-source-view-css' => 'cdf0d579',
     'phabricator-core-css' => 'a708bd25',
     'phabricator-countdown-css' => 'bff8012f',
     'phabricator-darklog' => '3b869402',
     'phabricator-darkmessage' => '26cd4b73',
     'phabricator-dashboard-css' => '5a205b9d',
     'phabricator-diff-changeset' => 'd7d3ba75',
     'phabricator-diff-changeset-list' => 'cc2c5de5',
     'phabricator-diff-inline' => '9c775532',
     'phabricator-diff-inline-content-state' => 'aa51efb4',
     'phabricator-diff-path-view' => '8207abf9',
     'phabricator-diff-tree-view' => '5d83623b',
     'phabricator-drag-and-drop-file-upload' => '4370900d',
     'phabricator-draggable-list' => '0169e425',
     'phabricator-fatal-config-template-css' => 'e689dbbd',
     'phabricator-favicon' => '7930776a',
     'phabricator-feed-css' => 'd8b6e3f8',
     'phabricator-file-upload' => '331676ea',
     'phabricator-flag-css' => '2b77be8d',
     'phabricator-keyboard-shortcut' => '1a844c06',
     'phabricator-keyboard-shortcut-manager' => '81debc48',
     'phabricator-main-menu-view' => '89fc16b6',
     'phabricator-nav-view-css' => '423f92cc',
     'phabricator-notification' => 'a9b91e3f',
     'phabricator-notification-css' => '30240bd2',
     'phabricator-notification-menu-css' => '4df1ee30',
     'phabricator-object-selector-css' => 'ee77366f',
     'phabricator-phtize' => '2f1db1ed',
     'phabricator-prefab' => '5793d835',
     'phabricator-remarkup-css' => '5baa3bd9',
     'phabricator-search-results-css' => '9ea70ace',
     'phabricator-shaped-request' => '995f5102',
     'phabricator-slowvote-css' => '1694baed',
     'phabricator-source-code-view-css' => '6b31244f',
     'phabricator-standard-page-view' => 'a374f94c',
     'phabricator-textareautils' => 'f340a484',
     'phabricator-title' => '43bc9360',
     'phabricator-tooltip' => '83754533',
     'phabricator-ui-example-css' => 'b4795059',
     'phabricator-zindex-css' => 'ac3bfcd4',
     'phame-css' => 'bb442327',
     'pholio-css' => '88ef5ef1',
     'pholio-edit-css' => '4df55b3b',
     'pholio-inline-comments-css' => '722b48c2',
     'phortune-credit-card-form' => 'd12d214f',
     'phortune-credit-card-form-css' => '3b9868a8',
     'phortune-css' => '508a1a5e',
     'phortune-invoice-css' => '4436b241',
     'phrequent-css' => 'bd79cc67',
     'phriction-document-css' => '03380da0',
     'phui-action-panel-css' => '6c386cbf',
     'phui-badge-view-css' => '666e25ad',
     'phui-basic-nav-view-css' => '56ebd66d',
     'phui-big-info-view-css' => '362ad37b',
     'phui-box-css' => '5ed3b8cb',
     'phui-bulk-editor-css' => '374d5e30',
     'phui-button-bar-css' => 'a4aa75c4',
     'phui-button-css' => 'e434f171',
     'phui-button-simple-css' => '1ff278aa',
     'phui-calendar-css' => 'f11073aa',
     'phui-calendar-day-css' => '9597d706',
     'phui-calendar-list-css' => 'ccd7e4e2',
     'phui-calendar-month-css' => 'cb758c42',
     'phui-chart-css' => 'fe8f87a7',
     'phui-cms-css' => '8c05c41e',
     'phui-comment-form-css' => '68a2d99a',
     'phui-comment-panel-css' => 'ec4e31c0',
     'phui-crumbs-view-css' => '614f43cf',
     'phui-curtain-object-ref-view-css' => '51d93266',
     'phui-curtain-view-css' => '68c5efb6',
     'phui-document-summary-view-css' => 'b068eed1',
     'phui-document-view-css' => '52b748a5',
     'phui-document-view-pro-css' => 'b9613a10',
     'phui-feed-story-css' => 'a0c05029',
     'phui-font-icon-base-css' => '303c9b87',
     'phui-fontkit-css' => '1ec937e5',
     'phui-form-css' => 'd1adb52c',
     'phui-form-view-css' => '7536aef9',
     'phui-formation-view-css' => 'd2dec8ed',
     'phui-head-thing-view-css' => 'd7f293df',
     'phui-header-view-css' => '36c86a58',
     'phui-hovercard' => '6199f752',
     'phui-hovercard-list' => 'de4b4919',
     'phui-hovercard-view-css' => '6ca90fa0',
     'phui-icon-set-selector-css' => '7aa5f3ec',
     'phui-icon-view-css' => '4cbc684a',
     'phui-image-mask-css' => '62c7f4d2',
     'phui-info-view-css' => 'a10a909b',
     'phui-inline-comment-view-css' => 'a864426f',
     'phui-invisible-character-view-css' => 'c694c4a4',
     'phui-left-right-css' => '68513c34',
     'phui-lightbox-css' => '4ebf22da',
     'phui-list-view-css' => '0c04affd',
     'phui-object-box-css' => 'fdffed5c',
     'phui-oi-big-ui-css' => 'fa74cc35',
     'phui-oi-color-css' => 'b517bfa0',
     'phui-oi-drag-ui-css' => 'da15d3dc',
     'phui-oi-flush-ui-css' => '490e2e2e',
     'phui-oi-list-view-css' => 'af98a277',
     'phui-oi-simple-ui-css' => '6a30fa46',
     'phui-pager-css' => 'd022c7ad',
     'phui-pinboard-view-css' => '1f08f5d8',
     'phui-policy-section-view-css' => '139fdc64',
     'phui-property-list-view-css' => '5adf7078',
     'phui-remarkup-preview-css' => '91767007',
     'phui-segment-bar-view-css' => '5166b370',
     'phui-spacing-css' => 'b05cadc3',
     'phui-status-list-view-css' => '293b5dad',
     'phui-tag-view-css' => 'fb811341',
     'phui-theme-css' => '35883b37',
-    'phui-timeline-view-css' => '2d32d7a9',
+    'phui-timeline-view-css' => 'cc554a79',
     'phui-two-column-view-css' => 'f96d319f',
     'phui-workboard-color-css' => '3a1c21ff',
     'phui-workboard-view-css' => '74fc9d98',
     'phui-workcard-view-css' => '913441b6',
     'phui-workpanel-view-css' => '3ae89b20',
     'phuix-action-list-view' => 'c68f183f',
     'phuix-action-view' => 'a8f573a9',
     'phuix-autocomplete' => '2fbe234d',
     'phuix-button-view' => '55a24e84',
     'phuix-dropdown-menu' => 'b557770a',
     'phuix-form-control-view' => '38c1f3fb',
     'phuix-formation-column-view' => '4bcc1f78',
     'phuix-formation-flank-view' => '6648270a',
     'phuix-formation-view' => 'cef53b3e',
     'phuix-icon-view' => 'a5257c4e',
     'policy-css' => 'ceb56a08',
     'policy-edit-css' => '8794e2ed',
     'policy-transaction-detail-css' => 'c02b8384',
     'ponder-view-css' => '05a09d0a',
     'project-card-view-css' => 'c1200da7',
     'project-triggers-css' => 'cd9c8bb9',
     'project-view-css' => '2f7caa20',
     'setup-issue-css' => '5eed85b2',
     'sprite-login-css' => '35d1510c',
     'sprite-tokens-css' => 'f1896dc5',
     'syntax-default-css' => '055fc231',
     'syntax-highlighting-css' => '548567f6',
     'tokens-css' => 'ce5a50bd',
     'trigger-rule' => '41b7b4f6',
     'trigger-rule-control' => '5faf27b9',
     'trigger-rule-editor' => 'b49fd60c',
     'trigger-rule-type' => '4feea7d3',
     'typeahead-browse-css' => 'b7ed02d2',
     'unhandled-exception-css' => '9ecfc00d',
   ),
   'requires' => array(
     '0116d3e8' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-stratcom',
     ),
     '01384686' => array(
       'javelin-behavior',
       'javelin-uri',
       'phabricator-notification',
     ),
     '0169e425' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-util',
       'javelin-vector',
       'javelin-magical-init',
     ),
     '022516b4' => array(
       'javelin-install',
       'javelin-util',
       'javelin-websocket',
       'javelin-leader',
       'javelin-json',
     ),
     '02cb4398' => array(
       'javelin-behavior',
       'javelin-dom',
       'phortune-credit-card-form',
     ),
     '030b4f7a' => array(
       'javelin-stratcom',
       'javelin-install',
       'javelin-uri',
       'javelin-util',
     ),
     '0392a5d8' => array(
       'javelin-install',
     ),
     '03e8891f' => array(
       'javelin-install',
     ),
     '04f8a1e3' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
       'javelin-workflow',
     ),
     '0507519c' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-vector',
       'javelin-util',
     ),
     '05d290ef' => array(
       'javelin-install',
       'javelin-util',
     ),
     '070679fe' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
       'javelin-uri',
       'phabricator-notification',
     ),
     '0889b835' => array(
       'javelin-install',
       'javelin-event',
       'javelin-util',
       'javelin-magical-init',
     ),
     '0922e81d' => array(
       'herald-rule-editor',
       'javelin-behavior',
     ),
     '0ad8d31f' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-dom',
       'phabricator-draggable-list',
     ),
     '0d2490ce' => array(
       'javelin-install',
     ),
     '0d915ff5' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
       'javelin-history',
       'javelin-external-editor-link-engine',
     ),
     '0eaa33a9' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-util',
       'phuix-dropdown-menu',
       'phuix-action-list-view',
       'phuix-action-view',
       'javelin-workflow',
       'phuix-icon-view',
     ),
     '111bfd2d' => array(
       'javelin-install',
     ),
     '1325b731' => array(
       'javelin-behavior',
       'javelin-uri',
       'phabricator-keyboard-shortcut',
     ),
     '139ef688' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-util',
     ),
     '14c7ab36' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
       'javelin-mask',
       'javelin-util',
       'phuix-icon-view',
       'phabricator-busy',
     ),
     '183738e6' => array(
       'javelin-behavior',
       'javelin-behavior-device',
       'javelin-stratcom',
       'javelin-vector',
       'phui-hovercard',
       'phui-hovercard-list',
     ),
     '1a844c06' => array(
       'javelin-install',
       'javelin-util',
       'phabricator-keyboard-shortcut-manager',
     ),
     '1b6acc2a' => array(
       'javelin-magical-init',
       'javelin-util',
     ),
     '1c850a26' => array(
       'javelin-install',
       'javelin-util',
     ),
     '1cab0e9a' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-uri',
       'javelin-mask',
       'phabricator-drag-and-drop-file-upload',
     ),
     '1cb7d027' => array(
       'javelin-behavior',
       'javelin-typeahead-ondemand-source',
       'javelin-typeahead',
       'javelin-dom',
       'javelin-uri',
       'javelin-util',
       'javelin-stratcom',
       'phabricator-prefab',
       'phuix-icon-view',
     ),
     '1e413dc9' => array(
       'javelin-behavior',
       'javelin-dom',
     ),
     '1ff278aa' => array(
       'phui-button-css',
     ),
     '202a2e85' => array(
       'javelin-install',
       'javelin-reactornode',
       'javelin-util',
       'javelin-reactor',
     ),
     '202bfa3f' => array(
       'javelin-behavior',
       'javelin-request',
     ),
     '20514cc2' => array(
       'javelin-util',
       'javelin-uri',
       'javelin-install',
     ),
     '225bbb98' => array(
       'javelin-install',
       'javelin-reactor',
       'javelin-util',
     ),
     '22ee68a5' => array(
       'javelin-install',
       'javelin-typeahead-source',
       'javelin-util',
     ),
     23387297 => array(
       'javelin-install',
       'javelin-util',
       'javelin-request',
       'javelin-typeahead-source',
     ),
     23631304 => array(
       'phui-fontkit-css',
     ),
     '242aa08b' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
     ),
     '242dedd0' => array(
       'javelin-stratcom',
       'javelin-behavior',
       'javelin-vector',
       'javelin-dom',
     ),
     '243d6c22' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-stratcom',
     ),
     '2539f834' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
       'javelin-json',
       'phabricator-draggable-list',
     ),
     '2633bef7' => array(
       'multirow-row-manager',
       'javelin-install',
       'javelin-util',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-json',
       'phabricator-prefab',
     ),
     '289bf236' => array(
       'javelin-install',
       'javelin-util',
     ),
     '29819b75' => array(
       'phabricator-notification',
       'javelin-stratcom',
       'javelin-behavior',
     ),
     '2a8b62d9' => array(
       'multirow-row-manager',
       'javelin-install',
       'path-typeahead',
       'javelin-dom',
       'javelin-util',
       'phabricator-prefab',
       'phuix-form-control-view',
     ),
     '2bdadf1a' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-util',
       'javelin-request',
       'phabricator-shaped-request',
     ),
     '2e255291' => array(
       'javelin-install',
       'javelin-util',
       'javelin-stratcom',
     ),
     '2f1db1ed' => array(
       'javelin-util',
     ),
     '2fbe234d' => array(
       'javelin-install',
       'javelin-dom',
       'phuix-icon-view',
       'phabricator-prefab',
     ),
     '308f9fe4' => array(
       'javelin-install',
       'javelin-util',
     ),
     '32755edb' => array(
       'javelin-install',
       'javelin-util',
     ),
     '3277c62d' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-json',
       'phabricator-drag-and-drop-file-upload',
       'phabricator-textareautils',
     ),
     '32db8374' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
     ),
     '331676ea' => array(
       'javelin-install',
       'javelin-dom',
       'phabricator-notification',
     ),
     34450586 => array(
       'javelin-color',
       'javelin-install',
       'javelin-util',
     ),
     '34c53422' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-workflow',
     ),
     '34e2a838' => array(
       'aphront-typeahead-control-css',
       'phui-tag-view-css',
     ),
     '3829a3cf' => array(
       'javelin-behavior',
       'javelin-uri',
     ),
     '38a6cedb' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-stratcom',
     ),
     '38c1f3fb' => array(
       'javelin-install',
       'javelin-dom',
     ),
     '398fdf13' => array(
       'javelin-behavior',
       'trigger-rule-editor',
       'trigger-rule',
       'trigger-rule-type',
     ),
     '3ae89b20' => array(
       'phui-workcard-view-css',
     ),
     '3b4899b0' => array(
       'javelin-behavior',
       'phabricator-prefab',
     ),
     '3dc5ad43' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-vector',
       'javelin-dom',
     ),
     '3eed1f2b' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
       'javelin-workflow',
       'javelin-quicksand',
       'phabricator-phtize',
       'phabricator-drag-and-drop-file-upload',
       'phabricator-draggable-list',
     ),
     '407ee861' => array(
       'javelin-behavior',
       'javelin-uri',
     ),
     '42c44e8b' => array(
       'javelin-behavior',
       'javelin-workflow',
       'javelin-json',
       'javelin-dom',
       'phabricator-keyboard-shortcut',
     ),
     '4370900d' => array(
       'javelin-install',
       'javelin-util',
       'javelin-request',
       'javelin-dom',
       'javelin-uri',
       'phabricator-file-upload',
     ),
     '43ba89a2' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-util',
       'phabricator-notification',
       'conpherence-thread-manager',
     ),
     '43bc9360' => array(
       'javelin-install',
     ),
     '44d48cd1' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-uri',
     ),
     '457f4d16' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-util',
       'javelin-dom',
       'javelin-request',
       'phabricator-keyboard-shortcut',
       'phabricator-darklog',
       'phabricator-darkmessage',
     ),
     '46116c01' => array(
       'javelin-request',
       'javelin-behavior',
       'javelin-dom',
       'javelin-router',
       'javelin-util',
       'phabricator-busy',
     ),
     '47a0728b' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-request',
     ),
     '4842f137' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-dom',
       'phabricator-draggable-list',
     ),
     '48a8641f' => array(
       'javelin-install',
     ),
     '48fe33d0' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-util',
       'javelin-uri',
     ),
     '490e2e2e' => array(
       'phui-oi-list-view-css',
     ),
     '4a7fb02b' => array(
       'javelin-behavior',
       'javelin-dom',
       'phortune-credit-card-form',
     ),
     '4ae58b5a' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-util',
       'javelin-workflow',
       'javelin-stratcom',
       'conpherence-thread-manager',
     ),
     '4b671572' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-util',
       'javelin-request',
     ),
     '4bcc1f78' => array(
       'javelin-install',
       'javelin-dom',
     ),
     '4dffaeb2' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-dom',
       'phuix-form-control-view',
       'phuix-icon-view',
       'javelin-behavior-phabricator-gesture',
     ),
     '4e61fa88' => array(
       'javelin-behavior',
       'javelin-aphlict',
       'javelin-stratcom',
       'javelin-request',
       'javelin-uri',
       'javelin-dom',
       'javelin-json',
       'javelin-router',
       'javelin-util',
       'javelin-leader',
       'javelin-sound',
       'phabricator-notification',
     ),
     '4feea7d3' => array(
       'trigger-rule-control',
     ),
     '506aa3f4' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
     ),
     '5202e831' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-fx',
     ),
     '52e3ff03' => array(
       'phui-chart-css',
       'd3',
       'javelin-chart-curtain-view',
       'javelin-chart-function-label',
     ),
     '541f81c3' => array(
       'javelin-install',
     ),
     54262396 => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
       'phabricator-phtize',
       'phabricator-textareautils',
       'javelin-workflow',
       'javelin-vector',
       'phuix-autocomplete',
       'javelin-mask',
     ),
     '548567f6' => array(
       'syntax-default-css',
     ),
     '55a24e84' => array(
       'javelin-install',
       'javelin-dom',
     ),
     '55d7b788' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
     ),
     '5793d835' => array(
       'javelin-install',
       'javelin-util',
       'javelin-dom',
       'javelin-typeahead',
       'javelin-tokenizer',
       'javelin-typeahead-preloaded-source',
       'javelin-typeahead-ondemand-source',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-util',
     ),
     '5803b9e7' => array(
       'javelin-behavior',
       'javelin-util',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-vector',
       'javelin-typeahead-static-source',
     ),
     '58cb6a88' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-util',
       'javelin-vector',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-workboard-controller',
       'javelin-workboard-drop-effect',
     ),
     '5902260c' => array(
       'javelin-util',
       'javelin-magical-init',
     ),
     '5a6f6a06' => array(
       'javelin-behavior',
       'javelin-quicksand',
     ),
     '5a79f6c3' => array(
       'javelin-install',
       'javelin-util',
       'javelin-request',
       'javelin-typeahead-source',
     ),
     '5aa1544e' => array(
       'javelin-behavior',
       'javelin-util',
       'javelin-stratcom',
       'javelin-dom',
       'javelin-vector',
       'javelin-magical-init',
       'javelin-request',
       'javelin-history',
       'javelin-workflow',
       'javelin-mask',
       'javelin-behavior-device',
       'phabricator-keyboard-shortcut',
     ),
     '5b54c823' => array(
       'javelin-install',
       'javelin-stratcom',
       'javelin-dom',
       'javelin-util',
     ),
     '5cf0501a' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
       'phuix-dropdown-menu',
     ),
     '5d83623b' => array(
       'javelin-dom',
     ),
     '5faf27b9' => array(
       'phuix-form-control-view',
     ),
     '60cd9241' => array(
       'javelin-behavior',
     ),
     '6199f752' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-vector',
       'javelin-request',
       'javelin-uri',
     ),
     '65bb0011' => array(
       'javelin-behavior',
       'javelin-dom',
     ),
     '66365ee2' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
     ),
     '6648270a' => array(
       'javelin-install',
       'javelin-dom',
     ),
     '6a1583a8' => array(
       'javelin-behavior',
       'javelin-history',
     ),
     '6a162524' => array(
       'javelin-behavior',
       'javelin-dom',
     ),
     '6a18c42e' => array(
       'javelin-install',
     ),
     '6a30fa46' => array(
       'phui-oi-list-view-css',
     ),
     '6a85bc5a' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-json',
       'javelin-workflow',
       'javelin-magical-init',
     ),
     '6cfa0008' => array(
       'javelin-dom',
       'javelin-dynval',
       'javelin-reactor',
       'javelin-reactornode',
       'javelin-install',
       'javelin-util',
     ),
     70245195 => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-dom',
     ),
     '727a5a61' => array(
       'phuix-icon-view',
     ),
     '72960bc1' => array(
       'javelin-install',
       'javelin-reactor',
       'javelin-util',
       'javelin-reactor-node-calmer',
     ),
     '73ecc1f8' => array(
       'javelin-behavior',
       'javelin-behavior-device',
       'javelin-stratcom',
       'phabricator-tooltip',
     ),
     74446546 => array(
       'javelin-behavior',
       'javelin-dom',
     ),
     '7474d31f' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-util',
       'javelin-vector',
       'javelin-stratcom',
       'javelin-workflow',
       'phabricator-drag-and-drop-file-upload',
       'javelin-workboard-board',
     ),
     '78bc5d94' => array(
       'javelin-behavior',
       'javelin-uri',
       'phabricator-notification',
     ),
     '78f811c9' => array(
       'javelin-install',
     ),
     '7930776a' => array(
       'javelin-install',
       'javelin-dom',
     ),
     '7b139193' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-dom',
     ),
     '7c4d8998' => array(
       'javelin-install',
       'javelin-dom',
     ),
     '80bff3af' => array(
       'javelin-install',
       'javelin-typeahead-source',
     ),
     '81debc48' => array(
       'javelin-install',
       'javelin-util',
       'javelin-stratcom',
       'javelin-dom',
       'javelin-vector',
     ),
     '8207abf9' => array(
       'javelin-dom',
     ),
     83754533 => array(
       'javelin-install',
       'javelin-util',
       'javelin-dom',
       'javelin-vector',
     ),
     '84e6891f' => array(
       'javelin-install',
       'javelin-stratcom',
       'javelin-util',
       'javelin-behavior',
       'javelin-json',
       'javelin-dom',
       'javelin-resource',
       'javelin-routable',
     ),
     '84f82dad' => array(
       'javelin-install',
     ),
     '87428eb2' => array(
       'javelin-behavior',
       'javelin-diffusion-locate-file-source',
       'javelin-dom',
       'javelin-typeahead',
       'javelin-uri',
     ),
     '876506b6' => array(
       'javelin-view',
       'javelin-install',
       'javelin-dom',
     ),
     '89a1ae3a' => array(
       'javelin-dom',
       'javelin-util',
       'javelin-stratcom',
       'javelin-install',
     ),
     '89fc16b6' => array(
       'phui-theme-css',
     ),
     '8ac32fd9' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-dom',
       'phabricator-draggable-list',
     ),
     '8b5c7d65' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
       'phabricator-busy',
     ),
     '8badee71' => array(
       'javelin-install',
       'javelin-util',
       'javelin-dom',
       'javelin-typeahead-normalizer',
     ),
     '8c2ed2bf' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-util',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-behavior-device',
       'javelin-history',
       'javelin-vector',
       'javelin-scrollbar',
       'phabricator-title',
       'phabricator-shaped-request',
       'conpherence-thread-manager',
     ),
     '8e0aa661' => array(
       'javelin-install',
       'javelin-dom',
     ),
     '8f959ad0' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-util',
       'javelin-workflow',
       'javelin-stratcom',
     ),
     '91befbcc' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-util',
       'javelin-workflow',
       'javelin-stratcom',
     ),
     '92388bae' => array(
       'javelin-behavior',
       'javelin-scrollbar',
     ),
     '925fe8cd' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
     ),
     '92cdd7b6' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
     ),
     '9347f172' => array(
       'javelin-behavior',
       'multirow-row-manager',
       'javelin-dom',
       'javelin-util',
       'phabricator-prefab',
       'javelin-json',
     ),
     '94243d89' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-typeahead-preloaded-source',
       'javelin-util',
     ),
     '9623adc1' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-dom',
       'javelin-router',
     ),
     '98ef467f' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-request',
       'javelin-util',
     ),
     '995f5102' => array(
       'javelin-install',
       'javelin-util',
       'javelin-request',
       'javelin-router',
     ),
     '9aae2b66' => array(
       'javelin-install',
       'javelin-util',
     ),
     '9c01e364' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-workflow',
     ),
     '9c775532' => array(
       'javelin-dom',
       'phabricator-diff-inline-content-state',
     ),
     '9cec214e' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-dom',
       'javelin-uri',
       'phabricator-textareautils',
     ),
     'a17b84f1' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-workflow',
     ),
     'a241536a' => array(
       'javelin-install',
     ),
     'a2ab19be' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-util',
       'javelin-stratcom',
       'javelin-workflow',
       'phabricator-draggable-list',
     ),
     'a43ae2ae' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-vector',
     ),
     'a4aa75c4' => array(
       'phui-button-css',
       'phui-button-simple-css',
     ),
     'a5257c4e' => array(
       'javelin-install',
       'javelin-dom',
     ),
     'a77e2cbd' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
       'javelin-vector',
     ),
     'a8f573a9' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-util',
     ),
     'a9942052' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-view-renderer',
       'javelin-install',
     ),
     'a9b91e3f' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-util',
       'phabricator-notification-css',
     ),
     'aa371860' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-dom',
       'phabricator-draggable-list',
     ),
     'aa51efb4' => array(
       'javelin-dom',
     ),
     'aa6d2308' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-util',
       'multirow-row-manager',
       'javelin-json',
       'phuix-form-control-view',
     ),
     'ac10c917' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-stratcom',
     ),
     'ac2b1e01' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
       'javelin-vector',
       'javelin-install',
     ),
     'ad258e28' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-chart',
     ),
     'ad486db3' => array(
       'javelin-install',
       'javelin-typeahead',
       'javelin-dom',
       'javelin-request',
       'javelin-typeahead-ondemand-source',
       'javelin-util',
     ),
     'aec8e38c' => array(
       'javelin-dom',
       'javelin-util',
       'javelin-stratcom',
       'javelin-install',
       'javelin-aphlict',
       'javelin-workflow',
       'javelin-router',
       'javelin-behavior-device',
       'javelin-vector',
     ),
     'b105a3a6' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
     ),
     'b26a41e4' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
     ),
     'b347a301' => array(
       'javelin-behavior',
     ),
     'b46d88c5' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-util',
       'javelin-stratcom',
       'javelin-workflow',
       'phabricator-draggable-list',
       'javelin-workboard-column',
       'javelin-workboard-header-template',
       'javelin-workboard-card-template',
       'javelin-workboard-order-template',
     ),
     'b49fd60c' => array(
       'multirow-row-manager',
       'trigger-rule',
     ),
     'b517bfa0' => array(
       'phui-oi-list-view-css',
     ),
     'b545d0a0' => array(
       'javelin-behavior',
       'javelin-util',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-vector',
     ),
     'b557770a' => array(
       'javelin-install',
       'javelin-util',
       'javelin-dom',
       'javelin-vector',
       'javelin-stratcom',
     ),
     'b58d1a2a' => array(
       'javelin-behavior',
       'javelin-behavior-device',
       'javelin-stratcom',
       'javelin-vector',
       'javelin-dom',
       'javelin-magical-init',
     ),
     'b5e9bff9' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
     ),
     'b7b73831' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-util',
       'phabricator-shaped-request',
     ),
     'b86ef6c2' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-stratcom',
       'phabricator-tooltip',
       'phabricator-diff-changeset-list',
       'phabricator-diff-changeset',
       'phuix-formation-view',
     ),
     'b86f297f' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-dom',
       'phabricator-draggable-list',
     ),
     'b9109f8f' => array(
       'javelin-behavior',
       'javelin-uri',
       'phabricator-notification',
     ),
     'bf159129' => array(
       'phui-inline-comment-view-css',
     ),
     'c03f2fb4' => array(
       'javelin-install',
     ),
     'c2c500a7' => array(
       'javelin-install',
       'javelin-dom',
       'phuix-button-view',
     ),
     'c3703a16' => array(
       'javelin-behavior',
       'javelin-aphlict',
       'phabricator-phtize',
       'javelin-dom',
     ),
     'c3d24e63' => array(
       'javelin-install',
       'javelin-workboard-card',
       'javelin-workboard-header',
     ),
     'c687e867' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-fx',
       'javelin-util',
     ),
     'c68f183f' => array(
       'javelin-install',
       'javelin-dom',
     ),
     'c715c123' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-util',
       'javelin-workflow',
       'javelin-json',
     ),
     'cc1553f3' => array(
       'javelin-stratcom',
       'javelin-request',
       'javelin-dom',
       'javelin-vector',
       'javelin-install',
       'javelin-util',
       'javelin-mask',
       'javelin-uri',
       'javelin-routable',
     ),
     'cc2c5de5' => array(
       'javelin-install',
       'phuix-button-view',
       'phabricator-diff-tree-view',
     ),
     'cef53b3e' => array(
       'javelin-install',
       'javelin-dom',
       'phuix-formation-column-view',
       'phuix-formation-flank-view',
     ),
     'cf32921f' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-stratcom',
     ),
     'd12d214f' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-json',
       'javelin-workflow',
       'javelin-util',
     ),
     'd3799cb4' => array(
       'javelin-install',
     ),
     'd4cc2d2a' => array(
       'javelin-install',
     ),
     'd7d3ba75' => array(
       'javelin-dom',
       'javelin-util',
       'javelin-stratcom',
       'javelin-install',
       'javelin-workflow',
       'javelin-router',
       'javelin-behavior-device',
       'javelin-vector',
       'phabricator-diff-inline',
       'phabricator-diff-path-view',
       'phuix-button-view',
       'javelin-external-editor-link-engine',
     ),
     'd8a86cfb' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-util',
       'phabricator-shaped-request',
     ),
     'da15d3dc' => array(
       'phui-oi-list-view-css',
     ),
     'da8f5259' => array(
       'javelin-behavior',
       'javelin-dom',
     ),
     'dae2d55b' => array(
       'javelin-behavior',
       'javelin-uri',
       'phabricator-notification',
     ),
     'de4b4919' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-vector',
       'javelin-request',
       'javelin-uri',
       'phui-hovercard',
     ),
     'e150bd50' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
       'phuix-dropdown-menu',
     ),
     'e4c7622a' => array(
       'javelin-magical-init',
       'javelin-install',
       'javelin-util',
       'javelin-vector',
       'javelin-stratcom',
     ),
     'e5bdb730' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-workflow',
       'javelin-dom',
       'phabricator-draggable-list',
     ),
     'e8240b50' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
     ),
     'e9a2940f' => array(
       'javelin-behavior',
       'javelin-request',
       'javelin-stratcom',
       'javelin-vector',
       'javelin-dom',
       'javelin-uri',
       'javelin-behavior-device',
       'phabricator-title',
       'phabricator-favicon',
     ),
     'e9c80beb' => array(
       'javelin-install',
       'javelin-event',
     ),
     'ebe83a6b' => array(
       'javelin-install',
     ),
     'ec4e31c0' => array(
       'phui-timeline-view-css',
     ),
     'ee77366f' => array(
       'aphront-dialog-view-css',
     ),
     'f340a484' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-vector',
     ),
     'f84bcbf4' => array(
       'javelin-behavior',
       'javelin-stratcom',
       'javelin-dom',
     ),
     'f8c4e135' => array(
       'javelin-install',
       'javelin-dom',
       'javelin-view-visitor',
       'javelin-util',
     ),
     'fa6f30b2' => array(
       'javelin-behavior',
       'javelin-dom',
       'javelin-stratcom',
       'javelin-behavior-device',
       'javelin-scrollbar',
       'javelin-quicksand',
       'phabricator-keyboard-shortcut',
       'conpherence-thread-manager',
     ),
     'fa74cc35' => array(
       'phui-oi-list-view-css',
     ),
     'fdc13e4e' => array(
       'javelin-install',
     ),
     'ff688a7a' => array(
       'owners-path-editor',
       'javelin-behavior',
     ),
   ),
   'packages' => array(
     'conpherence.pkg.css' => array(
       'conpherence-menu-css',
       'conpherence-color-css',
       'conpherence-message-pane-css',
       'conpherence-notification-css',
       'conpherence-transaction-css',
       'conpherence-participant-pane-css',
       'conpherence-header-pane-css',
     ),
     'conpherence.pkg.js' => array(
       'javelin-behavior-conpherence-menu',
       'javelin-behavior-conpherence-participant-pane',
       'javelin-behavior-conpherence-pontificate',
       'javelin-behavior-toggle-widget',
     ),
     'core.pkg.css' => array(
       'phabricator-core-css',
       'phabricator-zindex-css',
       'phui-button-css',
       'phui-button-simple-css',
       'phui-theme-css',
       'phabricator-standard-page-view',
       'aphront-dialog-view-css',
       'phui-form-view-css',
       'aphront-panel-view-css',
       'aphront-table-view-css',
       'aphront-tokenizer-control-css',
       'aphront-typeahead-control-css',
       'aphront-list-filter-view-css',
       'application-search-view-css',
       'phabricator-remarkup-css',
       'syntax-highlighting-css',
       'syntax-default-css',
       'phui-pager-css',
       'aphront-tooltip-css',
       'phabricator-flag-css',
       'phui-info-view-css',
       'phabricator-main-menu-view',
       'phabricator-notification-css',
       'phabricator-notification-menu-css',
       'phui-lightbox-css',
       'phui-comment-panel-css',
       'phui-header-view-css',
       'phabricator-nav-view-css',
       'phui-basic-nav-view-css',
       'phui-crumbs-view-css',
       'phui-oi-list-view-css',
       'phui-oi-color-css',
       'phui-oi-big-ui-css',
       'phui-oi-drag-ui-css',
       'phui-oi-simple-ui-css',
       'phui-oi-flush-ui-css',
       'global-drag-and-drop-css',
       'phui-spacing-css',
       'phui-form-css',
       'phui-icon-view-css',
       'phabricator-action-list-view-css',
       'phui-property-list-view-css',
       'phui-tag-view-css',
       'phui-list-view-css',
       'font-fontawesome',
       'font-lato',
       'phui-font-icon-base-css',
       'phui-fontkit-css',
       'phui-box-css',
       'phui-object-box-css',
       'phui-timeline-view-css',
       'phui-two-column-view-css',
       'phui-curtain-view-css',
       'sprite-login-css',
       'sprite-tokens-css',
       'tokens-css',
       'auth-css',
       'phui-status-list-view-css',
       'phui-feed-story-css',
       'phabricator-feed-css',
       'phabricator-dashboard-css',
       'aphront-multi-column-view-css',
       'phui-curtain-object-ref-view-css',
       'phui-comment-form-css',
       'phui-head-thing-view-css',
       'conpherence-durable-column-view',
       'phui-button-bar-css',
     ),
     'core.pkg.js' => array(
       'javelin-util',
       'javelin-install',
       'javelin-event',
       'javelin-stratcom',
       'javelin-behavior',
       'javelin-resource',
       'javelin-request',
       'javelin-vector',
       'javelin-dom',
       'javelin-json',
       'javelin-uri',
       'javelin-workflow',
       'javelin-mask',
       'javelin-typeahead',
       'javelin-typeahead-normalizer',
       'javelin-typeahead-source',
       'javelin-typeahead-preloaded-source',
       'javelin-typeahead-ondemand-source',
       'javelin-tokenizer',
       'javelin-history',
       'javelin-router',
       'javelin-routable',
       'javelin-behavior-aphront-basic-tokenizer',
       'javelin-behavior-workflow',
       'javelin-behavior-aphront-form-disable-on-submit',
       'phabricator-keyboard-shortcut-manager',
       'phabricator-keyboard-shortcut',
       'javelin-behavior-phabricator-keyboard-shortcuts',
       'javelin-behavior-refresh-csrf',
       'javelin-behavior-phabricator-watch-anchor',
       'javelin-behavior-phabricator-autofocus',
       'phuix-dropdown-menu',
       'phuix-action-list-view',
       'phuix-action-view',
       'phuix-icon-view',
       'phabricator-phtize',
       'javelin-behavior-phabricator-oncopy',
       'phabricator-tooltip',
       'javelin-behavior-phabricator-tooltips',
       'phabricator-prefab',
       'javelin-behavior-device',
       'javelin-behavior-toggle-class',
       'javelin-behavior-lightbox-attachments',
       'phabricator-busy',
       'javelin-sound',
       'javelin-aphlict',
       'phabricator-notification',
       'javelin-behavior-aphlict-listen',
       'javelin-behavior-phabricator-search-typeahead',
       'javelin-behavior-aphlict-dropdown',
       'javelin-behavior-history-install',
       'javelin-behavior-phabricator-gesture',
       'javelin-behavior-phabricator-remarkup-assist',
       'phabricator-textareautils',
       'phabricator-file-upload',
       'javelin-behavior-global-drag-and-drop',
       'javelin-behavior-phabricator-reveal-content',
       'phui-hovercard',
       'phui-hovercard-list',
       'javelin-behavior-phui-hovercards',
       'javelin-color',
       'javelin-fx',
       'phabricator-draggable-list',
       'javelin-behavior-phabricator-transaction-list',
       'javelin-behavior-phabricator-show-older-transactions',
       'javelin-behavior-phui-dropdown-menu',
       'javelin-behavior-doorkeeper-tag',
       'phabricator-title',
       'javelin-leader',
       'javelin-websocket',
       'javelin-behavior-dashboard-async-panel',
       'javelin-behavior-dashboard-tab-panel',
       'javelin-quicksand',
       'javelin-behavior-quicksand-blacklist',
       'javelin-behavior-high-security-warning',
       'javelin-behavior-read-only-warning',
       'javelin-scrollbar',
       'javelin-behavior-scrollbar',
       'javelin-behavior-durable-column',
       'conpherence-thread-manager',
       'javelin-behavior-detect-timezone',
       'javelin-behavior-setup-check-https',
       'javelin-behavior-aphlict-status',
       'javelin-behavior-user-menu',
       'phabricator-favicon',
       'javelin-behavior-phui-tab-group',
       'javelin-behavior-phui-submenu',
       'phuix-button-view',
       'javelin-behavior-comment-actions',
       'phuix-form-control-view',
       'phuix-autocomplete',
     ),
     'dark-console.pkg.js' => array(
       'javelin-behavior-dark-console',
       'phabricator-darklog',
       'phabricator-darkmessage',
     ),
     'differential.pkg.css' => array(
       'differential-core-view-css',
       'differential-changeset-view-css',
       'differential-revision-history-css',
       'differential-revision-list-css',
       'differential-table-of-contents-css',
       'differential-revision-comment-css',
       'differential-revision-add-comment-css',
       'phabricator-object-selector-css',
       'phabricator-content-source-view-css',
       'inline-comment-summary-css',
       'phui-inline-comment-view-css',
       'diff-tree-view-css',
       'phui-formation-view-css',
     ),
     'differential.pkg.js' => array(
       'phabricator-drag-and-drop-file-upload',
       'phabricator-shaped-request',
       'javelin-behavior-differential-populate',
       'javelin-behavior-differential-diff-radios',
       'javelin-behavior-aphront-drag-and-drop-textarea',
       'javelin-behavior-phabricator-object-selector',
       'javelin-behavior-repository-crossreference',
       'javelin-behavior-aphront-more',
       'phabricator-diff-inline-content-state',
       'phabricator-diff-inline',
       'phabricator-diff-changeset',
       'phabricator-diff-changeset-list',
       'phabricator-diff-tree-view',
       'phabricator-diff-path-view',
       'phuix-formation-view',
       'phuix-formation-column-view',
       'phuix-formation-flank-view',
       'javelin-external-editor-link-engine',
     ),
     'diffusion.pkg.css' => array(
       'diffusion-icons-css',
     ),
     'diffusion.pkg.js' => array(
       'javelin-behavior-diffusion-pull-lastmodified',
       'javelin-behavior-diffusion-commit-graph',
       'javelin-behavior-audit-preview',
     ),
     'maniphest.pkg.css' => array(
       'maniphest-task-summary-css',
     ),
     'maniphest.pkg.js' => array(
       'javelin-behavior-maniphest-batch-selector',
       'javelin-behavior-maniphest-list-editor',
     ),
   ),
 );
diff --git a/src/applications/transactions/storage/PhabricatorApplicationTransaction.php b/src/applications/transactions/storage/PhabricatorApplicationTransaction.php
index e32fe92983..56079efaf2 100644
--- a/src/applications/transactions/storage/PhabricatorApplicationTransaction.php
+++ b/src/applications/transactions/storage/PhabricatorApplicationTransaction.php
@@ -1,2036 +1,2036 @@
 <?php
 
 abstract class PhabricatorApplicationTransaction
   extends PhabricatorLiskDAO
   implements
     PhabricatorPolicyInterface,
     PhabricatorDestructibleInterface {
 
   const TARGET_TEXT = 'text';
   const TARGET_HTML = 'html';
 
   protected $phid;
   protected $objectPHID;
   protected $authorPHID;
   protected $viewPolicy;
   protected $editPolicy;
 
   protected $commentPHID;
   protected $commentVersion = 0;
   protected $transactionType;
   protected $oldValue;
   protected $newValue;
   protected $metadata = array();
 
   protected $contentSource;
 
   private $comment;
   private $commentNotLoaded;
 
   private $handles;
   private $renderingTarget = self::TARGET_HTML;
   private $transactionGroup = array();
   private $viewer = self::ATTACHABLE;
   private $object = self::ATTACHABLE;
   private $oldValueHasBeenSet = false;
 
   private $ignoreOnNoEffect;
 
 
   /**
    * Flag this transaction as a pure side-effect which should be ignored when
    * applying transactions if it has no effect, even if transaction application
    * would normally fail. This both provides users with better error messages
    * and allows transactions to perform optional side effects.
    */
   public function setIgnoreOnNoEffect($ignore) {
     $this->ignoreOnNoEffect = $ignore;
     return $this;
   }
 
   public function getIgnoreOnNoEffect() {
     return $this->ignoreOnNoEffect;
   }
 
   public function shouldGenerateOldValue() {
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_TOKEN:
       case PhabricatorTransactions::TYPE_CUSTOMFIELD:
       case PhabricatorTransactions::TYPE_INLINESTATE:
         return false;
     }
     return true;
   }
 
   abstract public function getApplicationTransactionType();
 
   private function getApplicationObjectTypeName() {
     $types = PhabricatorPHIDType::getAllTypes();
 
     $type = idx($types, $this->getApplicationTransactionType());
     if ($type) {
       return $type->getTypeName();
     }
 
     return pht('Object');
   }
 
   public function getApplicationTransactionCommentObject() {
     return null;
   }
 
   public function getMetadataValue($key, $default = null) {
     return idx($this->metadata, $key, $default);
   }
 
   public function setMetadataValue($key, $value) {
     $this->metadata[$key] = $value;
     return $this;
   }
 
   public function generatePHID() {
     $type = PhabricatorApplicationTransactionTransactionPHIDType::TYPECONST;
     $subtype = $this->getApplicationTransactionType();
 
     return PhabricatorPHID::generateNewPHID($type, $subtype);
   }
 
   protected function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_SERIALIZATION => array(
         'oldValue' => self::SERIALIZATION_JSON,
         'newValue' => self::SERIALIZATION_JSON,
         'metadata' => self::SERIALIZATION_JSON,
       ),
       self::CONFIG_COLUMN_SCHEMA => array(
         'commentPHID' => 'phid?',
         'commentVersion' => 'uint32',
         'contentSource' => 'text',
         'transactionType' => 'text32',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_object' => array(
           'columns' => array('objectPHID'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function setContentSource(PhabricatorContentSource $content_source) {
     $this->contentSource = $content_source->serialize();
     return $this;
   }
 
   public function getContentSource() {
     return PhabricatorContentSource::newFromSerialized($this->contentSource);
   }
 
   public function hasComment() {
     $comment = $this->getComment();
     if (!$comment) {
       return false;
     }
 
     if ($comment->isEmptyComment()) {
       return false;
     }
 
     return true;
   }
 
   public function getComment() {
     if ($this->commentNotLoaded) {
       throw new Exception(pht('Comment for this transaction was not loaded.'));
     }
     return $this->comment;
   }
 
   public function setIsCreateTransaction($create) {
     return $this->setMetadataValue('core.create', $create);
   }
 
   public function getIsCreateTransaction() {
     return (bool)$this->getMetadataValue('core.create', false);
   }
 
   public function setIsDefaultTransaction($default) {
     return $this->setMetadataValue('core.default', $default);
   }
 
   public function getIsDefaultTransaction() {
     return (bool)$this->getMetadataValue('core.default', false);
   }
 
   public function setIsSilentTransaction($silent) {
     return $this->setMetadataValue('core.silent', $silent);
   }
 
   public function getIsSilentTransaction() {
     return (bool)$this->getMetadataValue('core.silent', false);
   }
 
   public function setIsMFATransaction($mfa) {
     return $this->setMetadataValue('core.mfa', $mfa);
   }
 
   public function getIsMFATransaction() {
     return (bool)$this->getMetadataValue('core.mfa', false);
   }
 
   public function setIsLockOverrideTransaction($override) {
     return $this->setMetadataValue('core.lock-override', $override);
   }
 
   public function getIsLockOverrideTransaction() {
     return (bool)$this->getMetadataValue('core.lock-override', false);
   }
 
   public function setTransactionGroupID($group_id) {
     return $this->setMetadataValue('core.groupID', $group_id);
   }
 
   public function getTransactionGroupID() {
     return $this->getMetadataValue('core.groupID', null);
   }
 
   public function attachComment(
     PhabricatorApplicationTransactionComment $comment) {
     $this->comment = $comment;
     $this->commentNotLoaded = false;
     return $this;
   }
 
   public function setCommentNotLoaded($not_loaded) {
     $this->commentNotLoaded = $not_loaded;
     return $this;
   }
 
   public function attachObject($object) {
     $this->object = $object;
     return $this;
   }
 
   public function getObject() {
     return $this->assertAttached($this->object);
   }
 
   public function getRemarkupChanges() {
     $changes = $this->newRemarkupChanges();
     assert_instances_of($changes, 'PhabricatorTransactionRemarkupChange');
 
     // Convert older-style remarkup blocks into newer-style remarkup changes.
     // This builds changes that do not have the correct "old value", so rules
     // that operate differently against edits (like @user mentions) won't work
     // properly.
     foreach ($this->getRemarkupBlocks() as $block) {
       $changes[] = $this->newRemarkupChange()
         ->setOldValue(null)
         ->setNewValue($block);
     }
 
     $comment = $this->getComment();
     if ($comment) {
       if ($comment->hasOldComment()) {
         $old_value = $comment->getOldComment()->getContent();
       } else {
         $old_value = null;
       }
 
       $new_value = $comment->getContent();
 
       $changes[] = $this->newRemarkupChange()
         ->setOldValue($old_value)
         ->setNewValue($new_value);
     }
 
     $metadata = $this->getMetadataValue('remarkup.control');
 
     if (!is_array($metadata)) {
       $metadata = array();
     }
 
     foreach ($changes as $change) {
       if (!$change->getMetadata()) {
         $change->setMetadata($metadata);
       }
     }
 
     return $changes;
   }
 
   protected function newRemarkupChanges() {
     return array();
   }
 
   protected function newRemarkupChange() {
     return id(new PhabricatorTransactionRemarkupChange())
       ->setTransaction($this);
   }
 
   /**
    * @deprecated
    */
   public function getRemarkupBlocks() {
     $blocks = array();
 
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_CUSTOMFIELD:
         $field = $this->getTransactionCustomField();
         if ($field) {
           $custom_blocks = $field->getApplicationTransactionRemarkupBlocks(
             $this);
           foreach ($custom_blocks as $custom_block) {
             $blocks[] = $custom_block;
           }
         }
         break;
     }
 
     return $blocks;
   }
 
   public function setOldValue($value) {
     $this->oldValueHasBeenSet = true;
     $this->writeField('oldValue', $value);
     return $this;
   }
 
   public function hasOldValue() {
     return $this->oldValueHasBeenSet;
   }
 
   public function newChronologicalSortVector() {
     return id(new PhutilSortVector())
       ->addInt((int)$this->getDateCreated())
       ->addInt((int)$this->getID());
   }
 
 /* -(  Rendering  )---------------------------------------------------------- */
 
   public function setRenderingTarget($rendering_target) {
     $this->renderingTarget = $rendering_target;
     return $this;
   }
 
   public function getRenderingTarget() {
     return $this->renderingTarget;
   }
 
   public function attachViewer(PhabricatorUser $viewer) {
     $this->viewer = $viewer;
     return $this;
   }
 
   public function getViewer() {
     return $this->assertAttached($this->viewer);
   }
 
   public function getRequiredHandlePHIDs() {
     $phids = array();
 
     $old = $this->getOldValue();
     $new = $this->getNewValue();
 
     $phids[] = array($this->getAuthorPHID());
     $phids[] = array($this->getObjectPHID());
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_CUSTOMFIELD:
         $field = $this->getTransactionCustomField();
         if ($field) {
           $phids[] = $field->getApplicationTransactionRequiredHandlePHIDs(
             $this);
         }
         break;
       case PhabricatorTransactions::TYPE_SUBSCRIBERS:
         $phids[] = $old;
         $phids[] = $new;
         break;
       case PhabricatorTransactions::TYPE_FILE:
         $phids[] = array_keys($old + $new);
         break;
       case PhabricatorTransactions::TYPE_EDGE:
         $record = PhabricatorEdgeChangeRecord::newFromTransaction($this);
         $phids[] = $record->getChangedPHIDs();
         break;
       case PhabricatorTransactions::TYPE_COLUMNS:
         foreach ($new as $move) {
           $phids[] = array(
             $move['columnPHID'],
             $move['boardPHID'],
           );
           $phids[] = $move['fromColumnPHIDs'];
         }
         break;
       case PhabricatorTransactions::TYPE_EDIT_POLICY:
       case PhabricatorTransactions::TYPE_VIEW_POLICY:
       case PhabricatorTransactions::TYPE_JOIN_POLICY:
       case PhabricatorTransactions::TYPE_INTERACT_POLICY:
         if (!PhabricatorPolicyQuery::isSpecialPolicy($old)) {
           $phids[] = array($old);
         }
         if (!PhabricatorPolicyQuery::isSpecialPolicy($new)) {
           $phids[] = array($new);
         }
         break;
       case PhabricatorTransactions::TYPE_SPACE:
         if ($old) {
           $phids[] = array($old);
         }
         if ($new) {
           $phids[] = array($new);
         }
         break;
       case PhabricatorTransactions::TYPE_TOKEN:
         break;
     }
 
     if ($this->getComment()) {
       $phids[] = array($this->getComment()->getAuthorPHID());
     }
 
     return array_mergev($phids);
   }
 
   public function setHandles(array $handles) {
     $this->handles = $handles;
     return $this;
   }
 
   public function getHandle($phid) {
     if (empty($this->handles[$phid])) {
       throw new Exception(
         pht(
           'Transaction ("%s", of type "%s") requires a handle ("%s") that it '.
           'did not load.',
           $this->getPHID(),
           $this->getTransactionType(),
           $phid));
     }
     return $this->handles[$phid];
   }
 
   public function getHandleIfExists($phid) {
     return idx($this->handles, $phid);
   }
 
   public function getHandles() {
     if ($this->handles === null) {
       throw new Exception(
         pht('Transaction requires handles and it did not load them.'));
     }
     return $this->handles;
   }
 
   public function renderHandleLink($phid) {
     if ($this->renderingTarget == self::TARGET_HTML) {
       return $this->getHandle($phid)->renderHovercardLink();
     } else {
       return $this->getHandle($phid)->getLinkName();
     }
   }
 
   public function renderHandleList(array $phids) {
     $links = array();
     foreach ($phids as $phid) {
       $links[] = $this->renderHandleLink($phid);
     }
     if ($this->renderingTarget == self::TARGET_HTML) {
       return phutil_implode_html(', ', $links);
     } else {
       return implode(', ', $links);
     }
   }
 
   private function renderSubscriberList(array $phids, $change_type) {
     if ($this->getRenderingTarget() == self::TARGET_TEXT) {
       return $this->renderHandleList($phids);
     } else {
       $handles = array_select_keys($this->getHandles(), $phids);
       return id(new SubscriptionListStringBuilder())
         ->setHandles($handles)
         ->setObjectPHID($this->getPHID())
         ->buildTransactionString($change_type);
     }
   }
 
   protected function renderPolicyName($phid, $state = 'old') {
     $policy = PhabricatorPolicy::newFromPolicyAndHandle(
       $phid,
       $this->getHandleIfExists($phid));
 
     $ref = $policy->newRef($this->getViewer());
 
     if ($this->renderingTarget == self::TARGET_HTML) {
       $output = $ref->newTransactionLink($state, $this);
     } else {
       $output = $ref->getPolicyDisplayName();
     }
 
     return $output;
   }
 
   public function getIcon() {
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_COMMENT:
         $comment = $this->getComment();
         if ($comment && $comment->getIsRemoved()) {
           return 'fa-trash';
         }
         return 'fa-comment';
       case PhabricatorTransactions::TYPE_SUBSCRIBERS:
         $old = $this->getOldValue();
         $new = $this->getNewValue();
         $add = array_diff($new, $old);
         $rem = array_diff($old, $new);
         if ($add && $rem) {
           return 'fa-user';
         } else if ($add) {
           return 'fa-user-plus';
         } else if ($rem) {
           return 'fa-user-times';
         } else {
           return 'fa-user';
         }
       case PhabricatorTransactions::TYPE_VIEW_POLICY:
       case PhabricatorTransactions::TYPE_EDIT_POLICY:
       case PhabricatorTransactions::TYPE_JOIN_POLICY:
       case PhabricatorTransactions::TYPE_INTERACT_POLICY:
         return 'fa-lock';
       case PhabricatorTransactions::TYPE_EDGE:
         switch ($this->getMetadataValue('edge:type')) {
           case DiffusionCommitRevertedByCommitEdgeType::EDGECONST:
             return 'fa-undo';
           case DiffusionCommitRevertsCommitEdgeType::EDGECONST:
             return 'fa-ambulance';
         }
         return 'fa-link';
       case PhabricatorTransactions::TYPE_TOKEN:
         return 'fa-trophy';
       case PhabricatorTransactions::TYPE_SPACE:
         return 'fa-th-large';
       case PhabricatorTransactions::TYPE_COLUMNS:
         return 'fa-columns';
       case PhabricatorTransactions::TYPE_MFA:
         return 'fa-vcard';
     }
 
     return 'fa-pencil';
   }
 
   public function getToken() {
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_TOKEN:
         $old = $this->getOldValue();
         $new = $this->getNewValue();
         if ($new) {
           $icon = substr($new, 10);
         } else {
           $icon = substr($old, 10);
         }
         return array($icon, !$this->getNewValue());
     }
 
     return array(null, null);
   }
 
   public function getColor() {
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_COMMENT;
         $comment = $this->getComment();
         if ($comment && $comment->getIsRemoved()) {
-          return 'black';
+          return 'grey';
         }
         break;
       case PhabricatorTransactions::TYPE_EDGE:
         switch ($this->getMetadataValue('edge:type')) {
           case DiffusionCommitRevertedByCommitEdgeType::EDGECONST:
             return 'pink';
           case DiffusionCommitRevertsCommitEdgeType::EDGECONST:
             return 'sky';
         }
         break;
       case PhabricatorTransactions::TYPE_MFA;
         return 'pink';
     }
     return null;
   }
 
   protected function getTransactionCustomField() {
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_CUSTOMFIELD:
         $key = $this->getMetadataValue('customfield:key');
         if (!$key) {
           return null;
         }
 
         $object = $this->getObject();
 
         if (!($object instanceof PhabricatorCustomFieldInterface)) {
           return null;
         }
 
         $field = PhabricatorCustomField::getObjectField(
           $object,
           PhabricatorCustomField::ROLE_APPLICATIONTRANSACTIONS,
           $key);
         if (!$field) {
           return null;
         }
 
         $field->setViewer($this->getViewer());
         return $field;
     }
 
     return null;
   }
 
   public function shouldHide() {
     // Never hide comments.
     if ($this->hasComment()) {
       return false;
     }
 
     $xaction_type = $this->getTransactionType();
 
     // Always hide requests for object history.
     if ($xaction_type === PhabricatorTransactions::TYPE_HISTORY) {
       return true;
     }
 
     // Always hide file attach/detach transactions.
     if ($xaction_type === PhabricatorTransactions::TYPE_FILE) {
       if ($this->getMetadataValue('attach.implicit')) {
         return true;
       }
     }
 
     // Hide creation transactions if the old value is empty. These are
     // transactions like "alice set the task title to: ...", which are
     // essentially never interesting.
     if ($this->getIsCreateTransaction()) {
       switch ($xaction_type) {
         case PhabricatorTransactions::TYPE_CREATE:
         case PhabricatorTransactions::TYPE_VIEW_POLICY:
         case PhabricatorTransactions::TYPE_EDIT_POLICY:
         case PhabricatorTransactions::TYPE_JOIN_POLICY:
         case PhabricatorTransactions::TYPE_INTERACT_POLICY:
         case PhabricatorTransactions::TYPE_SPACE:
           break;
         case PhabricatorTransactions::TYPE_SUBTYPE:
           return true;
         default:
           $old = $this->getOldValue();
 
           if (is_array($old) && !$old) {
             return true;
           }
 
           if (!is_array($old)) {
             if ($old === '' || $old === null) {
               return true;
             }
 
             // The integer 0 is also uninteresting by default; this is often
             // an "off" flag for something like "All Day Event".
             if ($old === 0) {
               return true;
             }
           }
 
           break;
       }
     }
 
     // Hide creation transactions setting values to defaults, even if
     // the old value is not empty. For example, tasks may have a global
     // default view policy of "All Users", but a particular form sets the
     // policy to "Administrators". The transaction corresponding to this
     // change is not interesting, since it is the default behavior of the
     // form.
 
     if ($this->getIsCreateTransaction()) {
       if ($this->getIsDefaultTransaction()) {
         return true;
       }
     }
 
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_VIEW_POLICY:
       case PhabricatorTransactions::TYPE_EDIT_POLICY:
       case PhabricatorTransactions::TYPE_JOIN_POLICY:
       case PhabricatorTransactions::TYPE_INTERACT_POLICY:
       case PhabricatorTransactions::TYPE_SPACE:
         if ($this->getIsCreateTransaction()) {
           break;
         }
 
         // TODO: Remove this eventually, this is handling old changes during
         // object creation prior to the introduction of "create" and "default"
         // transaction display flags.
 
         // NOTE: We can also hit this case with Space transactions that later
         // update a default space (`null`) to an explicit space, so handling
         // the Space case may require some finesse.
 
         if ($this->getOldValue() === null) {
           return true;
         } else {
           return false;
         }
         break;
       case PhabricatorTransactions::TYPE_CUSTOMFIELD:
         $field = $this->getTransactionCustomField();
         if ($field) {
           return $field->shouldHideInApplicationTransactions($this);
         }
         break;
       case PhabricatorTransactions::TYPE_COLUMNS:
         return !$this->getInterestingMoves($this->getNewValue());
       case PhabricatorTransactions::TYPE_EDGE:
         $edge_type = $this->getMetadataValue('edge:type');
         switch ($edge_type) {
           case PhabricatorObjectMentionsObjectEdgeType::EDGECONST:
           case ManiphestTaskHasDuplicateTaskEdgeType::EDGECONST:
           case ManiphestTaskIsDuplicateOfTaskEdgeType::EDGECONST:
           case PhabricatorMutedEdgeType::EDGECONST:
           case PhabricatorMutedByEdgeType::EDGECONST:
             return true;
           case PhabricatorObjectMentionedByObjectEdgeType::EDGECONST:
             $record = PhabricatorEdgeChangeRecord::newFromTransaction($this);
             $add = $record->getAddedPHIDs();
             $add_value = reset($add);
             $add_handle = $this->getHandle($add_value);
             if ($add_handle->getPolicyFiltered()) {
               return true;
             }
             return false;
             break;
           default:
             break;
         }
         break;
 
       case PhabricatorTransactions::TYPE_INLINESTATE:
         list($done, $undone) = $this->getInterestingInlineStateChangeCounts();
 
         if (!$done && !$undone) {
           return true;
         }
 
         break;
 
     }
 
     return false;
   }
 
   public function shouldHideForMail(array $xactions) {
     if ($this->isSelfSubscription()) {
       return true;
     }
 
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_TOKEN:
         return true;
       case PhabricatorTransactions::TYPE_EDGE:
         $edge_type = $this->getMetadataValue('edge:type');
         switch ($edge_type) {
           case PhabricatorObjectMentionsObjectEdgeType::EDGECONST:
           case PhabricatorObjectMentionedByObjectEdgeType::EDGECONST:
           case DifferentialRevisionDependsOnRevisionEdgeType::EDGECONST:
           case DifferentialRevisionDependedOnByRevisionEdgeType::EDGECONST:
           case ManiphestTaskHasCommitEdgeType::EDGECONST:
           case DiffusionCommitHasTaskEdgeType::EDGECONST:
           case DiffusionCommitHasRevisionEdgeType::EDGECONST:
           case DifferentialRevisionHasCommitEdgeType::EDGECONST:
             return true;
           case PhabricatorProjectObjectHasProjectEdgeType::EDGECONST:
             // When an object is first created, we hide any corresponding
             // project transactions in the web UI because you can just look at
             // the UI element elsewhere on screen to see which projects it
             // is tagged with. However, in mail there's no other way to get
             // this information, and it has some amount of value to users, so
             // we keep the transaction. See T10493.
             return false;
           default:
             break;
         }
         break;
     }
 
     if ($this->isInlineCommentTransaction()) {
       $inlines = array();
 
       // If there's a normal comment, we don't need to publish the inline
       // transaction, since the normal comment covers things.
       foreach ($xactions as $xaction) {
         if ($xaction->isInlineCommentTransaction()) {
           $inlines[] = $xaction;
           continue;
         }
 
         // We found a normal comment, so hide this inline transaction.
         if ($xaction->hasComment()) {
           return true;
         }
       }
 
       // If there are several inline comments, only publish the first one.
       if ($this !== head($inlines)) {
         return true;
       }
     }
 
     return $this->shouldHide();
   }
 
   public function shouldHideForFeed() {
     if ($this->isSelfSubscription()) {
       return true;
     }
 
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_TOKEN:
       case PhabricatorTransactions::TYPE_MFA:
         return true;
       case PhabricatorTransactions::TYPE_SUBSCRIBERS:
         // See T8952. When an application (usually Herald) modifies
         // subscribers, this tends to be very uninteresting.
         if ($this->isApplicationAuthor()) {
           return true;
         }
         break;
       case PhabricatorTransactions::TYPE_EDGE:
         $edge_type = $this->getMetadataValue('edge:type');
         switch ($edge_type) {
           case PhabricatorObjectMentionsObjectEdgeType::EDGECONST:
           case PhabricatorObjectMentionedByObjectEdgeType::EDGECONST:
           case DifferentialRevisionDependsOnRevisionEdgeType::EDGECONST:
           case DifferentialRevisionDependedOnByRevisionEdgeType::EDGECONST:
           case ManiphestTaskHasCommitEdgeType::EDGECONST:
           case DiffusionCommitHasTaskEdgeType::EDGECONST:
           case DiffusionCommitHasRevisionEdgeType::EDGECONST:
           case DifferentialRevisionHasCommitEdgeType::EDGECONST:
             return true;
           default:
             break;
         }
         break;
      case PhabricatorTransactions::TYPE_INLINESTATE:
        return true;
     }
 
     return $this->shouldHide();
   }
 
   public function shouldHideForNotifications() {
     return $this->shouldHideForFeed();
   }
 
   private function getTitleForMailWithRenderingTarget($new_target) {
     $old_target = $this->getRenderingTarget();
     try {
       $this->setRenderingTarget($new_target);
       $result = $this->getTitleForMail();
     } catch (Exception $ex) {
       $this->setRenderingTarget($old_target);
       throw $ex;
     }
     $this->setRenderingTarget($old_target);
     return $result;
   }
 
   public function getTitleForMail() {
     return $this->getTitle();
   }
 
   public function getTitleForTextMail() {
     return $this->getTitleForMailWithRenderingTarget(self::TARGET_TEXT);
   }
 
   public function getTitleForHTMLMail() {
     // TODO: For now, rendering this with TARGET_HTML generates links with
     // bad targets ("/x/y/" instead of "https://dev.example.com/x/y/"). Throw
     // a rug over the issue for the moment. See T12921.
 
     $title = $this->getTitleForMailWithRenderingTarget(self::TARGET_TEXT);
     if ($title === null) {
       return null;
     }
 
     if ($this->hasChangeDetails()) {
       $details_uri = $this->getChangeDetailsURI();
       $details_uri = PhabricatorEnv::getProductionURI($details_uri);
 
       $show_details = phutil_tag(
         'a',
         array(
           'href' => $details_uri,
         ),
         pht('(Show Details)'));
 
       $title = array($title, ' ', $show_details);
     }
 
     return $title;
   }
 
   public function getChangeDetailsURI() {
     return '/transactions/detail/'.$this->getPHID().'/';
   }
 
   public function getBodyForMail() {
     if ($this->isInlineCommentTransaction()) {
       // We don't return inline comment content as mail body content, because
       // applications need to contextualize it (by adding line numbers, for
       // example) in order for it to make sense.
       return null;
     }
 
     $comment = $this->getComment();
     if ($comment && strlen($comment->getContent())) {
       return $comment->getContent();
     }
 
     return null;
   }
 
   public function getNoEffectDescription() {
 
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_COMMENT:
         return pht('You can not post an empty comment.');
       case PhabricatorTransactions::TYPE_VIEW_POLICY:
         return pht(
           'This %s already has that view policy.',
           $this->getApplicationObjectTypeName());
       case PhabricatorTransactions::TYPE_EDIT_POLICY:
         return pht(
           'This %s already has that edit policy.',
           $this->getApplicationObjectTypeName());
       case PhabricatorTransactions::TYPE_JOIN_POLICY:
         return pht(
           'This %s already has that join policy.',
           $this->getApplicationObjectTypeName());
       case PhabricatorTransactions::TYPE_INTERACT_POLICY:
         return pht(
           'This %s already has that interact policy.',
           $this->getApplicationObjectTypeName());
       case PhabricatorTransactions::TYPE_SUBSCRIBERS:
         return pht(
           'All users are already subscribed to this %s.',
           $this->getApplicationObjectTypeName());
       case PhabricatorTransactions::TYPE_SPACE:
         return pht('This object is already in that space.');
       case PhabricatorTransactions::TYPE_EDGE:
         return pht('Edges already exist; transaction has no effect.');
       case PhabricatorTransactions::TYPE_COLUMNS:
         return pht(
           'You have not moved this object to any columns it is not '.
           'already in.');
       case PhabricatorTransactions::TYPE_MFA:
         return pht(
           'You can not sign a transaction group that has no other '.
           'effects.');
     }
 
     return pht(
       'Transaction (of type "%s") has no effect.',
       $this->getTransactionType());
   }
 
   public function getTitle() {
     $author_phid = $this->getAuthorPHID();
 
     $old = $this->getOldValue();
     $new = $this->getNewValue();
 
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_CREATE:
         return pht(
           '%s created this object.',
           $this->renderHandleLink($author_phid));
       case PhabricatorTransactions::TYPE_COMMENT:
         return pht(
           '%s added a comment.',
           $this->renderHandleLink($author_phid));
       case PhabricatorTransactions::TYPE_VIEW_POLICY:
         if ($this->getIsCreateTransaction()) {
           return pht(
             '%s created this object with visibility "%s".',
             $this->renderHandleLink($author_phid),
             $this->renderPolicyName($new, 'new'));
         } else {
           return pht(
             '%s changed the visibility from "%s" to "%s".',
             $this->renderHandleLink($author_phid),
             $this->renderPolicyName($old, 'old'),
             $this->renderPolicyName($new, 'new'));
         }
       case PhabricatorTransactions::TYPE_EDIT_POLICY:
         if ($this->getIsCreateTransaction()) {
           return pht(
             '%s created this object with edit policy "%s".',
             $this->renderHandleLink($author_phid),
             $this->renderPolicyName($new, 'new'));
         } else {
           return pht(
             '%s changed the edit policy from "%s" to "%s".',
             $this->renderHandleLink($author_phid),
             $this->renderPolicyName($old, 'old'),
             $this->renderPolicyName($new, 'new'));
         }
       case PhabricatorTransactions::TYPE_JOIN_POLICY:
         if ($this->getIsCreateTransaction()) {
           return pht(
             '%s created this object with join policy "%s".',
             $this->renderHandleLink($author_phid),
             $this->renderPolicyName($new, 'new'));
         } else {
           return pht(
             '%s changed the join policy from "%s" to "%s".',
             $this->renderHandleLink($author_phid),
             $this->renderPolicyName($old, 'old'),
             $this->renderPolicyName($new, 'new'));
         }
       case PhabricatorTransactions::TYPE_INTERACT_POLICY:
         if ($this->getIsCreateTransaction()) {
           return pht(
             '%s created this object with interact policy "%s".',
             $this->renderHandleLink($author_phid),
             $this->renderPolicyName($new, 'new'));
         } else {
           return pht(
             '%s changed the interact policy from "%s" to "%s".',
             $this->renderHandleLink($author_phid),
             $this->renderPolicyName($old, 'old'),
             $this->renderPolicyName($new, 'new'));
         }
       case PhabricatorTransactions::TYPE_SPACE:
         if ($this->getIsCreateTransaction()) {
           return pht(
             '%s created this object in space %s.',
             $this->renderHandleLink($author_phid),
             $this->renderHandleLink($new));
         } else {
           return pht(
             '%s shifted this object from the %s space to the %s space.',
             $this->renderHandleLink($author_phid),
             $this->renderHandleLink($old),
             $this->renderHandleLink($new));
         }
       case PhabricatorTransactions::TYPE_SUBSCRIBERS:
         $add = array_diff($new, $old);
         $rem = array_diff($old, $new);
 
         if ($add && $rem) {
           return pht(
             '%s edited subscriber(s), added %d: %s; removed %d: %s.',
             $this->renderHandleLink($author_phid),
             count($add),
             $this->renderSubscriberList($add, 'add'),
             count($rem),
             $this->renderSubscriberList($rem, 'rem'));
         } else if ($add) {
           return pht(
             '%s added %d subscriber(s): %s.',
             $this->renderHandleLink($author_phid),
             count($add),
             $this->renderSubscriberList($add, 'add'));
         } else if ($rem) {
           return pht(
             '%s removed %d subscriber(s): %s.',
             $this->renderHandleLink($author_phid),
             count($rem),
             $this->renderSubscriberList($rem, 'rem'));
         } else {
           // This is used when rendering previews, before the user actually
           // selects any CCs.
           return pht(
             '%s updated subscribers...',
             $this->renderHandleLink($author_phid));
         }
         break;
       case PhabricatorTransactions::TYPE_FILE:
         $add = array_diff_key($new, $old);
         $add = array_keys($add);
 
         $rem = array_diff_key($old, $new);
         $rem = array_keys($rem);
 
         $mod = array();
         foreach ($old + $new as $key => $ignored) {
           if (!isset($old[$key])) {
             continue;
           }
 
           if (!isset($new[$key])) {
             continue;
           }
 
           if ($old[$key] === $new[$key]) {
             continue;
           }
 
           $mod[] = $key;
         }
 
         // Specialize the specific case of only modifying files and upgrading
         // references to attachments. This is accessible via the UI and can
         // be shown more clearly than the generic default transaction shows
         // it.
 
         $mode_reference = PhabricatorFileAttachment::MODE_REFERENCE;
         $mode_attach = PhabricatorFileAttachment::MODE_ATTACH;
 
         $is_refattach = false;
         if ($mod && !$add && !$rem) {
           $all_refattach = true;
           foreach ($mod as $phid) {
             if (idx($old, $phid) !== $mode_reference) {
               $all_refattach = false;
               break;
             }
             if (idx($new, $phid) !== $mode_attach) {
               $all_refattach = false;
               break;
             }
           }
           $is_refattach = $all_refattach;
         }
 
         if ($is_refattach) {
           return pht(
             '%s attached %s referenced file(s): %s.',
             $this->renderHandleLink($author_phid),
             phutil_count($mod),
             $this->renderHandleList($mod));
         } else if ($add && $rem && $mod) {
           return pht(
             '%s updated %s attached file(s), added %s: %s; removed %s: %s; '.
             'modified %s: %s.',
             $this->renderHandleLink($author_phid),
             new PhutilNumber(count($add) + count($rem)),
             phutil_count($add),
             $this->renderHandleList($add),
             phutil_count($rem),
             $this->renderHandleList($rem),
             phutil_count($mod),
             $this->renderHandleList($mod));
         } else if ($add && $rem) {
           return pht(
             '%s updated %s attached file(s), added %s: %s; removed %s: %s.',
             $this->renderHandleLink($author_phid),
             new PhutilNumber(count($add) + count($rem)),
             phutil_count($add),
             $this->renderHandleList($add),
             phutil_count($rem),
             $this->renderHandleList($rem));
         } else if ($add && $mod) {
           return pht(
             '%s updated %s attached file(s), added %s: %s; modified %s: %s.',
             $this->renderHandleLink($author_phid),
             new PhutilNumber(count($add) + count($mod)),
             phutil_count($add),
             $this->renderHandleList($add),
             phutil_count($mod),
             $this->renderHandleList($mod));
         } else if ($rem && $mod) {
           return pht(
             '%s updated %s attached file(s), removed %s: %s; modified %s: %s.',
             $this->renderHandleLink($author_phid),
             new PhutilNumber(count($rem) + count($mod)),
             phutil_count($rem),
             $this->renderHandleList($rem),
             phutil_count($mod),
             $this->renderHandleList($mod));
         } else if ($add) {
           return pht(
             '%s attached %s file(s): %s.',
             $this->renderHandleLink($author_phid),
             phutil_count($add),
             $this->renderHandleList($add));
         } else if ($rem) {
           return pht(
             '%s removed %s attached file(s): %s.',
             $this->renderHandleLink($author_phid),
             phutil_count($rem),
             $this->renderHandleList($rem));
         } else if ($mod) {
           return pht(
             '%s modified %s attached file(s): %s.',
             $this->renderHandleLink($author_phid),
             phutil_count($mod),
             $this->renderHandleList($mod));
         } else {
           return pht(
             '%s attached files...',
             $this->renderHandleLink($author_phid));
         }
 
         break;
       case PhabricatorTransactions::TYPE_EDGE:
         $record = PhabricatorEdgeChangeRecord::newFromTransaction($this);
         $add = $record->getAddedPHIDs();
         $rem = $record->getRemovedPHIDs();
 
         $type = $this->getMetadata('edge:type');
         $type = head($type);
 
         try {
           $type_obj = PhabricatorEdgeType::getByConstant($type);
         } catch (Exception $ex) {
           // Recover somewhat gracefully from edge transactions which
           // we don't have the classes for.
           return pht(
             '%s edited an edge.',
             $this->renderHandleLink($author_phid));
         }
 
         if ($add && $rem) {
           return $type_obj->getTransactionEditString(
             $this->renderHandleLink($author_phid),
             new PhutilNumber(count($add) + count($rem)),
             phutil_count($add),
             $this->renderHandleList($add),
             phutil_count($rem),
             $this->renderHandleList($rem));
         } else if ($add) {
           return $type_obj->getTransactionAddString(
             $this->renderHandleLink($author_phid),
             phutil_count($add),
             $this->renderHandleList($add));
         } else if ($rem) {
           return $type_obj->getTransactionRemoveString(
             $this->renderHandleLink($author_phid),
             phutil_count($rem),
             $this->renderHandleList($rem));
         } else {
           return $type_obj->getTransactionPreviewString(
             $this->renderHandleLink($author_phid));
         }
 
       case PhabricatorTransactions::TYPE_CUSTOMFIELD:
         $field = $this->getTransactionCustomField();
         if ($field) {
           return $field->getApplicationTransactionTitle($this);
         } else {
           $developer_mode = 'phabricator.developer-mode';
           $is_developer = PhabricatorEnv::getEnvConfig($developer_mode);
           if ($is_developer) {
             return pht(
               '%s edited a custom field (with key "%s").',
               $this->renderHandleLink($author_phid),
               $this->getMetadata('customfield:key'));
           } else {
             return pht(
               '%s edited a custom field.',
               $this->renderHandleLink($author_phid));
           }
         }
 
       case PhabricatorTransactions::TYPE_TOKEN:
         if ($old && $new) {
           return pht(
             '%s updated a token.',
             $this->renderHandleLink($author_phid));
         } else if ($old) {
           return pht(
             '%s rescinded a token.',
             $this->renderHandleLink($author_phid));
         } else {
           return pht(
             '%s awarded a token.',
             $this->renderHandleLink($author_phid));
         }
 
       case PhabricatorTransactions::TYPE_INLINESTATE:
         list($done, $undone) = $this->getInterestingInlineStateChangeCounts();
         if ($done && $undone) {
           return pht(
             '%s marked %s inline comment(s) as done and %s inline comment(s) '.
             'as not done.',
             $this->renderHandleLink($author_phid),
             new PhutilNumber($done),
             new PhutilNumber($undone));
         } else if ($done) {
           return pht(
             '%s marked %s inline comment(s) as done.',
             $this->renderHandleLink($author_phid),
             new PhutilNumber($done));
         } else {
           return pht(
             '%s marked %s inline comment(s) as not done.',
             $this->renderHandleLink($author_phid),
             new PhutilNumber($undone));
         }
         break;
 
       case PhabricatorTransactions::TYPE_COLUMNS:
         $moves = $this->getInterestingMoves($new);
         if (count($moves) == 1) {
           $move = head($moves);
           $from_columns = $move['fromColumnPHIDs'];
           $to_column = $move['columnPHID'];
           $board_phid = $move['boardPHID'];
           if (count($from_columns) == 1) {
             return pht(
               '%s moved this task from %s to %s on the %s board.',
               $this->renderHandleLink($author_phid),
               $this->renderHandleLink(head($from_columns)),
               $this->renderHandleLink($to_column),
               $this->renderHandleLink($board_phid));
           } else {
             return pht(
               '%s moved this task to %s on the %s board.',
               $this->renderHandleLink($author_phid),
               $this->renderHandleLink($to_column),
               $this->renderHandleLink($board_phid));
           }
         } else {
           $fragments = array();
           foreach ($moves as $move) {
             $to_column = $move['columnPHID'];
             $board_phid = $move['boardPHID'];
             $fragments[] = pht(
               '%s (%s)',
               $this->renderHandleLink($board_phid),
               $this->renderHandleLink($to_column));
           }
 
           return pht(
             '%s moved this task on %s board(s): %s.',
             $this->renderHandleLink($author_phid),
             phutil_count($moves),
             phutil_implode_html(', ', $fragments));
         }
         break;
 
 
       case PhabricatorTransactions::TYPE_MFA:
         return pht(
           '%s signed these changes with MFA.',
           $this->renderHandleLink($author_phid));
 
       default:
         // In developer mode, provide a better hint here about which string
         // we're missing.
         $developer_mode = 'phabricator.developer-mode';
         $is_developer = PhabricatorEnv::getEnvConfig($developer_mode);
         if ($is_developer) {
           return pht(
             '%s edited this object (transaction type "%s").',
             $this->renderHandleLink($author_phid),
             $this->getTransactionType());
         } else {
           return pht(
             '%s edited this %s.',
             $this->renderHandleLink($author_phid),
             $this->getApplicationObjectTypeName());
         }
     }
   }
 
   public function getTitleForFeed() {
     $author_phid = $this->getAuthorPHID();
     $object_phid = $this->getObjectPHID();
 
     $old = $this->getOldValue();
     $new = $this->getNewValue();
 
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_CREATE:
         return pht(
           '%s created %s.',
           $this->renderHandleLink($author_phid),
           $this->renderHandleLink($object_phid));
       case PhabricatorTransactions::TYPE_COMMENT:
         return pht(
           '%s added a comment to %s.',
           $this->renderHandleLink($author_phid),
           $this->renderHandleLink($object_phid));
       case PhabricatorTransactions::TYPE_VIEW_POLICY:
         return pht(
           '%s changed the visibility for %s.',
           $this->renderHandleLink($author_phid),
           $this->renderHandleLink($object_phid));
       case PhabricatorTransactions::TYPE_EDIT_POLICY:
         return pht(
           '%s changed the edit policy for %s.',
           $this->renderHandleLink($author_phid),
           $this->renderHandleLink($object_phid));
       case PhabricatorTransactions::TYPE_JOIN_POLICY:
         return pht(
           '%s changed the join policy for %s.',
           $this->renderHandleLink($author_phid),
           $this->renderHandleLink($object_phid));
       case PhabricatorTransactions::TYPE_INTERACT_POLICY:
         return pht(
           '%s changed the interact policy for %s.',
           $this->renderHandleLink($author_phid),
           $this->renderHandleLink($object_phid));
       case PhabricatorTransactions::TYPE_SUBSCRIBERS:
         return pht(
           '%s updated subscribers of %s.',
           $this->renderHandleLink($author_phid),
           $this->renderHandleLink($object_phid));
       case PhabricatorTransactions::TYPE_SPACE:
         if ($this->getIsCreateTransaction()) {
           return pht(
             '%s created %s in the %s space.',
             $this->renderHandleLink($author_phid),
             $this->renderHandleLink($object_phid),
             $this->renderHandleLink($new));
         } else {
           return pht(
             '%s shifted %s from the %s space to the %s space.',
             $this->renderHandleLink($author_phid),
             $this->renderHandleLink($object_phid),
             $this->renderHandleLink($old),
             $this->renderHandleLink($new));
         }
       case PhabricatorTransactions::TYPE_EDGE:
         $record = PhabricatorEdgeChangeRecord::newFromTransaction($this);
         $add = $record->getAddedPHIDs();
         $rem = $record->getRemovedPHIDs();
 
         $type = $this->getMetadata('edge:type');
         $type = head($type);
 
         $type_obj = PhabricatorEdgeType::getByConstant($type);
 
         if ($add && $rem) {
           return $type_obj->getFeedEditString(
             $this->renderHandleLink($author_phid),
             $this->renderHandleLink($object_phid),
             new PhutilNumber(count($add) + count($rem)),
             phutil_count($add),
             $this->renderHandleList($add),
             phutil_count($rem),
             $this->renderHandleList($rem));
         } else if ($add) {
           return $type_obj->getFeedAddString(
             $this->renderHandleLink($author_phid),
             $this->renderHandleLink($object_phid),
             phutil_count($add),
             $this->renderHandleList($add));
         } else if ($rem) {
           return $type_obj->getFeedRemoveString(
             $this->renderHandleLink($author_phid),
             $this->renderHandleLink($object_phid),
             phutil_count($rem),
             $this->renderHandleList($rem));
         } else {
           return pht(
             '%s edited edge metadata for %s.',
             $this->renderHandleLink($author_phid),
             $this->renderHandleLink($object_phid));
         }
 
       case PhabricatorTransactions::TYPE_CUSTOMFIELD:
         $field = $this->getTransactionCustomField();
         if ($field) {
           return $field->getApplicationTransactionTitleForFeed($this);
         } else {
           return pht(
             '%s edited a custom field on %s.',
             $this->renderHandleLink($author_phid),
             $this->renderHandleLink($object_phid));
         }
 
       case PhabricatorTransactions::TYPE_COLUMNS:
         $moves = $this->getInterestingMoves($new);
         if (count($moves) == 1) {
           $move = head($moves);
           $from_columns = $move['fromColumnPHIDs'];
           $to_column = $move['columnPHID'];
           $board_phid = $move['boardPHID'];
           if (count($from_columns) == 1) {
             return pht(
               '%s moved %s from %s to %s on the %s board.',
               $this->renderHandleLink($author_phid),
               $this->renderHandleLink($object_phid),
               $this->renderHandleLink(head($from_columns)),
               $this->renderHandleLink($to_column),
               $this->renderHandleLink($board_phid));
           } else {
             return pht(
               '%s moved %s to %s on the %s board.',
               $this->renderHandleLink($author_phid),
               $this->renderHandleLink($object_phid),
               $this->renderHandleLink($to_column),
               $this->renderHandleLink($board_phid));
           }
         } else {
           $fragments = array();
           foreach ($moves as $move) {
             $fragments[] = pht(
               '%s (%s)',
               $this->renderHandleLink($board_phid),
               $this->renderHandleLink($to_column));
           }
 
           return pht(
             '%s moved %s on %s board(s): %s.',
             $this->renderHandleLink($author_phid),
             $this->renderHandleLink($object_phid),
             phutil_count($moves),
             phutil_implode_html(', ', $fragments));
         }
         break;
 
       case PhabricatorTransactions::TYPE_MFA:
         return null;
 
     }
 
     return $this->getTitle();
   }
 
   public function getMarkupFieldsForFeed(PhabricatorFeedStory $story) {
     $fields = array();
 
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_COMMENT:
         $text = $this->getComment()->getContent();
         if (strlen($text)) {
           $fields[] = 'comment/'.$this->getID();
         }
         break;
     }
 
     return $fields;
   }
 
   public function getMarkupTextForFeed(PhabricatorFeedStory $story, $field) {
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_COMMENT:
         $text = $this->getComment()->getContent();
         return PhabricatorMarkupEngine::summarize($text);
     }
 
     return null;
   }
 
   public function getBodyForFeed(PhabricatorFeedStory $story) {
     $remarkup = $this->getRemarkupBodyForFeed($story);
     if ($remarkup !== null) {
       $remarkup = PhabricatorMarkupEngine::summarize($remarkup);
       return new PHUIRemarkupView($this->viewer, $remarkup);
     }
 
     $old = $this->getOldValue();
     $new = $this->getNewValue();
 
     $body = null;
 
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_COMMENT:
         $text = $this->getComment()->getContent();
         if (strlen($text)) {
           $body = $story->getMarkupFieldOutput('comment/'.$this->getID());
         }
         break;
     }
 
     return $body;
   }
 
   public function getRemarkupBodyForFeed(PhabricatorFeedStory $story) {
     return null;
   }
 
   public function getActionStrength() {
     if ($this->isInlineCommentTransaction()) {
       return 25;
     }
 
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_COMMENT:
         return 50;
       case PhabricatorTransactions::TYPE_SUBSCRIBERS:
         if ($this->isSelfSubscription()) {
           // Make this weaker than TYPE_COMMENT.
           return 25;
         }
 
         // In other cases, subscriptions are more interesting than comments
         // (which are shown anyway) but less interesting than any other type of
         // transaction.
         return 75;
       case PhabricatorTransactions::TYPE_MFA:
         // We want MFA signatures to render at the top of transaction groups,
         // on top of the things they signed.
         return 1000;
     }
 
     return 100;
   }
 
   public function isCommentTransaction() {
     if ($this->hasComment()) {
       return true;
     }
 
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_COMMENT:
         return true;
     }
 
     return false;
   }
 
   public function isInlineCommentTransaction() {
     return false;
   }
 
   public function getActionName() {
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_COMMENT:
         return pht('Commented On');
       case PhabricatorTransactions::TYPE_VIEW_POLICY:
       case PhabricatorTransactions::TYPE_EDIT_POLICY:
       case PhabricatorTransactions::TYPE_JOIN_POLICY:
       case PhabricatorTransactions::TYPE_INTERACT_POLICY:
         return pht('Changed Policy');
       case PhabricatorTransactions::TYPE_SUBSCRIBERS:
         return pht('Changed Subscribers');
       default:
         return pht('Updated');
     }
   }
 
   public function getMailTags() {
     return array();
   }
 
   public function hasChangeDetails() {
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_FILE:
         return true;
       case PhabricatorTransactions::TYPE_CUSTOMFIELD:
         $field = $this->getTransactionCustomField();
         if ($field) {
           return $field->getApplicationTransactionHasChangeDetails($this);
         }
         break;
     }
     return false;
   }
 
   public function hasChangeDetailsForMail() {
     return $this->hasChangeDetails();
   }
 
   public function renderChangeDetailsForMail(PhabricatorUser $viewer) {
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_FILE:
         return false;
     }
 
     $view = $this->renderChangeDetails($viewer);
     if ($view instanceof PhabricatorApplicationTransactionTextDiffDetailView) {
       return $view->renderForMail();
     }
     return null;
   }
 
   public function renderChangeDetails(PhabricatorUser $viewer) {
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_FILE:
         return $this->newFileTransactionChangeDetails($viewer);
       case PhabricatorTransactions::TYPE_CUSTOMFIELD:
         $field = $this->getTransactionCustomField();
         if ($field) {
           return $field->getApplicationTransactionChangeDetails($this, $viewer);
         }
         break;
     }
 
     return $this->renderTextCorpusChangeDetails(
       $viewer,
       $this->getOldValue(),
       $this->getNewValue());
   }
 
   public function renderTextCorpusChangeDetails(
     PhabricatorUser $viewer,
     $old,
     $new) {
     return id(new PhabricatorApplicationTransactionTextDiffDetailView())
       ->setUser($viewer)
       ->setOldText($old)
       ->setNewText($new);
   }
 
   public function attachTransactionGroup(array $group) {
     assert_instances_of($group, __CLASS__);
     $this->transactionGroup = $group;
     return $this;
   }
 
   public function getTransactionGroup() {
     return $this->transactionGroup;
   }
 
   /**
    * Should this transaction be visually grouped with an existing transaction
    * group?
    *
    * @param list<PhabricatorApplicationTransaction> List of transactions.
    * @return bool True to display in a group with the other transactions.
    */
   public function shouldDisplayGroupWith(array $group) {
     $this_source = null;
     if ($this->getContentSource()) {
       $this_source = $this->getContentSource()->getSource();
     }
 
     $type_mfa = PhabricatorTransactions::TYPE_MFA;
 
     foreach ($group as $xaction) {
       // Don't group transactions by different authors.
       if ($xaction->getAuthorPHID() != $this->getAuthorPHID()) {
         return false;
       }
 
       // Don't group transactions for different objects.
       if ($xaction->getObjectPHID() != $this->getObjectPHID()) {
         return false;
       }
 
       // Don't group anything into a group which already has a comment.
       if ($xaction->isCommentTransaction()) {
         return false;
       }
 
       // Don't group transactions from different content sources.
       $other_source = null;
       if ($xaction->getContentSource()) {
         $other_source = $xaction->getContentSource()->getSource();
       }
 
       if ($other_source != $this_source) {
         return false;
       }
 
       // Don't group transactions which happened more than 2 minutes apart.
       $apart = abs($xaction->getDateCreated() - $this->getDateCreated());
       if ($apart > (60 * 2)) {
         return false;
       }
 
       // Don't group silent and nonsilent transactions together.
       $is_silent = $this->getIsSilentTransaction();
       if ($is_silent != $xaction->getIsSilentTransaction()) {
         return false;
       }
 
       // Don't group MFA and non-MFA transactions together.
       $is_mfa = $this->getIsMFATransaction();
       if ($is_mfa != $xaction->getIsMFATransaction()) {
         return false;
       }
 
       // Don't group two "Sign with MFA" transactions together.
       if ($this->getTransactionType() === $type_mfa) {
         if ($xaction->getTransactionType() === $type_mfa) {
           return false;
         }
       }
 
       // Don't group lock override and non-override transactions together.
       $is_override = $this->getIsLockOverrideTransaction();
       if ($is_override != $xaction->getIsLockOverrideTransaction()) {
         return false;
       }
     }
 
     return true;
   }
 
   public function renderExtraInformationLink() {
     $herald_xscript_id = $this->getMetadataValue('herald:transcriptID');
 
     if ($herald_xscript_id) {
       return phutil_tag(
         'a',
         array(
           'href' => '/herald/transcript/'.$herald_xscript_id.'/',
         ),
         pht('View Herald Transcript'));
     }
 
     return null;
   }
 
   public function renderAsTextForDoorkeeper(
     DoorkeeperFeedStoryPublisher $publisher,
     PhabricatorFeedStory $story,
     array $xactions) {
 
     $text = array();
     $body = array();
 
     foreach ($xactions as $xaction) {
       $xaction_body = $xaction->getBodyForMail();
       if ($xaction_body !== null) {
         $body[] = $xaction_body;
       }
 
       if ($xaction->shouldHideForMail($xactions)) {
         continue;
       }
 
       $old_target = $xaction->getRenderingTarget();
       $new_target = self::TARGET_TEXT;
       $xaction->setRenderingTarget($new_target);
 
       if ($publisher->getRenderWithImpliedContext()) {
         $text[] = $xaction->getTitle();
       } else {
         $text[] = $xaction->getTitleForFeed();
       }
 
       $xaction->setRenderingTarget($old_target);
     }
 
     $text = implode("\n", $text);
     $body = implode("\n\n", $body);
 
     return rtrim($text."\n\n".$body);
   }
 
   /**
    * Test if this transaction is just a user subscribing or unsubscribing
    * themselves.
    */
   private function isSelfSubscription() {
     $type = $this->getTransactionType();
     if ($type != PhabricatorTransactions::TYPE_SUBSCRIBERS) {
       return false;
     }
 
     $old = $this->getOldValue();
     $new = $this->getNewValue();
 
     $add = array_diff($old, $new);
     $rem = array_diff($new, $old);
 
     if ((count($add) + count($rem)) != 1) {
       // More than one user affected.
       return false;
     }
 
     $affected_phid = head(array_merge($add, $rem));
     if ($affected_phid != $this->getAuthorPHID()) {
       // Affected user is someone else.
       return false;
     }
 
     return true;
   }
 
   private function isApplicationAuthor() {
     $author_phid = $this->getAuthorPHID();
     $author_type = phid_get_type($author_phid);
     $application_type = PhabricatorApplicationApplicationPHIDType::TYPECONST;
     return ($author_type == $application_type);
   }
 
 
   private function getInterestingMoves(array $moves) {
     // Remove moves which only shift the position of a task within a column.
     foreach ($moves as $key => $move) {
       $from_phids = array_fuse($move['fromColumnPHIDs']);
       if (isset($from_phids[$move['columnPHID']])) {
         unset($moves[$key]);
       }
     }
 
     return $moves;
   }
 
   private function getInterestingInlineStateChangeCounts() {
     // See PHI995. Newer inline state transactions have additional details
     // which we use to tailor the rendering behavior. These details are not
     // present on older transactions.
     $details = $this->getMetadataValue('inline.details', array());
 
     $new = $this->getNewValue();
 
     $done = 0;
     $undone = 0;
     foreach ($new as $phid => $state) {
       $is_done = ($state == PhabricatorInlineComment::STATE_DONE);
 
       // See PHI995. If you're marking your own inline comments as "Done",
       // don't count them when rendering a timeline story. In the case where
       // you're only affecting your own comments, this will hide the
       // "alice marked X comments as done" story entirely.
 
       // Usually, this happens when you pre-mark inlines as "done" and submit
       // them yourself. We'll still generate an "alice added inline comments"
       // story (in most cases/contexts), but the state change story is largely
       // just clutter and slightly confusing/misleading.
 
       $inline_details = idx($details, $phid, array());
       $inline_author_phid = idx($inline_details, 'authorPHID');
       if ($inline_author_phid) {
         if ($inline_author_phid == $this->getAuthorPHID()) {
           if ($is_done) {
             continue;
           }
         }
       }
 
       if ($is_done) {
         $done++;
       } else {
         $undone++;
       }
     }
 
     return array($done, $undone);
   }
 
   public function newGlobalSortVector() {
     return id(new PhutilSortVector())
       ->addInt(-$this->getDateCreated())
       ->addString($this->getPHID());
   }
 
   public function newActionStrengthSortVector() {
     return id(new PhutilSortVector())
       ->addInt(-$this->getActionStrength());
   }
 
   private function newFileTransactionChangeDetails(PhabricatorUser $viewer) {
     $old = $this->getOldValue();
     $new = $this->getNewValue();
 
     $phids = array_keys($old + $new);
     $handles = $viewer->loadHandles($phids);
 
     $names = array(
       PhabricatorFileAttachment::MODE_REFERENCE => pht('Referenced'),
       PhabricatorFileAttachment::MODE_ATTACH => pht('Attached'),
     );
 
     $rows = array();
     foreach ($old + $new as $phid => $ignored) {
       $handle = $handles[$phid];
 
       $old_mode = idx($old, $phid);
       $new_mode = idx($new, $phid);
 
       if ($old_mode === null) {
         $old_name = pht('None');
       } else if (isset($names[$old_mode])) {
         $old_name = $names[$old_mode];
       } else {
         $old_name = pht('Unknown ("%s")', $old_mode);
       }
 
       if ($new_mode === null) {
         $new_name = pht('Detached');
       } else if (isset($names[$new_mode])) {
         $new_name = $names[$new_mode];
       } else {
         $new_name = pht('Unknown ("%s")', $new_mode);
       }
 
       $rows[] = array(
         $handle->renderLink(),
         $old_name,
         $new_name,
       );
     }
 
     $table = id(new AphrontTableView($rows))
       ->setHeaders(
         array(
           pht('File'),
           pht('Old Mode'),
           pht('New Mode'),
         ))
       ->setColumnClasses(
         array(
           'pri',
         ));
 
     return id(new PHUIBoxView())
       ->addMargin(PHUI::MARGIN_SMALL)
       ->appendChild($table);
   }
 
 
 
 /* -(  PhabricatorPolicyInterface Implementation  )-------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         return $this->getViewPolicy();
       case PhabricatorPolicyCapability::CAN_EDIT:
         return $this->getEditPolicy();
     }
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return ($viewer->getPHID() == $this->getAuthorPHID());
   }
 
   public function describeAutomaticCapability($capability) {
     return pht(
       'Transactions are visible to users that can see the object which was '.
       'acted upon. Some transactions - in particular, comments - are '.
       'editable by the transaction author.');
   }
 
   public function getModularType() {
     return null;
   }
 
   public function setForceNotifyPHIDs(array $phids) {
     $this->setMetadataValue('notify.force', $phids);
     return $this;
   }
 
   public function getForceNotifyPHIDs() {
     return $this->getMetadataValue('notify.force', array());
   }
 
 
 /* -(  PhabricatorDestructibleInterface  )----------------------------------- */
 
 
   public function destroyObjectPermanently(
     PhabricatorDestructionEngine $engine) {
 
     $this->openTransaction();
       $comment_template = $this->getApplicationTransactionCommentObject();
 
       if ($comment_template) {
         $comments = $comment_template->loadAllWhere(
           'transactionPHID = %s',
           $this->getPHID());
         foreach ($comments as $comment) {
           $engine->destroyObject($comment);
         }
       }
 
       $this->delete();
     $this->saveTransaction();
   }
 
 }
diff --git a/src/applications/transactions/view/PhabricatorApplicationTransactionView.php b/src/applications/transactions/view/PhabricatorApplicationTransactionView.php
index ee2020f890..180ba071a9 100644
--- a/src/applications/transactions/view/PhabricatorApplicationTransactionView.php
+++ b/src/applications/transactions/view/PhabricatorApplicationTransactionView.php
@@ -1,565 +1,570 @@
 <?php
 
 /**
  * @concrete-extensible
  */
 class PhabricatorApplicationTransactionView extends AphrontView {
 
   private $transactions;
   private $engine;
   private $showEditActions = true;
   private $isPreview;
   private $object;
   private $objectPHID;
   private $shouldTerminate = false;
   private $quoteTargetID;
   private $quoteRef;
   private $pager;
   private $renderAsFeed;
   private $hideCommentOptions = false;
   private $viewData = array();
 
   public function setRenderAsFeed($feed) {
     $this->renderAsFeed = $feed;
     return $this;
   }
 
   public function setQuoteRef($quote_ref) {
     $this->quoteRef = $quote_ref;
     return $this;
   }
 
   public function getQuoteRef() {
     return $this->quoteRef;
   }
 
   public function setQuoteTargetID($quote_target_id) {
     $this->quoteTargetID = $quote_target_id;
     return $this;
   }
 
   public function getQuoteTargetID() {
     return $this->quoteTargetID;
   }
 
   public function setObject(
     PhabricatorApplicationTransactionInterface $object) {
     $this->object = $object;
     return $this;
   }
 
   private function getObject() {
     return $this->object;
   }
 
   public function setObjectPHID($object_phid) {
     $this->objectPHID = $object_phid;
     return $this;
   }
 
   public function getObjectPHID() {
     return $this->objectPHID;
   }
 
   public function setIsPreview($is_preview) {
     $this->isPreview = $is_preview;
     return $this;
   }
 
   public function getIsPreview() {
     return $this->isPreview;
   }
 
   public function setShowEditActions($show_edit_actions) {
     $this->showEditActions = $show_edit_actions;
     return $this;
   }
 
   public function getShowEditActions() {
     return $this->showEditActions;
   }
 
   public function setMarkupEngine(PhabricatorMarkupEngine $engine) {
     $this->engine = $engine;
     return $this;
   }
 
   public function setTransactions(array $transactions) {
     assert_instances_of($transactions, 'PhabricatorApplicationTransaction');
     $this->transactions = $transactions;
     return $this;
   }
 
   public function getTransactions() {
     return $this->transactions;
   }
 
   public function setShouldTerminate($term) {
     $this->shouldTerminate = $term;
     return $this;
   }
 
   public function setPager(AphrontCursorPagerView $pager) {
     $this->pager = $pager;
     return $this;
   }
 
   public function getPager() {
     return $this->pager;
   }
 
   public function setHideCommentOptions($hide_comment_options) {
     $this->hideCommentOptions = $hide_comment_options;
     return $this;
   }
 
   public function getHideCommentOptions() {
     return $this->hideCommentOptions;
   }
 
   public function setViewData(array $view_data) {
     $this->viewData = $view_data;
     return $this;
   }
 
   public function getViewData() {
     return $this->viewData;
   }
 
   public function buildEvents($with_hiding = false) {
     $user = $this->getUser();
 
     $xactions = $this->transactions;
 
     $xactions = $this->filterHiddenTransactions($xactions);
     $xactions = $this->groupRelatedTransactions($xactions);
     $groups = $this->groupDisplayTransactions($xactions);
 
     // If the viewer has interacted with this object, we hide things from
     // before their most recent interaction by default. This tends to make
     // very long threads much more manageable, because you don't have to
     // scroll through a lot of history and can focus on just new stuff.
 
     $show_group = null;
 
     if ($with_hiding) {
       // Find the most recent comment by the viewer.
       $group_keys = array_keys($groups);
       $group_keys = array_reverse($group_keys);
 
       // If we would only hide a small number of transactions, don't hide
       // anything. Just don't examine the last few keys. Also, we always
       // want to show the most recent pieces of activity, so don't examine
       // the first few keys either.
       $group_keys = array_slice($group_keys, 2, -2);
 
       $type_comment = PhabricatorTransactions::TYPE_COMMENT;
       foreach ($group_keys as $group_key) {
         $group = $groups[$group_key];
         foreach ($group as $xaction) {
           if ($xaction->getAuthorPHID() == $user->getPHID() &&
               $xaction->getTransactionType() == $type_comment) {
             // This is the most recent group where the user commented.
             $show_group = $group_key;
             break 2;
           }
         }
       }
     }
 
     $events = array();
     $hide_by_default = ($show_group !== null);
     $set_next_page_id = false;
 
     foreach ($groups as $group_key => $group) {
       if ($hide_by_default && ($show_group === $group_key)) {
         $hide_by_default = false;
         $set_next_page_id = true;
       }
 
       $group_event = null;
       foreach ($group as $xaction) {
         $event = $this->renderEvent($xaction, $group);
         $event->setHideByDefault($hide_by_default);
         if (!$group_event) {
           $group_event = $event;
         } else {
           $group_event->addEventToGroup($event);
         }
         if ($set_next_page_id) {
           $set_next_page_id = false;
           $pager = $this->getPager();
           if ($pager) {
             $pager->setNextPageID($xaction->getID());
           }
         }
       }
       $events[] = $group_event;
 
     }
 
     return $events;
   }
 
   public function render() {
     if (!$this->getObjectPHID()) {
       throw new PhutilInvalidStateException('setObjectPHID');
     }
 
     $view = $this->buildPHUITimelineView();
 
     if ($this->getShowEditActions()) {
       Javelin::initBehavior('phabricator-transaction-list');
     }
 
     return $view->render();
   }
 
   public function buildPHUITimelineView($with_hiding = true) {
     if (!$this->getObjectPHID()) {
       throw new PhutilInvalidStateException('setObjectPHID');
     }
 
     $view = id(new PHUITimelineView())
       ->setViewer($this->getViewer())
       ->setShouldTerminate($this->shouldTerminate)
       ->setQuoteTargetID($this->getQuoteTargetID())
       ->setQuoteRef($this->getQuoteRef())
       ->setViewData($this->getViewData());
 
     $events = $this->buildEvents($with_hiding);
     foreach ($events as $event) {
       $view->addEvent($event);
     }
 
     if ($this->getPager()) {
       $view->setPager($this->getPager());
     }
 
     return $view;
   }
 
   public function isTimelineEmpty() {
     return !count($this->buildEvents(true));
   }
 
   protected function getOrBuildEngine() {
     if (!$this->engine) {
       $field = PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT;
 
       $engine = id(new PhabricatorMarkupEngine())
         ->setViewer($this->getViewer());
 
       $object = $this->getObject();
       if ($object) {
         $engine->setContextObject($object);
       }
 
       foreach ($this->transactions as $xaction) {
         if (!$xaction->hasComment()) {
           continue;
         }
         $engine->addObject($xaction->getComment(), $field);
       }
       $engine->process();
 
       $this->engine = $engine;
     }
 
     return $this->engine;
   }
 
   private function buildChangeDetailsLink(
     PhabricatorApplicationTransaction $xaction) {
 
     return javelin_tag(
       'a',
       array(
         'href' => $xaction->getChangeDetailsURI(),
         'sigil' => 'workflow',
       ),
       pht('(Show Details)'));
   }
 
   private function buildExtraInformationLink(
     PhabricatorApplicationTransaction $xaction) {
 
     $link = $xaction->renderExtraInformationLink();
     if (!$link) {
       return null;
     }
 
     return phutil_tag(
       'span',
       array(
         'class' => 'phui-timeline-extra-information',
       ),
       array(" \xC2\xB7  ", $link));
   }
 
   protected function shouldGroupTransactions(
     PhabricatorApplicationTransaction $u,
     PhabricatorApplicationTransaction $v) {
     return false;
   }
 
   protected function renderTransactionContent(
     PhabricatorApplicationTransaction $xaction) {
 
     $field = PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT;
     $engine = $this->getOrBuildEngine();
     $comment = $xaction->getComment();
 
     if ($comment) {
       if ($comment->getIsRemoved()) {
         return javelin_tag(
           'span',
           array(
             'class' => 'comment-deleted',
             'sigil' => 'transaction-comment',
             'meta'  => array('phid' => $comment->getTransactionPHID()),
           ),
           pht(
             'This comment was removed by %s.',
             $xaction->getHandle($comment->getAuthorPHID())->renderLink()));
       } else if ($comment->getIsDeleted()) {
         return javelin_tag(
           'span',
           array(
             'class' => 'comment-deleted',
             'sigil' => 'transaction-comment',
             'meta'  => array('phid' => $comment->getTransactionPHID()),
           ),
           pht('This comment has been deleted.'));
       } else if ($xaction->hasComment()) {
         return javelin_tag(
           'span',
           array(
             'class' => 'transaction-comment',
             'sigil' => 'transaction-comment',
             'meta'  => array('phid' => $comment->getTransactionPHID()),
           ),
           $engine->getOutput($comment, $field));
       } else {
         // This is an empty, non-deleted comment. Usually this happens when
         // rendering previews.
         return null;
       }
     }
 
     return null;
   }
 
   private function filterHiddenTransactions(array $xactions) {
     foreach ($xactions as $key => $xaction) {
       if ($xaction->shouldHide()) {
         unset($xactions[$key]);
       }
     }
     return $xactions;
   }
 
   private function groupRelatedTransactions(array $xactions) {
     $last = null;
     $last_key = null;
     $groups = array();
     foreach ($xactions as $key => $xaction) {
       if ($last && $this->shouldGroupTransactions($last, $xaction)) {
         $groups[$last_key][] = $xaction;
         unset($xactions[$key]);
       } else {
         $last = $xaction;
         $last_key = $key;
       }
     }
 
     foreach ($xactions as $key => $xaction) {
       $xaction->attachTransactionGroup(idx($groups, $key, array()));
     }
 
     return $xactions;
   }
 
   private function groupDisplayTransactions(array $xactions) {
     $groups = array();
     $group = array();
     foreach ($xactions as $xaction) {
       if ($xaction->shouldDisplayGroupWith($group)) {
         $group[] = $xaction;
       } else {
         if ($group) {
           $groups[] = $group;
         }
         $group = array($xaction);
       }
     }
 
     if ($group) {
       $groups[] = $group;
     }
 
     foreach ($groups as $key => $group) {
       $results = array();
 
       // Sort transactions within the group by action strength, then by
       // chronological order. This makes sure that multiple actions of the
       // same type (like a close, then a reopen) render in the order they
       // were performed.
       $strength_groups = mgroup($group, 'getActionStrength');
       krsort($strength_groups);
       foreach ($strength_groups as $strength_group) {
         foreach (msort($strength_group, 'getID') as $xaction) {
           $results[] = $xaction;
         }
       }
 
       $groups[$key] = $results;
     }
 
     return $groups;
   }
 
   private function renderEvent(
     PhabricatorApplicationTransaction $xaction,
     array $group) {
     $viewer = $this->getViewer();
 
     $event = id(new PHUITimelineEventView())
       ->setViewer($viewer)
       ->setAuthorPHID($xaction->getAuthorPHID())
       ->setTransactionPHID($xaction->getPHID())
       ->setUserHandle($xaction->getHandle($xaction->getAuthorPHID()))
       ->setIcon($xaction->getIcon())
       ->setColor($xaction->getColor())
       ->setHideCommentOptions($this->getHideCommentOptions())
       ->setIsSilent($xaction->getIsSilentTransaction())
       ->setIsMFA($xaction->getIsMFATransaction())
       ->setIsLockOverride($xaction->getIsLockOverrideTransaction());
 
     list($token, $token_removed) = $xaction->getToken();
     if ($token) {
       $event->setToken($token, $token_removed);
     }
 
     if (!$this->shouldSuppressTitle($xaction, $group)) {
       if ($this->renderAsFeed) {
         $title = $xaction->getTitleForFeed();
       } else {
         $title = $xaction->getTitle();
       }
       if ($xaction->hasChangeDetails()) {
         if (!$this->isPreview) {
           $details = $this->buildChangeDetailsLink($xaction);
           $title = array(
             $title,
             ' ',
             $details,
           );
         }
       }
 
       if (!$this->isPreview) {
         $more = $this->buildExtraInformationLink($xaction);
         if ($more) {
           $title = array($title, ' ', $more);
         }
       }
 
       $event->setTitle($title);
     }
 
     if ($this->isPreview) {
       $event->setIsPreview(true);
     } else {
       $event
         ->setDateCreated($xaction->getDateCreated())
         ->setContentSource($xaction->getContentSource())
         ->setAnchor($xaction->getID());
     }
 
     $transaction_type = $xaction->getTransactionType();
     $comment_type = PhabricatorTransactions::TYPE_COMMENT;
     $is_normal_comment = ($transaction_type == $comment_type);
 
     if ($this->getShowEditActions() &&
         !$this->isPreview &&
         $is_normal_comment) {
 
       $has_deleted_comment =
         $xaction->getComment() &&
         $xaction->getComment()->getIsDeleted();
 
       $has_removed_comment =
         $xaction->getComment() &&
         $xaction->getComment()->getIsRemoved();
 
+      // Make designers happy to make CSS customizations
+      if ($has_removed_comment) {
+        $event->addClass('phui-timeline-shell-removed');
+      }
+
       if ($xaction->getCommentVersion() > 1 && !$has_removed_comment) {
         $event->setIsEdited(true);
       }
 
       if (!$has_removed_comment) {
         $event->setIsNormalComment(true);
       }
 
       // If we have a place for quoted text to go and this is a quotable
       // comment, pass the quote target ID to the event view.
       if ($this->getQuoteTargetID()) {
         if ($xaction->hasComment()) {
           if (!$has_removed_comment && !$has_deleted_comment) {
             $event->setQuoteTargetID($this->getQuoteTargetID());
             $event->setQuoteRef($this->getQuoteRef());
           }
         }
       }
 
       $can_edit = PhabricatorPolicyCapability::CAN_EDIT;
 
       if ($xaction->hasComment() || $has_deleted_comment) {
         $has_edit_capability = PhabricatorPolicyFilter::hasCapability(
           $viewer,
           $xaction,
           $can_edit);
         if ($has_edit_capability && !$has_removed_comment) {
           $event->setIsEditable(true);
         }
 
         if ($has_edit_capability || $viewer->getIsAdmin()) {
           if (!$has_removed_comment) {
             $event->setIsRemovable(true);
           }
         }
       }
 
       $can_interact = PhabricatorPolicyFilter::canInteract(
         $viewer,
         $xaction->getObject());
       $event->setCanInteract($can_interact);
     }
 
     $comment = $this->renderTransactionContent($xaction);
     if ($comment) {
       $event->appendChild($comment);
     }
 
     return $event;
   }
 
   private function shouldSuppressTitle(
     PhabricatorApplicationTransaction $xaction,
     array $group) {
 
     // This is a little hard-coded, but we don't have any other reasonable
     // cases for now. Suppress "commented on" if there are other actions in
     // the display group.
 
     if (count($group) > 1) {
       $type_comment = PhabricatorTransactions::TYPE_COMMENT;
       if ($xaction->getTransactionType() == $type_comment) {
         return true;
       }
     }
 
     return false;
   }
 
 }
diff --git a/webroot/rsrc/css/phui/phui-timeline-view.css b/webroot/rsrc/css/phui/phui-timeline-view.css
index e08373d589..59caec7fea 100644
--- a/webroot/rsrc/css/phui/phui-timeline-view.css
+++ b/webroot/rsrc/css/phui/phui-timeline-view.css
@@ -1,440 +1,460 @@
 /**
  * @provides phui-timeline-view-css
  */
 
 .phui-timeline-view {
   padding: 0 16px;
   background-image: url('/rsrc/image/d5d8e1.png');
   background-repeat: repeat-y;
   background-position: 96px;
 }
 
 .device .phui-timeline-view {
   padding: 0 8px;
 }
 
 .device-tablet .phui-timeline-view {
   background-position: 24px;
 }
 
 .device-phone .phui-timeline-view {
   padding: 0;
   background-position: 24px;
 }
 
 .phui-timeline-major-event .phui-timeline-group {
   border-left: 1px solid {$timeline};
   border-right: 1px solid {$timeline};
   border-radius: 3px;
 }
 
 .device-desktop .phui-timeline-event-view {
   margin-left: 62px;
   position: relative;
 }
 
 .device-desktop .phui-timeline-event-view.phui-timeline-minor-event {
   margin-left: 67px;
 }
 
 .device-desktop .phui-timeline-spacer {
   min-height: 16px;
 }
 
 .device-desktop .phui-timeline-event-view.the-worlds-end {
   background: {$lightblueborder};
   width: 9px;
   height: 9px;
   border-radius: 2px;
   margin-left: 76px;
   margin-bottom: 20px;
 }
 
 .device-desktop .phui-timeline-wedge {
   border-bottom: 1px solid {$timeline};
   position: absolute;
   width: 12px;
 }
 
 .device-phone .phui-timeline-minor-event,
 .device-tablet .phui-timeline-minor-event {
   padding-left: 3px;
 }
 
 .phui-timeline-major-event .phui-timeline-content {
   border-top: 1px solid {$timeline};
   border-bottom: 1px solid {$timeline};
   border-radius: 3px;
 }
 
 .phui-timeline-title {
   line-height: 24px;
   min-height: 19px;
   position: relative;
   color: {$greytext};
 }
 
 .phui-timeline-minor-event .phui-timeline-title {
   padding: 1px 8px 4px 33px;
 }
 
 .phui-timeline-title a {
   font-weight: bold;
   color: {$darkgreytext};
 }
 
 .device-desktop .phui-timeline-wedge {
   left: -12px;
 }
 
 .device-desktop .phui-timeline-major-event .phui-timeline-wedge {
   top: 26px;
 }
 
 .device-desktop .phui-timeline-minor-event .phui-timeline-wedge {
   top: 12px;
   left: -18px;
   width: 20px;
 }
 
 .phui-timeline-image {
   background-repeat: no-repeat;
   position: absolute;
   border-radius: 3px;
   background-size: 100%;
   display: block;
 }
 
 .device-desktop .phui-timeline-major-event .phui-timeline-image {
   width: 50px;
   height: 50px;
   top: 0px;
   left: -62px;
 }
 
 .device-desktop .phui-timeline-minor-event .phui-timeline-image {
   width: 26px;
   height: 26px;
   background-size: 26px auto;
   left: -41px;
 }
 
 .phui-timeline-major-event .phui-timeline-title {
   background: {$lightgreybackground};
   min-height: 22px;
   border-top-right-radius: 3px;
   border-top-left-radius: 3px;
 }
 
 .phui-timeline-major-event .phui-timeline-title + .phui-timeline-title {
   border-radius: 0;
   padding-top: 0;
 }
 
 .phui-timeline-major-event .phui-timeline-title + .phui-timeline-title
   .phui-timeline-icon-fill {
     margin-top: 0;
   }
 
 .phui-timeline-title {
   padding: 5px 8px;
   overflow-x: auto;
   overflow-y: hidden;
 }
 
 .phui-timeline-title-with-icon {
   padding-left: 36px;
 }
 
 .phui-timeline-title-with-menu {
   padding-right: 36px;
 }
 
 .phui-timeline-view .phui-icon-view.phui-timeline-token {
   vertical-align: middle;
   margin-right: 4px;
 }
 
 .phui-timeline-token.strikethrough {
   position: relative;
 }
 
 .phui-timeline-token.strikethrough:before {
   position: absolute;
   content: "";
   left: 0;
   top: 50%;
   right: 0;
   border-top: 3px solid;
   border-color: {$darkbluetext};
 
   -webkit-transform:rotate(-40deg);
   -moz-transform:rotate(-40deg);
   -ms-transform:rotate(-40deg);
   -o-transform:rotate(-40deg);
   transform:rotate(-40deg);
 }
 
 .phui-timeline-major-event .phui-timeline-content
   .phui-timeline-core-content {
   padding: 16px;
   line-height: 18px;
   background: {$page.content};
   border-top: 1px solid rgba({$alphablue},.1);
   border-bottom-left-radius: 3px;
   border-bottom-right-radius: 3px;
 }
 
 .phui-timeline-core-content {
   overflow-x: auto;
 }
 
+/*
+ * Start Customization for removed comments
+ * https://we.phorge.it/T15192
+ */
+
 .phui-timeline-core-content .comment-deleted {
   font-style: italic;
 }
+.phui-timeline-shell-removed .phui-timeline-image {
+  opacity: 0.5;
+}
+.phui-timeline-shell-removed,
+.phui-timeline-shell-removed a,
+.phui-timeline-shell-removed .phui-timeline-title {
+  color:#888; /* grey */
+}
+.phui-timeline-shell-removed
+  .phui-timeline-major-event
+    .phui-timeline-content .phui-timeline-core-content {
+      padding:4px 16px; /* reduce vertical space from 16px */
+}
+
+/* End Customization for removed comments */
 
 .device .phui-timeline-event-view {
   min-height: 23px;
   position: relative;
 }
 
 .device-phone .phui-timeline-event-view {
   margin: 0 8px;
 }
 
 .device .phui-timeline-image {
   display: none;
 }
 
 .device .phui-timeline-spacer {
   min-height: 8px;
   border-width: 0;
 }
 
 .phui-timeline-icon-fill {
   position: absolute;
   width: 34px;
   height: 34px;
   top: 0;
   left: 0;
   text-align: center;
 }
 
 .phui-timeline-icon {
   color: {$bluetext};
 }
 
 .phui-icon-view.phui-timeline-icon {
   font-size: 14px;
 }
 
 .phui-timeline-icon-fill {
   height: 26px;
   width: 26px;
   border-radius: 3px;
   background-color: {$timeline.icon.background};
 }
 
 .phui-timeline-major-event .phui-timeline-icon-fill {
   margin: 4px;
 }
 
 .phui-timeline-icon-fill .phui-timeline-icon {
   margin-top: 6px;
 }
 
 .phui-timeline-extra,
 .phui-timeline-extra .phabricator-content-source-view {
   font-size: {$smallerfontsize};
   font-weight: normal;
   color: {$lightgreytext};
   margin-left: 8px;
 }
 
 .phui-timeline-title .phui-timeline-extra a {
   font-weight: normal;
   color: {$lightgreytext};
 }
 
 .phui-timeline-title .phui-timeline-value,
 .conpherence-transaction-content .phui-timeline-value,
 .phui-feed-story-head .phui-timeline-value {
   font-style: italic;
   color: {$blacktext};
 }
 
 .device-desktop .phui-timeline-extra {
   float: right;
 }
 
 .device .phui-timeline-extra {
   display: inline-block;
   line-height: 16px;
   margin-left: 8px;
   white-space: nowrap;
 }
 
 .device-phone .phui-timeline-extra {
   display: block;
   margin: 0;
 }
 
 .phui-timeline-icon-fill.fill-has-color .phui-icon-view {
   color: {$page.content};
 }
 
 .phui-timeline-icon-fill-red {
   background-color: {$red};
 }
 
 .phui-timeline-icon-fill-orange {
   background-color: {$orange};
 }
 
 .phui-timeline-icon-fill-yellow {
   background-color: {$yellow};
 }
 
 .phui-timeline-icon-fill-green {
   background-color: {$green};
 }
 
 .phui-timeline-icon-fill-sky {
   background-color: {$sky};
 }
 
 .phui-timeline-icon-fill-blue {
   background-color: {$blue};
 }
 
 .phui-timeline-icon-fill-indigo {
   background-color: {$indigo};
 }
 
 .phui-timeline-icon-fill-violet {
   background-color: {$violet};
 }
 
 .phui-timeline-icon-fill-pink {
   background-color: {$pink};
 }
 
 .phui-timeline-icon-fill-grey {
   background-color: #888;
 }
 
 .phui-timeline-icon-fill-black {
   background-color: #000;
 }
 
 .phui-timeline-shell.anchor-target {
   background: {$lightyellow};
   border-width: 0 1px 0 0;
   border-style: solid;
   border-color: {$yellow};
   padding: 4px;
   margin: -4px;
 }
 
 .phui-timeline-preview-header {
   background: #e0e3ec;
   color: {$darkgreytext};
   padding: 4px 1.25%;
   border: solid {$blueborder} 1px 0;
 }
 
 .phui-timeline-change-details {
   padding: 10px 0;
   border-style: solid;
   border-color: #efefef;
   border-width: 1px 0;
 }
 
 .phui-timeline-older-transactions-are-hidden {
   background: {$gentle.highlight};
   border: 1px solid {$gentle.highlight.border};
   text-align: center;
   padding: 12px;
   color: {$darkgreytext};
   cursor: pointer;
   border-radius: 3px;
 }
 
 .device-phone .phui-timeline-older-transactions-are-hidden {
   margin: 0 8px;
 }
 
 .phui-timeline-title .phui-timeline-extra-information a {
   font-weight: normal;
   color: {$greytext};
 }
 
 .phui-timeline-comment-actions .phui-icon-view {
   width: 16px;
   height: 16px;
   font-size: 16px;
   text-align: center;
   overflow: hidden;
 }
 
 .phui-timeline-menu {
   position: absolute;
   right: 3px;
   top: 6px;
   width: 28px;
   height: 24px;
   text-align: center;
   line-height: 22px;
   font-size: 16px;
   border-left: 1px solid {$thinblueborder};
 }
 
 .phui-timeline-menu:focus {
   outline: none;
 }
 
 a.phui-timeline-menu .phui-icon-view {
   color: {$bluetext};
 }
 
 .device-desktop a.phui-timeline-menu:hover .phui-icon-view {
   color: {$sky};
 }
 
 .phui-timeline-menu.phuix-dropdown-open {
   background: rgba({$alphablue},0.1);
   border: none;
   border-radius: 3px;
 }
 
 .phui-timeline-view + .phui-object-box {
   margin-top: 0;
 }
 
 .phui-timeline-badges {
   position: absolute;
   left: -64px;
   top: 52px;
   width: 54px;
   text-align: center;
 }
 
 .phui-timeline-badges .phui-badge-mini {
   height: 18px;
   width: 18px;
   line-height: 16px;
 }
 
 .phui-timeline-badges .phui-badge-mini .phui-icon-view {
   font-size: 10px;
 }
 
 .phui-comment-preview-view {
   margin-bottom: 20px;
 }
 
 .phui-timeline-view .phui-pinboard-view {
   margin: 8px 0 0 0;
   padding: 0;
   text-align: left;
 }