Page MenuHomestyx hydra

No OneTemporary

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
index 7aeb049f96..a92d33b71e 100644
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -1,2198 +1,2204 @@
<?php
/**
* This file is automatically generated. Use 'bin/celerity map' to rebuild it.
* @generated
*/
return array(
'names' =>
array(
- 'core.pkg.css' => '9cc0bd27',
+ 'core.pkg.css' => '2ed3f133',
'core.pkg.js' => 'b7bdab05',
'darkconsole.pkg.js' => 'ca8671ce',
'differential.pkg.css' => 'd1b3a605',
'differential.pkg.js' => 'e0d3b0da',
'diffusion.pkg.css' => '3783278d',
'diffusion.pkg.js' => '5b4010f4',
'javelin.pkg.js' => '5b0f988e',
'maniphest.pkg.css' => 'f1887d71',
'maniphest.pkg.js' => '2fe8af22',
'rsrc/css/aphront/aphront-bars.css' => '231ac33c',
'rsrc/css/aphront/aphront-notes.css' => '6acadd3f',
'rsrc/css/aphront/context-bar.css' => '1c3b0529',
'rsrc/css/aphront/dark-console.css' => '6378ef3d',
'rsrc/css/aphront/dialog-view.css' => 'c01d24b4',
'rsrc/css/aphront/error-view.css' => '16cd9949',
'rsrc/css/aphront/lightbox-attachment.css' => '7acac05d',
'rsrc/css/aphront/list-filter-view.css' => 'ef989c67',
'rsrc/css/aphront/multi-column.css' => '12f65921',
'rsrc/css/aphront/notification.css' => '6901121e',
'rsrc/css/aphront/pager-view.css' => '2e3539af',
'rsrc/css/aphront/panel-view.css' => '5846dfa2',
'rsrc/css/aphront/phabricator-nav-view.css' => '80e60fc1',
'rsrc/css/aphront/request-failure-view.css' => 'da14df31',
'rsrc/css/aphront/table-view.css' => '92a719ca',
'rsrc/css/aphront/tokenizer.css' => '36903077',
'rsrc/css/aphront/tooltip.css' => '9c90229d',
'rsrc/css/aphront/transaction.css' => 'ce491938',
'rsrc/css/aphront/two-column.css' => '16ab3ad2',
'rsrc/css/aphront/typeahead.css' => '271456a1',
'rsrc/css/application/auth/auth.css' => '1e655982',
'rsrc/css/application/base/main-menu-view.css' => 'd36e0c11',
'rsrc/css/application/base/notification-menu.css' => 'fc9a363c',
'rsrc/css/application/base/phabricator-application-launch-view.css' => '5cb75f67',
'rsrc/css/application/base/standard-page-view.css' => '517cdfb1',
'rsrc/css/application/chatlog/chatlog.css' => '852140ff',
'rsrc/css/application/config/config-options.css' => '7fedf08b',
'rsrc/css/application/config/config-template.css' => '25d446d6',
'rsrc/css/application/config/setup-issue.css' => '69e640e7',
'rsrc/css/application/conpherence/menu.css' => '561348ac',
'rsrc/css/application/conpherence/message-pane.css' => '2aedca89',
'rsrc/css/application/conpherence/notification.css' => '403cf598',
'rsrc/css/application/conpherence/update.css' => '1099a660',
'rsrc/css/application/conpherence/widget-pane.css' => '87b12e0c',
'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4',
'rsrc/css/application/countdown/timer.css' => '86b7b0a0',
'rsrc/css/application/diff/inline-comment-summary.css' => '14a91639',
'rsrc/css/application/differential/add-comment.css' => 'c478bcaa',
'rsrc/css/application/differential/changeset-view.css' => 'e710a360',
'rsrc/css/application/differential/core.css' => '7ac3cabc',
'rsrc/css/application/differential/local-commits-view.css' => '19649019',
'rsrc/css/application/differential/results-table.css' => '239924f9',
'rsrc/css/application/differential/revision-comment.css' => '48186045',
'rsrc/css/application/differential/revision-history.css' => 'f37aee8f',
'rsrc/css/application/differential/revision-list.css' => 'f3c47d33',
'rsrc/css/application/differential/table-of-contents.css' => '19566f76',
'rsrc/css/application/diffusion/commit-view.css' => '92d1e8f9',
'rsrc/css/application/diffusion/diffusion-icons.css' => '384a0f7d',
'rsrc/css/application/diffusion/diffusion-source.css' => '66fdf661',
'rsrc/css/application/directory/phabricator-jump-nav.css' => 'f0c5e726',
'rsrc/css/application/feed/feed.css' => '0d17c209',
'rsrc/css/application/files/global-drag-and-drop.css' => '697324ad',
'rsrc/css/application/flag/flag.css' => '5337623f',
'rsrc/css/application/herald/herald-test.css' => '2b7d0f54',
'rsrc/css/application/herald/herald.css' => '59d48f01',
'rsrc/css/application/legalpad/legalpad-document.css' => 'cd275275',
'rsrc/css/application/maniphest/batch-editor.css' => '8f380ebc',
'rsrc/css/application/maniphest/report.css' => '6fc16517',
'rsrc/css/application/maniphest/task-edit.css' => '8e23031b',
'rsrc/css/application/maniphest/task-summary.css' => '6df1a768',
'rsrc/css/application/objectselector/object-selector.css' => '029a133d',
'rsrc/css/application/owners/owners-path-editor.css' => '2f00933b',
'rsrc/css/application/paste/paste.css' => 'aa1767d1',
'rsrc/css/application/people/people-profile.css' => 'ba7b2762',
'rsrc/css/application/phame/phame.css' => '450826e1',
'rsrc/css/application/pholio/pholio-edit.css' => 'b9e59b6d',
'rsrc/css/application/pholio/pholio-inline-comments.css' => '52be33f0',
'rsrc/css/application/pholio/pholio.css' => 'd23ace50',
'rsrc/css/application/phortune/phortune-credit-card-form.css' => 'b25b4beb',
'rsrc/css/application/phrequent/phrequent.css' => 'ffc185ad',
'rsrc/css/application/phriction/phriction-document-css.css' => 'b0309d8e',
'rsrc/css/application/policy/policy-edit.css' => '05cca26a',
'rsrc/css/application/policy/policy.css' => '957ea14c',
'rsrc/css/application/ponder/comments.css' => '6cdccea7',
'rsrc/css/application/ponder/feed.css' => 'e62615b6',
'rsrc/css/application/ponder/post.css' => 'ebab8a70',
'rsrc/css/application/ponder/vote.css' => '8ed6ed8b',
'rsrc/css/application/profile/profile-view.css' => '9bdb9804',
'rsrc/css/application/projects/phabricator-object-list-view.css' => '1a1ea560',
'rsrc/css/application/projects/project-tag.css' => '095c9404',
'rsrc/css/application/releeph/releeph-branch.css' => 'b8821d2d',
'rsrc/css/application/releeph/releeph-colors.css' => '2d2d6aa8',
'rsrc/css/application/releeph/releeph-core.css' => '140b959d',
'rsrc/css/application/releeph/releeph-intents.css' => '7364ac97',
'rsrc/css/application/releeph/releeph-preview-branch.css' => '0e383ca3',
'rsrc/css/application/releeph/releeph-project.css' => 'ee1f9f57',
'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd',
'rsrc/css/application/releeph/releeph-request-typeahead.css' => '667a48ae',
'rsrc/css/application/releeph/releeph-status.css' => 'a20631d9',
'rsrc/css/application/search/search-results.css' => 'f240504c',
'rsrc/css/application/settings/settings.css' => 'ea8f5915',
'rsrc/css/application/slowvote/slowvote.css' => '266df6a1',
'rsrc/css/application/tokens/tokens.css' => 'fb286311',
'rsrc/css/application/uiexample/example.css' => '4741b891',
'rsrc/css/core/core.css' => 'da26ddb2',
'rsrc/css/core/remarkup.css' => 'ca7f2265',
'rsrc/css/core/syntax.css' => '3c18c1cb',
'rsrc/css/core/z-index.css' => '0fd29d49',
- 'rsrc/css/diviner/diviner-shared.css' => 'be90f718',
+ 'rsrc/css/diviner/diviner-shared.css' => '38813222',
+ 'rsrc/css/font/font-source-sans-pro.css' => '225851dd',
'rsrc/css/layout/phabricator-action-header-view.css' => 'c14dfc57',
'rsrc/css/layout/phabricator-action-list-view.css' => '81383e25',
'rsrc/css/layout/phabricator-crumbs-view.css' => '2d9db584',
'rsrc/css/layout/phabricator-filetree-view.css' => 'a8c86ace',
'rsrc/css/layout/phabricator-hovercard-view.css' => '67c12b16',
'rsrc/css/layout/phabricator-side-menu-view.css' => '503699d0',
'rsrc/css/layout/phabricator-source-code-view.css' => '62a99814',
'rsrc/css/phui/calendar/phui-calendar-day.css' => 'de035c8a',
'rsrc/css/phui/calendar/phui-calendar-list.css' => 'c1d0ca59',
'rsrc/css/phui/calendar/phui-calendar-month.css' => '5e762971',
'rsrc/css/phui/calendar/phui-calendar.css' => '5e1ad989',
'rsrc/css/phui/phui-box.css' => 'a36cf3a5',
'rsrc/css/phui/phui-button.css' => '8784a966',
- 'rsrc/css/phui/phui-document.css' => '143b2ac8',
+ 'rsrc/css/phui/phui-document.css' => 'b56323cf',
'rsrc/css/phui/phui-feed-story.css' => '3a59c2cf',
+ 'rsrc/css/phui/phui-fontkit.css' => 'de84aa4a',
'rsrc/css/phui/phui-form-view.css' => '0efd3326',
'rsrc/css/phui/phui-form.css' => 'b78ec020',
- 'rsrc/css/phui/phui-header-view.css' => '472a6003',
+ 'rsrc/css/phui/phui-header-view.css' => 'b76a37b3',
'rsrc/css/phui/phui-icon.css' => '7a5771a9',
'rsrc/css/phui/phui-info-panel.css' => '27ea50a1',
'rsrc/css/phui/phui-list.css' => '2edb76cf',
'rsrc/css/phui/phui-object-box.css' => 'ce92d8ec',
'rsrc/css/phui/phui-object-item-list-view.css' => '4e4e3d4c',
'rsrc/css/phui/phui-pinboard-view.css' => '4b346c2a',
'rsrc/css/phui/phui-property-list-view.css' => 'dbf53b12',
'rsrc/css/phui/phui-remarkup-preview.css' => '19ad512b',
'rsrc/css/phui/phui-spacing.css' => '042804d6',
'rsrc/css/phui/phui-status.css' => '2f562399',
'rsrc/css/phui/phui-tag-view.css' => '295d81c4',
'rsrc/css/phui/phui-text.css' => '23e9b4b7',
'rsrc/css/phui/phui-timeline-view.css' => 'd3ccba00',
'rsrc/css/phui/phui-workboard-view.css' => 'bf70dd2e',
'rsrc/css/phui/phui-workpanel-view.css' => '97b69459',
'rsrc/css/sprite-actions.css' => '969ad0e5',
'rsrc/css/sprite-apps-large.css' => '5abf49e9',
'rsrc/css/sprite-apps-xlarge.css' => 'db66c878',
'rsrc/css/sprite-apps.css' => '6973a52b',
'rsrc/css/sprite-buttonbar.css' => 'ba1c5738',
'rsrc/css/sprite-conpherence.css' => '3b4a0487',
'rsrc/css/sprite-docs.css' => '5f65d0da',
'rsrc/css/sprite-gradient.css' => 'a10def53',
'rsrc/css/sprite-icons.css' => 'f19a828c',
'rsrc/css/sprite-login.css' => '9fbaec81',
'rsrc/css/sprite-main-header.css' => '92720ee2',
'rsrc/css/sprite-menu.css' => '8da53882',
'rsrc/css/sprite-minicons.css' => 'df4f76fe',
'rsrc/css/sprite-payments.css' => 'cc085d44',
'rsrc/css/sprite-projects.css' => '7578fa56',
'rsrc/css/sprite-status.css' => '8bce1c97',
'rsrc/css/sprite-tokens.css' => '1706b943',
+ 'rsrc/externals/font/SourceSansPro.woff' => '44e50175',
+ 'rsrc/externals/font/SourceSansProBold.woff' => '8799f025',
'rsrc/externals/javelin/core/Event.js' => '79473b62',
'rsrc/externals/javelin/core/Stratcom.js' => 'c293f7b9',
'rsrc/externals/javelin/core/__tests__/event-stop-and-kill.js' => '717554e4',
'rsrc/externals/javelin/core/__tests__/install.js' => 'c432ee85',
'rsrc/externals/javelin/core/__tests__/stratcom.js' => 'da194d4b',
'rsrc/externals/javelin/core/__tests__/util.js' => 'd3b157a9',
'rsrc/externals/javelin/core/init.js' => 'b88ab49e',
'rsrc/externals/javelin/core/init_node.js' => 'd7dde471',
'rsrc/externals/javelin/core/install.js' => '52a92793',
'rsrc/externals/javelin/core/util.js' => '7501647b',
'rsrc/externals/javelin/docs/Base.js' => '897bb199',
'rsrc/externals/javelin/docs/onload.js' => '81fb4862',
'rsrc/externals/javelin/ext/fx/Color.js' => '7e41274a',
'rsrc/externals/javelin/ext/fx/FX.js' => '54b612ba',
'rsrc/externals/javelin/ext/reactor/core/DynVal.js' => 'f6555212',
'rsrc/externals/javelin/ext/reactor/core/Reactor.js' => '77b1cf6f',
'rsrc/externals/javelin/ext/reactor/core/ReactorNode.js' => 'b4c30592',
'rsrc/externals/javelin/ext/reactor/core/ReactorNodeCalmer.js' => '76f4ebed',
'rsrc/externals/javelin/ext/reactor/dom/RDOM.js' => 'b6d401d6',
'rsrc/externals/javelin/ext/view/HTMLView.js' => 'e5b406f9',
'rsrc/externals/javelin/ext/view/View.js' => '0f764c35',
'rsrc/externals/javelin/ext/view/ViewInterpreter.js' => '0c33c1a0',
'rsrc/externals/javelin/ext/view/ViewPlaceholder.js' => '2fa810fc',
'rsrc/externals/javelin/ext/view/ViewRenderer.js' => '6c2b09a2',
'rsrc/externals/javelin/ext/view/ViewVisitor.js' => 'efe49472',
'rsrc/externals/javelin/ext/view/__tests__/HTMLView.js' => 'f92d7bcb',
'rsrc/externals/javelin/ext/view/__tests__/View.js' => 'bda69c40',
'rsrc/externals/javelin/ext/view/__tests__/ViewInterpreter.js' => '7a94d6a5',
'rsrc/externals/javelin/ext/view/__tests__/ViewRenderer.js' => '5426001c',
'rsrc/externals/javelin/lib/Cookie.js' => '6b3dcf44',
'rsrc/externals/javelin/lib/DOM.js' => '5054855f',
'rsrc/externals/javelin/lib/History.js' => 'c60f4327',
'rsrc/externals/javelin/lib/JSON.js' => '08e56a4e',
'rsrc/externals/javelin/lib/Mask.js' => 'b9f26029',
'rsrc/externals/javelin/lib/Request.js' => '23f9bb8d',
'rsrc/externals/javelin/lib/Resource.js' => '356de121',
'rsrc/externals/javelin/lib/URI.js' => 'd9a9b862',
'rsrc/externals/javelin/lib/Vector.js' => '403a3dce',
'rsrc/externals/javelin/lib/Workflow.js' => 'd16edeae',
'rsrc/externals/javelin/lib/__tests__/Cookie.js' => '5ed109e8',
'rsrc/externals/javelin/lib/__tests__/DOM.js' => 'c984504b',
'rsrc/externals/javelin/lib/__tests__/JSON.js' => '2295d074',
'rsrc/externals/javelin/lib/__tests__/URI.js' => '003ed329',
'rsrc/externals/javelin/lib/__tests__/behavior.js' => '1ea62783',
'rsrc/externals/javelin/lib/behavior.js' => '8a3ed18b',
'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => 'e7c21fb3',
'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => 'c54eeefb',
'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => '5f850b5c',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '84f34ab1',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => 'a79b75a4',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js' => 'f778a573',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '62e18640',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => 'cdde23f1',
'rsrc/externals/raphael/g.raphael.js' => '40dde778',
'rsrc/externals/raphael/g.raphael.line.js' => '40da039e',
'rsrc/externals/raphael/raphael.js' => '51ee6b43',
'rsrc/image/BFCFDA.png' => 'd5ec91f4',
'rsrc/image/actions/edit.png' => '2fc41442',
'rsrc/image/apple-touch-icon.png' => '8458dda7',
'rsrc/image/avatar.png' => '62c5f933',
'rsrc/image/checker_dark.png' => 'd8e65881',
'rsrc/image/checker_light.png' => 'a0155918',
'rsrc/image/credit_cards.png' => '72b8ede8',
'rsrc/image/darkload.gif' => '1ffd3ec6',
'rsrc/image/divot.png' => '94dded62',
'rsrc/image/grippy_texture.png' => 'aca81e2f',
'rsrc/image/icon/fatcow/arrow_branch.png' => '2537c01c',
'rsrc/image/icon/fatcow/arrow_merge.png' => '21b660e0',
'rsrc/image/icon/fatcow/bullet_black.png' => 'ff190031',
'rsrc/image/icon/fatcow/bullet_orange.png' => 'e273e5bb',
'rsrc/image/icon/fatcow/bullet_red.png' => 'c0b75434',
'rsrc/image/icon/fatcow/calendar_edit.png' => '24632275',
'rsrc/image/icon/fatcow/document_black.png' => '45fe1c60',
'rsrc/image/icon/fatcow/flag_blue.png' => 'a01abb1d',
'rsrc/image/icon/fatcow/flag_finish.png' => '67825cee',
'rsrc/image/icon/fatcow/flag_ghost.png' => '20ca8783',
'rsrc/image/icon/fatcow/flag_green.png' => '7e0eaa7a',
'rsrc/image/icon/fatcow/flag_orange.png' => '9e73df66',
'rsrc/image/icon/fatcow/flag_pink.png' => '7e92f3b2',
'rsrc/image/icon/fatcow/flag_purple.png' => 'cc517522',
'rsrc/image/icon/fatcow/flag_red.png' => '04ec726f',
'rsrc/image/icon/fatcow/flag_yellow.png' => '73946fd4',
'rsrc/image/icon/fatcow/folder.png' => '95a435af',
'rsrc/image/icon/fatcow/folder_go.png' => '001cbc94',
'rsrc/image/icon/fatcow/key_question.png' => '52a0c26a',
'rsrc/image/icon/fatcow/link.png' => '7afd4d5e',
'rsrc/image/icon/fatcow/page_white_edit.png' => '39a2eed8',
'rsrc/image/icon/fatcow/page_white_link.png' => 'a90023c7',
'rsrc/image/icon/fatcow/page_white_put.png' => '08c95a0c',
'rsrc/image/icon/fatcow/page_white_text.png' => '1e1f79c3',
'rsrc/image/icon/fatcow/source/conduit.png' => '4ea01d2f',
'rsrc/image/icon/fatcow/source/email.png' => '9bab3239',
'rsrc/image/icon/fatcow/source/fax.png' => '04195e68',
'rsrc/image/icon/fatcow/source/mobile.png' => 'f1321264',
'rsrc/image/icon/fatcow/source/tablet.png' => '49396799',
'rsrc/image/icon/fatcow/source/web.png' => '136ccb5d',
'rsrc/image/icon/fatcow/thumbnails/default160x120.png' => 'f2e8a2eb',
'rsrc/image/icon/fatcow/thumbnails/default60x45.png' => '0118abed',
'rsrc/image/icon/fatcow/thumbnails/image160x120.png' => '79bb556a',
'rsrc/image/icon/fatcow/thumbnails/image60x45.png' => 'c5e1685e',
'rsrc/image/icon/fatcow/thumbnails/pdf160x120.png' => 'ac9edbf5',
'rsrc/image/icon/fatcow/thumbnails/pdf60x45.png' => 'c0db4143',
'rsrc/image/icon/fatcow/thumbnails/zip160x120.png' => '75f9cd0f',
'rsrc/image/icon/fatcow/thumbnails/zip60x45.png' => 'af11bf3e',
'rsrc/image/icon/lightbox/close-2.png' => 'cc40e7c8',
'rsrc/image/icon/lightbox/close-hover-2.png' => 'fb5d6d9e',
'rsrc/image/icon/lightbox/left-arrow-2.png' => '8426133b',
'rsrc/image/icon/lightbox/left-arrow-hover-2.png' => '701e5ee3',
'rsrc/image/icon/lightbox/right-arrow-2.png' => '6d5519a0',
'rsrc/image/icon/lightbox/right-arrow-hover-2.png' => '3a04aa21',
'rsrc/image/icon/subscribe.png' => 'd03ed5a5',
'rsrc/image/icon/tango/attachment.png' => 'ecc8022e',
'rsrc/image/icon/tango/edit.png' => '929a1363',
'rsrc/image/icon/tango/go-down.png' => '96d95e43',
'rsrc/image/icon/tango/log.png' => 'b08cc63a',
'rsrc/image/icon/tango/upload.png' => '7bbb7984',
'rsrc/image/icon/unsubscribe.png' => '25725013',
'rsrc/image/lightblue-header.png' => '5c168b6d',
'rsrc/image/loading.gif' => '75d384cc',
'rsrc/image/loading/boating_24.gif' => '5c90f086',
'rsrc/image/loading/compass_24.gif' => 'b36b4f46',
'rsrc/image/loading/loading_24.gif' => '26bc9adc',
'rsrc/image/loading/loading_48.gif' => '6a4994c7',
'rsrc/image/loading/loading_d48.gif' => 'cdcbe900',
'rsrc/image/loading/loading_w24.gif' => '7662fa2b',
'rsrc/image/main_texture.png' => '29a2c5ad',
'rsrc/image/menu_texture.png' => '5a17580d',
'rsrc/image/people/harding.png' => '45aa614e',
'rsrc/image/people/jefferson.png' => 'afca0e53',
'rsrc/image/people/lincoln.png' => '9369126d',
'rsrc/image/people/mckinley.png' => 'fb8f16ce',
'rsrc/image/people/taft.png' => 'd7bc402c',
'rsrc/image/people/washington.png' => '40dd301c',
'rsrc/image/phrequent_active.png' => 'a466a8ed',
'rsrc/image/phrequent_inactive.png' => 'bfc15a69',
'rsrc/image/search-white.png' => '64cc0d45',
'rsrc/image/search.png' => '82625a7e',
'rsrc/image/sprite-actions-X2.png' => '7dfd5652',
'rsrc/image/sprite-actions.png' => '2ddd18c3',
'rsrc/image/sprite-apps-X2.png' => 'c091b2d3',
'rsrc/image/sprite-apps-large-X2.png' => 'e1396a83',
'rsrc/image/sprite-apps-large.png' => '48cef7bd',
'rsrc/image/sprite-apps-xlarge.png' => 'a751a580',
'rsrc/image/sprite-apps.png' => '4f788e21',
'rsrc/image/sprite-buttonbar-X2.png' => '2c09a184',
'rsrc/image/sprite-buttonbar.png' => 'e98e96af',
'rsrc/image/sprite-conpherence-X2.png' => 'cd2d08d7',
'rsrc/image/sprite-conpherence.png' => 'a5ab2eb7',
'rsrc/image/sprite-docs-X2.png' => '6dc1adad',
'rsrc/image/sprite-docs.png' => '4636297f',
'rsrc/image/sprite-gradient.png' => '4ece0b62',
'rsrc/image/sprite-icons-X2.png' => '0d5867c0',
'rsrc/image/sprite-icons.png' => '3f754bda',
'rsrc/image/sprite-login-X2.png' => '81c1344f',
'rsrc/image/sprite-login.png' => '7c729508',
'rsrc/image/sprite-main-header.png' => '83521873',
'rsrc/image/sprite-menu-X2.png' => '949974c6',
'rsrc/image/sprite-menu.png' => '307d5da0',
'rsrc/image/sprite-minicons-X2.png' => '55377e4e',
'rsrc/image/sprite-minicons.png' => '272644ea',
'rsrc/image/sprite-payments.png' => 'd8576309',
'rsrc/image/sprite-projects-X2.png' => '218fdc8b',
'rsrc/image/sprite-projects.png' => '631ff9a7',
'rsrc/image/sprite-status-X2.png' => '82445ee0',
'rsrc/image/sprite-status.png' => '926a896a',
'rsrc/image/sprite-tokens-X2.png' => 'b4776580',
'rsrc/image/sprite-tokens.png' => '25b75533',
'rsrc/image/texture/card-gradient.png' => '815f26e8',
'rsrc/image/texture/dark-menu-hover.png' => '5fa7ece8',
'rsrc/image/texture/dark-menu.png' => '7e22296e',
'rsrc/image/texture/grip.png' => '719404f3',
'rsrc/image/texture/panel-header-gradient.png' => 'e3b8dcfe',
'rsrc/image/texture/phlnx-bg.png' => '8d819209',
'rsrc/image/texture/pholio-background.gif' => 'ba29239c',
'rsrc/image/texture/table_header.png' => '5c433037',
'rsrc/image/texture/table_header_hover.png' => '038ec3b9',
'rsrc/image/texture/table_header_tall.png' => 'd56b434f',
'rsrc/js/application/aphlict/Aphlict.js' => '493665ee',
'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => '2a2dba85',
'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => '845731b8',
'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18',
'rsrc/js/application/config/behavior-reorder-fields.js' => '938aed89',
'rsrc/js/application/conpherence/behavior-menu.js' => '7ee23816',
'rsrc/js/application/conpherence/behavior-pontificate.js' => '53f6f2dd',
'rsrc/js/application/conpherence/behavior-widget-pane.js' => 'd8ef8659',
'rsrc/js/application/countdown/timer.js' => '889c96f3',
'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => 'f2441746',
'rsrc/js/application/differential/behavior-accept-with-errors.js' => 'e12c760a',
'rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js' => '533a187b',
'rsrc/js/application/differential/behavior-comment-jump.js' => '71755c79',
'rsrc/js/application/differential/behavior-comment-preview.js' => '127f2018',
'rsrc/js/application/differential/behavior-diff-radios.js' => 'e1ff79b1',
'rsrc/js/application/differential/behavior-dropdown-menus.js' => '5f004630',
'rsrc/js/application/differential/behavior-edit-inline-comments.js' => '00861799',
'rsrc/js/application/differential/behavior-keyboard-nav.js' => '173ce7e7',
'rsrc/js/application/differential/behavior-populate.js' => 'ce0c217a',
'rsrc/js/application/differential/behavior-show-all-comments.js' => '7c273581',
'rsrc/js/application/differential/behavior-show-field-details.js' => '441f2137',
'rsrc/js/application/differential/behavior-show-more.js' => 'dd7e8ef5',
'rsrc/js/application/differential/behavior-toggle-files.js' => 'ca3f91eb',
'rsrc/js/application/differential/behavior-user-select.js' => 'a8d8459d',
'rsrc/js/application/diffusion/behavior-audit-preview.js' => 'be81801d',
'rsrc/js/application/diffusion/behavior-commit-branches.js' => 'bdaf4d04',
'rsrc/js/application/diffusion/behavior-commit-graph.js' => 'f7f1289f',
'rsrc/js/application/diffusion/behavior-jump-to.js' => '9db3d160',
'rsrc/js/application/diffusion/behavior-load-blame.js' => '42126667',
'rsrc/js/application/diffusion/behavior-pull-lastmodified.js' => '75903ee1',
'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => 'e5822781',
'rsrc/js/application/files/behavior-icon-composer.js' => '8ef9ab58',
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
'rsrc/js/application/harbormaster/behavior-reorder-steps.js' => '957a7fde',
'rsrc/js/application/herald/HeraldRuleEditor.js' => '4f31d692',
'rsrc/js/application/herald/PathTypeahead.js' => 'f7fc67ec',
'rsrc/js/application/herald/herald-rule-editor.js' => '7ebaeed3',
'rsrc/js/application/maniphest/behavior-batch-editor.js' => '391457d7',
'rsrc/js/application/maniphest/behavior-batch-selector.js' => 'ead554ec',
'rsrc/js/application/maniphest/behavior-line-chart.js' => '64ef2fd2',
'rsrc/js/application/maniphest/behavior-list-edit.js' => 'cf76cfd5',
'rsrc/js/application/maniphest/behavior-subpriorityeditor.js' => '84845b5b',
'rsrc/js/application/maniphest/behavior-transaction-controls.js' => 'dddd43ac',
'rsrc/js/application/maniphest/behavior-transaction-expand.js' => '2f2e18aa',
'rsrc/js/application/maniphest/behavior-transaction-preview.js' => 'f8248bc5',
'rsrc/js/application/owners/OwnersPathEditor.js' => '46efd18e',
'rsrc/js/application/owners/owners-path-editor.js' => '7a68dda3',
'rsrc/js/application/passphrase/phame-credential-control.js' => '1e1c8a59',
'rsrc/js/application/phame/phame-post-preview.js' => '61d927ec',
'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => '1e1e8bb0',
'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => '28497740',
'rsrc/js/application/phortune/behavior-balanced-payment-form.js' => '3b3e1664',
'rsrc/js/application/phortune/behavior-stripe-payment-form.js' => '1693a296',
'rsrc/js/application/phortune/behavior-test-payment-form.js' => 'b3e5ee60',
'rsrc/js/application/phortune/phortune-credit-card-form.js' => '2290aeef',
'rsrc/js/application/policy/behavior-policy-control.js' => 'c01153ea',
'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '263aeb8c',
'rsrc/js/application/ponder/behavior-votebox.js' => '327dbe61',
'rsrc/js/application/projects/behavior-project-boards.js' => '04c59172',
'rsrc/js/application/projects/behavior-project-create.js' => '065227cc',
'rsrc/js/application/releeph/releeph-preview-branch.js' => '9eb2cedb',
'rsrc/js/application/releeph/releeph-request-state-change.js' => 'fe7fc914',
'rsrc/js/application/releeph/releeph-request-typeahead.js' => 'cd9e7094',
'rsrc/js/application/repository/repository-crossreference.js' => '8ab282be',
'rsrc/js/application/search/behavior-reorder-queries.js' => '37871df4',
'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => 'a51fdb2e',
'rsrc/js/application/transactions/behavior-transaction-comment-form.js' => '9084a36f',
'rsrc/js/application/transactions/behavior-transaction-list.js' => '3c918aa8',
'rsrc/js/application/uiexample/JavelinViewExample.js' => 'd4a14807',
'rsrc/js/application/uiexample/ReactorButtonExample.js' => '44524435',
'rsrc/js/application/uiexample/ReactorCheckboxExample.js' => '7ba325ee',
'rsrc/js/application/uiexample/ReactorFocusExample.js' => '82f568cd',
'rsrc/js/application/uiexample/ReactorInputExample.js' => 'd6ca6b1c',
'rsrc/js/application/uiexample/ReactorMouseoverExample.js' => '4e37e4de',
'rsrc/js/application/uiexample/ReactorRadioExample.js' => '858f9728',
'rsrc/js/application/uiexample/ReactorSelectExample.js' => '189e4fe3',
'rsrc/js/application/uiexample/ReactorSendClassExample.js' => 'bf97561d',
'rsrc/js/application/uiexample/ReactorSendPropertiesExample.js' => '551add57',
'rsrc/js/application/uiexample/busy-example.js' => 'fbbce3bf',
'rsrc/js/application/uiexample/gesture-example.js' => 'f42bb8c6',
'rsrc/js/application/uiexample/notification-example.js' => 'c51a6616',
'rsrc/js/core/Busy.js' => '6453c869',
'rsrc/js/core/DragAndDropFileUpload.js' => 'ae6abfba',
'rsrc/js/core/DraggableList.js' => '1681c4d4',
'rsrc/js/core/DropdownMenu.js' => 'fb342e18',
'rsrc/js/core/DropdownMenuItem.js' => '0f386ef4',
'rsrc/js/core/FileUpload.js' => 'a4ae61bf',
'rsrc/js/core/Hovercard.js' => '4f344388',
'rsrc/js/core/KeyboardShortcut.js' => '1ae869f2',
'rsrc/js/core/KeyboardShortcutManager.js' => 'ad7a69ca',
'rsrc/js/core/MultirowRowManager.js' => '50395a1b',
'rsrc/js/core/Notification.js' => '0c6946e7',
'rsrc/js/core/Prefab.js' => '0326e5d0',
'rsrc/js/core/ShapedRequest.js' => 'dfa181a4',
'rsrc/js/core/TextAreaUtils.js' => 'b3ec3cfc',
'rsrc/js/core/ToolTip.js' => '0a81ea29',
'rsrc/js/core/behavior-active-nav.js' => 'c81bc98f',
'rsrc/js/core/behavior-audio-source.js' => '59b251eb',
'rsrc/js/core/behavior-autofocus.js' => '7319e029',
'rsrc/js/core/behavior-crop.js' => 'b98fc918',
'rsrc/js/core/behavior-dark-console.js' => 'e9fdb5e5',
'rsrc/js/core/behavior-device.js' => '03d6ed07',
'rsrc/js/core/behavior-drag-and-drop-textarea.js' => '4a11ea9c',
'rsrc/js/core/behavior-error-log.js' => 'a5d7cf86',
'rsrc/js/core/behavior-fancy-datepicker.js' => '5d584426',
'rsrc/js/core/behavior-file-tree.js' => 'c8728c70',
'rsrc/js/core/behavior-form.js' => '27d4da3f',
'rsrc/js/core/behavior-gesture.js' => 'fe2e0ba4',
'rsrc/js/core/behavior-global-drag-and-drop.js' => '8fd76bab',
'rsrc/js/core/behavior-history-install.js' => '7ee2b591',
'rsrc/js/core/behavior-hovercard.js' => '9c808199',
'rsrc/js/core/behavior-keyboard-pager.js' => 'b657bdf8',
'rsrc/js/core/behavior-keyboard-shortcuts.js' => 'd75709e6',
'rsrc/js/core/behavior-konami.js' => '5bc2cb21',
'rsrc/js/core/behavior-lightbox-attachments.js' => '3aa45ad9',
'rsrc/js/core/behavior-line-linker.js' => 'bc778103',
'rsrc/js/core/behavior-more.js' => '9b9197be',
'rsrc/js/core/behavior-object-selector.js' => 'b4eef37b',
'rsrc/js/core/behavior-oncopy.js' => 'dab9253e',
'rsrc/js/core/behavior-phabricator-nav.js' => 'b5842a5e',
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'c021950a',
'rsrc/js/core/behavior-refresh-csrf.js' => 'c4b31646',
'rsrc/js/core/behavior-remarkup-preview.js' => 'f7379f45',
'rsrc/js/core/behavior-reveal-content.js' => '8f24abfc',
'rsrc/js/core/behavior-search-typeahead.js' => 'f6b56f7a',
'rsrc/js/core/behavior-select-on-click.js' => '0e34ca02',
'rsrc/js/core/behavior-toggle-class.js' => 'a82a7769',
'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884',
'rsrc/js/core/behavior-tooltip.js' => 'e5dd1c6d',
'rsrc/js/core/behavior-watch-anchor.js' => '06e05112',
'rsrc/js/core/behavior-workflow.js' => '82947dda',
'rsrc/js/core/phtize.js' => 'd254d646',
'rsrc/js/phui/behavior-phui-object-box-tabs.js' => 'a3e2244e',
'rsrc/swf/aphlict.swf' => 'abac967d',
),
'symbols' =>
array(
'aphront-bars' => '231ac33c',
'aphront-contextbar-view-css' => '1c3b0529',
'aphront-dark-console-css' => '6378ef3d',
'aphront-dialog-view-css' => 'c01d24b4',
'aphront-error-view-css' => '16cd9949',
'aphront-list-filter-view-css' => 'ef989c67',
'aphront-multi-column-view-css' => '12f65921',
'aphront-notes' => '6acadd3f',
'aphront-pager-view-css' => '2e3539af',
'aphront-panel-view-css' => '5846dfa2',
'aphront-request-failure-view-css' => 'da14df31',
'aphront-table-view-css' => '92a719ca',
'aphront-tokenizer-control-css' => '36903077',
'aphront-tooltip-css' => '9c90229d',
'aphront-two-column-view-css' => '16ab3ad2',
'aphront-typeahead-control-css' => '271456a1',
'auth-css' => '1e655982',
'config-options-css' => '7fedf08b',
'conpherence-menu-css' => '561348ac',
'conpherence-message-pane-css' => '2aedca89',
'conpherence-notification-css' => '403cf598',
'conpherence-update-css' => '1099a660',
'conpherence-widget-pane-css' => '87b12e0c',
'differential-changeset-view-css' => 'e710a360',
'differential-core-view-css' => '7ac3cabc',
'differential-inline-comment-editor' => 'f2441746',
'differential-local-commits-view-css' => '19649019',
'differential-results-table-css' => '239924f9',
'differential-revision-add-comment-css' => 'c478bcaa',
'differential-revision-comment-css' => '48186045',
'differential-revision-history-css' => 'f37aee8f',
'differential-revision-list-css' => 'f3c47d33',
'differential-table-of-contents-css' => '19566f76',
'diffusion-commit-view-css' => '92d1e8f9',
'diffusion-icons-css' => '384a0f7d',
'diffusion-source-css' => '66fdf661',
- 'diviner-shared-css' => 'be90f718',
+ 'diviner-shared-css' => '38813222',
+ 'font-source-sans-pro' => '225851dd',
'global-drag-and-drop-css' => '697324ad',
'herald-css' => '59d48f01',
'herald-rule-editor' => '4f31d692',
'herald-test-css' => '2b7d0f54',
'inline-comment-summary-css' => '14a91639',
'javelin-aphlict' => '493665ee',
'javelin-behavior' => '8a3ed18b',
'javelin-behavior-aphlict-dropdown' => '2a2dba85',
'javelin-behavior-aphlict-listen' => '845731b8',
'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884',
'javelin-behavior-aphront-crop' => 'b98fc918',
'javelin-behavior-aphront-drag-and-drop-textarea' => '4a11ea9c',
'javelin-behavior-aphront-form-disable-on-submit' => '27d4da3f',
'javelin-behavior-aphront-more' => '9b9197be',
'javelin-behavior-audio-source' => '59b251eb',
'javelin-behavior-audit-preview' => 'be81801d',
'javelin-behavior-balanced-payment-form' => '3b3e1664',
'javelin-behavior-config-reorder-fields' => '938aed89',
'javelin-behavior-conpherence-menu' => '7ee23816',
'javelin-behavior-conpherence-pontificate' => '53f6f2dd',
'javelin-behavior-conpherence-widget-pane' => 'd8ef8659',
'javelin-behavior-countdown-timer' => '889c96f3',
'javelin-behavior-dark-console' => 'e9fdb5e5',
'javelin-behavior-device' => '03d6ed07',
'javelin-behavior-differential-accept-with-errors' => 'e12c760a',
'javelin-behavior-differential-add-reviewers-and-ccs' => '533a187b',
'javelin-behavior-differential-comment-jump' => '71755c79',
'javelin-behavior-differential-diff-radios' => 'e1ff79b1',
'javelin-behavior-differential-dropdown-menus' => '5f004630',
'javelin-behavior-differential-edit-inline-comments' => '00861799',
'javelin-behavior-differential-feedback-preview' => '127f2018',
'javelin-behavior-differential-keyboard-navigation' => '173ce7e7',
'javelin-behavior-differential-populate' => 'ce0c217a',
'javelin-behavior-differential-show-field-details' => '441f2137',
'javelin-behavior-differential-show-more' => 'dd7e8ef5',
'javelin-behavior-differential-toggle-files' => 'ca3f91eb',
'javelin-behavior-differential-user-select' => 'a8d8459d',
'javelin-behavior-diffusion-commit-branches' => 'bdaf4d04',
'javelin-behavior-diffusion-commit-graph' => 'f7f1289f',
'javelin-behavior-diffusion-jump-to' => '9db3d160',
'javelin-behavior-diffusion-pull-lastmodified' => '75903ee1',
'javelin-behavior-doorkeeper-tag' => 'e5822781',
'javelin-behavior-error-log' => 'a5d7cf86',
'javelin-behavior-fancy-datepicker' => '5d584426',
'javelin-behavior-global-drag-and-drop' => '8fd76bab',
'javelin-behavior-harbormaster-reorder-steps' => '957a7fde',
'javelin-behavior-herald-rule-editor' => '7ebaeed3',
'javelin-behavior-history-install' => '7ee2b591',
'javelin-behavior-icon-composer' => '8ef9ab58',
'javelin-behavior-konami' => '5bc2cb21',
'javelin-behavior-launch-icon-composer' => '48086888',
'javelin-behavior-lightbox-attachments' => '3aa45ad9',
'javelin-behavior-line-chart' => '64ef2fd2',
'javelin-behavior-load-blame' => '42126667',
'javelin-behavior-maniphest-batch-editor' => '391457d7',
'javelin-behavior-maniphest-batch-selector' => 'ead554ec',
'javelin-behavior-maniphest-list-editor' => 'cf76cfd5',
'javelin-behavior-maniphest-subpriority-editor' => '84845b5b',
'javelin-behavior-maniphest-transaction-controls' => 'dddd43ac',
'javelin-behavior-maniphest-transaction-expand' => '2f2e18aa',
'javelin-behavior-maniphest-transaction-preview' => 'f8248bc5',
'javelin-behavior-owners-path-editor' => '7a68dda3',
'javelin-behavior-passphrase-credential-control' => '1e1c8a59',
'javelin-behavior-persona-login' => '9414ff18',
'javelin-behavior-phabricator-active-nav' => 'c81bc98f',
'javelin-behavior-phabricator-autofocus' => '7319e029',
'javelin-behavior-phabricator-busy-example' => 'fbbce3bf',
'javelin-behavior-phabricator-file-tree' => 'c8728c70',
'javelin-behavior-phabricator-gesture' => 'fe2e0ba4',
'javelin-behavior-phabricator-gesture-example' => 'f42bb8c6',
'javelin-behavior-phabricator-hovercards' => '9c808199',
'javelin-behavior-phabricator-keyboard-pager' => 'b657bdf8',
'javelin-behavior-phabricator-keyboard-shortcuts' => 'd75709e6',
'javelin-behavior-phabricator-line-linker' => 'bc778103',
'javelin-behavior-phabricator-nav' => 'b5842a5e',
'javelin-behavior-phabricator-notification-example' => 'c51a6616',
'javelin-behavior-phabricator-object-selector' => 'b4eef37b',
'javelin-behavior-phabricator-oncopy' => 'dab9253e',
'javelin-behavior-phabricator-remarkup-assist' => 'c021950a',
'javelin-behavior-phabricator-reveal-content' => '8f24abfc',
'javelin-behavior-phabricator-search-typeahead' => 'f6b56f7a',
'javelin-behavior-phabricator-show-all-transactions' => '7c273581',
'javelin-behavior-phabricator-tooltips' => 'e5dd1c6d',
'javelin-behavior-phabricator-transaction-comment-form' => '9084a36f',
'javelin-behavior-phabricator-transaction-list' => '3c918aa8',
'javelin-behavior-phabricator-watch-anchor' => '06e05112',
'javelin-behavior-phame-post-preview' => '61d927ec',
'javelin-behavior-pholio-mock-edit' => '1e1e8bb0',
'javelin-behavior-pholio-mock-view' => '28497740',
'javelin-behavior-phui-object-box-tabs' => 'a3e2244e',
'javelin-behavior-policy-control' => 'c01153ea',
'javelin-behavior-policy-rule-editor' => '263aeb8c',
'javelin-behavior-ponder-votebox' => '327dbe61',
'javelin-behavior-project-boards' => '04c59172',
'javelin-behavior-project-create' => '065227cc',
'javelin-behavior-refresh-csrf' => 'c4b31646',
'javelin-behavior-releeph-preview-branch' => '9eb2cedb',
'javelin-behavior-releeph-request-state-change' => 'fe7fc914',
'javelin-behavior-releeph-request-typeahead' => 'cd9e7094',
'javelin-behavior-remarkup-preview' => 'f7379f45',
'javelin-behavior-repository-crossreference' => '8ab282be',
'javelin-behavior-search-reorder-queries' => '37871df4',
'javelin-behavior-select-on-click' => '0e34ca02',
'javelin-behavior-slowvote-embed' => 'a51fdb2e',
'javelin-behavior-stripe-payment-form' => '1693a296',
'javelin-behavior-test-payment-form' => 'b3e5ee60',
'javelin-behavior-toggle-class' => 'a82a7769',
'javelin-behavior-view-placeholder' => '2fa810fc',
'javelin-behavior-workflow' => '82947dda',
'javelin-color' => '7e41274a',
'javelin-cookie' => '6b3dcf44',
'javelin-dom' => '5054855f',
'javelin-dynval' => 'f6555212',
'javelin-event' => '79473b62',
'javelin-fx' => '54b612ba',
'javelin-history' => 'c60f4327',
'javelin-install' => '52a92793',
'javelin-json' => '08e56a4e',
'javelin-magical-init' => 'b88ab49e',
'javelin-mask' => 'b9f26029',
'javelin-reactor' => '77b1cf6f',
'javelin-reactor-dom' => 'b6d401d6',
'javelin-reactor-node-calmer' => '76f4ebed',
'javelin-reactornode' => 'b4c30592',
'javelin-request' => '23f9bb8d',
'javelin-resource' => '356de121',
'javelin-stratcom' => 'c293f7b9',
'javelin-tokenizer' => 'e7c21fb3',
'javelin-typeahead' => 'c54eeefb',
'javelin-typeahead-composite-source' => '84f34ab1',
'javelin-typeahead-normalizer' => '5f850b5c',
'javelin-typeahead-ondemand-source' => 'a79b75a4',
'javelin-typeahead-preloaded-source' => 'f778a573',
'javelin-typeahead-source' => '62e18640',
'javelin-typeahead-static-source' => 'cdde23f1',
'javelin-uri' => 'd9a9b862',
'javelin-util' => '7501647b',
'javelin-vector' => '403a3dce',
'javelin-view' => '0f764c35',
'javelin-view-html' => 'e5b406f9',
'javelin-view-interpreter' => '0c33c1a0',
'javelin-view-renderer' => '6c2b09a2',
'javelin-view-visitor' => 'efe49472',
'javelin-workflow' => 'd16edeae',
'legalpad-document-css' => 'cd275275',
'lightbox-attachment-css' => '7acac05d',
'maniphest-batch-editor' => '8f380ebc',
'maniphest-report-css' => '6fc16517',
'maniphest-task-edit-css' => '8e23031b',
'maniphest-task-summary-css' => '6df1a768',
'multirow-row-manager' => '50395a1b',
'owners-path-editor' => '46efd18e',
'owners-path-editor-css' => '2f00933b',
'paste-css' => 'aa1767d1',
'path-typeahead' => 'f7fc67ec',
'people-profile-css' => 'ba7b2762',
'phabricator-action-header-view-css' => 'c14dfc57',
'phabricator-action-list-view-css' => '81383e25',
'phabricator-application-launch-view-css' => '5cb75f67',
'phabricator-busy' => '6453c869',
'phabricator-chatlog-css' => '852140ff',
'phabricator-content-source-view-css' => '4b8b05d4',
'phabricator-core-css' => 'da26ddb2',
'phabricator-countdown-css' => '86b7b0a0',
'phabricator-crumbs-view-css' => '2d9db584',
'phabricator-drag-and-drop-file-upload' => 'ae6abfba',
'phabricator-draggable-list' => '1681c4d4',
'phabricator-dropdown-menu' => 'fb342e18',
'phabricator-fatal-config-template-css' => '25d446d6',
'phabricator-feed-css' => '0d17c209',
'phabricator-file-upload' => 'a4ae61bf',
'phabricator-filetree-view-css' => 'a8c86ace',
'phabricator-flag-css' => '5337623f',
'phabricator-hovercard' => '4f344388',
'phabricator-hovercard-view-css' => '67c12b16',
'phabricator-jump-nav' => 'f0c5e726',
'phabricator-keyboard-shortcut' => '1ae869f2',
'phabricator-keyboard-shortcut-manager' => 'ad7a69ca',
'phabricator-main-menu-view' => 'd36e0c11',
'phabricator-menu-item' => '0f386ef4',
'phabricator-nav-view-css' => '80e60fc1',
'phabricator-notification' => '0c6946e7',
'phabricator-notification-css' => '6901121e',
'phabricator-notification-menu-css' => 'fc9a363c',
'phabricator-object-list-view-css' => '1a1ea560',
'phabricator-object-selector-css' => '029a133d',
'phabricator-phtize' => 'd254d646',
'phabricator-prefab' => '0326e5d0',
'phabricator-profile-css' => '9bdb9804',
'phabricator-project-tag-css' => '095c9404',
'phabricator-remarkup-css' => 'ca7f2265',
'phabricator-search-results-css' => 'f240504c',
'phabricator-settings-css' => 'ea8f5915',
'phabricator-shaped-request' => 'dfa181a4',
'phabricator-side-menu-view-css' => '503699d0',
'phabricator-slowvote-css' => '266df6a1',
'phabricator-source-code-view-css' => '62a99814',
'phabricator-standard-page-view' => '517cdfb1',
'phabricator-textareautils' => 'b3ec3cfc',
'phabricator-tooltip' => '0a81ea29',
'phabricator-transaction-view-css' => 'ce491938',
'phabricator-ui-example-css' => '4741b891',
'phabricator-uiexample-javelin-view' => 'd4a14807',
'phabricator-uiexample-reactor-button' => '44524435',
'phabricator-uiexample-reactor-checkbox' => '7ba325ee',
'phabricator-uiexample-reactor-focus' => '82f568cd',
'phabricator-uiexample-reactor-input' => 'd6ca6b1c',
'phabricator-uiexample-reactor-mouseover' => '4e37e4de',
'phabricator-uiexample-reactor-radio' => '858f9728',
'phabricator-uiexample-reactor-select' => '189e4fe3',
'phabricator-uiexample-reactor-sendclass' => 'bf97561d',
'phabricator-uiexample-reactor-sendproperties' => '551add57',
'phabricator-zindex-css' => '0fd29d49',
'phame-css' => '450826e1',
'pholio-css' => 'd23ace50',
'pholio-edit-css' => 'b9e59b6d',
'pholio-inline-comments-css' => '52be33f0',
'phortune-credit-card-form' => '2290aeef',
'phortune-credit-card-form-css' => 'b25b4beb',
'phrequent-css' => 'ffc185ad',
'phriction-document-css' => 'b0309d8e',
'phui-box-css' => 'a36cf3a5',
'phui-button-css' => '8784a966',
'phui-calendar-css' => '5e1ad989',
'phui-calendar-day-css' => 'de035c8a',
'phui-calendar-list-css' => 'c1d0ca59',
'phui-calendar-month-css' => '5e762971',
- 'phui-document-view-css' => '143b2ac8',
+ 'phui-document-view-css' => 'b56323cf',
'phui-feed-story-css' => '3a59c2cf',
+ 'phui-fontkit-css' => 'de84aa4a',
'phui-form-css' => 'b78ec020',
'phui-form-view-css' => '0efd3326',
- 'phui-header-view-css' => '472a6003',
+ 'phui-header-view-css' => 'b76a37b3',
'phui-icon-view-css' => '7a5771a9',
'phui-info-panel-css' => '27ea50a1',
'phui-list-view-css' => '2edb76cf',
'phui-object-box-css' => 'ce92d8ec',
'phui-object-item-list-view-css' => '4e4e3d4c',
'phui-pinboard-view-css' => '4b346c2a',
'phui-property-list-view-css' => 'dbf53b12',
'phui-remarkup-preview-css' => '19ad512b',
'phui-spacing-css' => '042804d6',
'phui-status-list-view-css' => '2f562399',
'phui-tag-view-css' => '295d81c4',
'phui-text-css' => '23e9b4b7',
'phui-timeline-view-css' => 'd3ccba00',
'phui-workboard-view-css' => 'bf70dd2e',
'phui-workpanel-view-css' => '97b69459',
'policy-css' => '957ea14c',
'policy-edit-css' => '05cca26a',
'ponder-comment-table-css' => '6cdccea7',
'ponder-feed-view-css' => 'e62615b6',
'ponder-post-css' => 'ebab8a70',
'ponder-vote-css' => '8ed6ed8b',
'raphael-core' => '51ee6b43',
'raphael-g' => '40dde778',
'raphael-g-line' => '40da039e',
'releeph-branch' => 'b8821d2d',
'releeph-colors' => '2d2d6aa8',
'releeph-core' => '140b959d',
'releeph-intents' => '7364ac97',
'releeph-preview-branch' => '0e383ca3',
'releeph-project' => 'ee1f9f57',
'releeph-request-differential-create-dialog' => '8d8b92cd',
'releeph-request-typeahead-css' => '667a48ae',
'releeph-status' => 'a20631d9',
'setup-issue-css' => '69e640e7',
'sprite-actions-css' => '969ad0e5',
'sprite-apps-css' => '6973a52b',
'sprite-apps-large-css' => '5abf49e9',
'sprite-apps-xlarge-css' => 'db66c878',
'sprite-buttonbar-css' => 'ba1c5738',
'sprite-conpherence-css' => '3b4a0487',
'sprite-docs-css' => '5f65d0da',
'sprite-gradient-css' => 'a10def53',
'sprite-icons-css' => 'f19a828c',
'sprite-login-css' => '9fbaec81',
'sprite-main-header-css' => '92720ee2',
'sprite-menu-css' => '8da53882',
'sprite-minicons-css' => 'df4f76fe',
'sprite-payments-css' => 'cc085d44',
'sprite-projects-css' => '7578fa56',
'sprite-status-css' => '8bce1c97',
'sprite-tokens-css' => '1706b943',
'syntax-highlighting-css' => '3c18c1cb',
'tokens-css' => 'fb286311',
),
'requires' =>
array(
'00861799' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-util',
4 => 'javelin-vector',
5 => 'differential-inline-comment-editor',
),
'029a133d' =>
array(
0 => 'aphront-dialog-view-css',
),
'0326e5d0' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-typeahead',
4 => 'javelin-tokenizer',
5 => 'javelin-typeahead-preloaded-source',
6 => 'javelin-typeahead-ondemand-source',
7 => 'javelin-dom',
8 => 'javelin-stratcom',
9 => 'javelin-util',
),
'03d6ed07' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-vector',
4 => 'javelin-install',
),
'04c59172' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-stratcom',
4 => 'javelin-workflow',
5 => 'phabricator-draggable-list',
),
'065227cc' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-workflow',
),
'06e05112' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-vector',
),
'08e56a4e' =>
array(
0 => 'javelin-install',
),
'0a81ea29' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-vector',
),
'0c33c1a0' =>
array(
0 => 'javelin-view',
1 => 'javelin-install',
2 => 'javelin-dom',
),
'0c6946e7' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-util',
4 => 'phabricator-notification-css',
),
'0e34ca02' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'0f386ef4' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
),
'0f764c35' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'127f2018' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-request',
4 => 'javelin-util',
5 => 'phabricator-shaped-request',
),
'1681c4d4' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-util',
4 => 'javelin-vector',
5 => 'javelin-magical-init',
),
'1693a296' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phortune-credit-card-form',
),
'173ce7e7' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'phabricator-keyboard-shortcut',
),
'189e4fe3' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-reactor-dom',
),
'1ae869f2' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'phabricator-keyboard-shortcut-manager',
),
'1e1c8a59' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-workflow',
4 => 'javelin-util',
5 => 'javelin-uri',
),
'1e1e8bb0' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-workflow',
4 => 'phabricator-phtize',
5 => 'phabricator-drag-and-drop-file-upload',
6 => 'phabricator-draggable-list',
),
'2290aeef' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-json',
3 => 'javelin-workflow',
4 => 'javelin-util',
),
'23f9bb8d' =>
array(
0 => 'javelin-install',
1 => 'javelin-stratcom',
2 => 'javelin-util',
3 => 'javelin-behavior',
4 => 'javelin-json',
5 => 'javelin-dom',
6 => 'javelin-resource',
),
'263aeb8c' =>
array(
0 => 'javelin-behavior',
1 => 'multirow-row-manager',
2 => 'javelin-dom',
3 => 'javelin-util',
4 => 'phabricator-prefab',
5 => 'javelin-tokenizer',
6 => 'javelin-typeahead',
7 => 'javelin-typeahead-preloaded-source',
8 => 'javelin-json',
),
'27d4da3f' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'2a2dba85' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-request',
2 => 'javelin-stratcom',
3 => 'javelin-vector',
4 => 'javelin-dom',
5 => 'javelin-uri',
6 => 'javelin-behavior-device',
),
'2f2e18aa' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-workflow',
3 => 'javelin-stratcom',
),
'2fa810fc' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-view-renderer',
3 => 'javelin-install',
),
'327dbe61' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-stratcom',
4 => 'javelin-request',
),
'356de121' =>
array(
0 => 'javelin-util',
1 => 'javelin-uri',
2 => 'javelin-install',
),
'37871df4' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-workflow',
3 => 'javelin-dom',
4 => 'phabricator-draggable-list',
),
'391457d7' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-prefab',
4 => 'multirow-row-manager',
5 => 'javelin-json',
),
'3aa45ad9' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-mask',
4 => 'javelin-util',
5 => 'phabricator-busy',
),
'3b3e1664' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phortune-credit-card-form',
),
'3c918aa8' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-workflow',
3 => 'javelin-dom',
4 => 'javelin-fx',
),
'403a3dce' =>
array(
0 => 'javelin-install',
1 => 'javelin-event',
),
'441f2137' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'46efd18e' =>
array(
0 => 'multirow-row-manager',
1 => 'javelin-install',
2 => 'path-typeahead',
3 => 'javelin-dom',
4 => 'javelin-util',
5 => 'phabricator-prefab',
),
'493665ee' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'4a11ea9c' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phabricator-drag-and-drop-file-upload',
3 => 'phabricator-textareautils',
),
'4e37e4de' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-reactor-dom',
),
'4f31d692' =>
array(
0 => 'multirow-row-manager',
1 => 'javelin-install',
2 => 'javelin-typeahead',
3 => 'javelin-util',
4 => 'javelin-dom',
5 => 'javelin-tokenizer',
6 => 'javelin-typeahead-preloaded-source',
7 => 'javelin-stratcom',
8 => 'javelin-json',
9 => 'phabricator-prefab',
),
'4f344388' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-vector',
3 => 'javelin-request',
4 => 'javelin-uri',
),
'50395a1b' =>
array(
0 => 'javelin-install',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-util',
),
'5054855f' =>
array(
0 => 'javelin-magical-init',
1 => 'javelin-install',
2 => 'javelin-util',
3 => 'javelin-vector',
4 => 'javelin-stratcom',
),
'52a92793' =>
array(
0 => 'javelin-util',
1 => 'javelin-magical-init',
),
'533a187b' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phabricator-prefab',
),
'53f6f2dd' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-workflow',
4 => 'javelin-stratcom',
),
'54b612ba' =>
array(
0 => 'javelin-color',
1 => 'javelin-install',
2 => 'javelin-util',
),
'551add57' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-reactor-dom',
),
'59b251eb' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-vector',
3 => 'javelin-dom',
),
'5bc2cb21' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
),
'5d584426' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-stratcom',
4 => 'javelin-vector',
),
'5f004630' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-stratcom',
4 => 'phabricator-dropdown-menu',
5 => 'phabricator-menu-item',
6 => 'phabricator-phtize',
),
'5f850b5c' =>
array(
0 => 'javelin-install',
),
'61d927ec' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'62e18640' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-typeahead-normalizer',
),
'6453c869' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-fx',
),
'64ef2fd2' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-vector',
),
'6b3dcf44' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'6c2b09a2' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'71755c79' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'7319e029' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'75903ee1' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-request',
),
'76f4ebed' =>
array(
0 => 'javelin-install',
1 => 'javelin-reactor',
2 => 'javelin-util',
),
'77b1cf6f' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'79473b62' =>
array(
0 => 'javelin-install',
),
'7a68dda3' =>
array(
0 => 'owners-path-editor',
1 => 'javelin-behavior',
),
'7ba325ee' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-reactor-dom',
),
'7c273581' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'7e41274a' =>
array(
0 => 'javelin-install',
),
'7ebaeed3' =>
array(
0 => 'herald-rule-editor',
1 => 'javelin-behavior',
),
'7ee23816' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-stratcom',
4 => 'javelin-workflow',
5 => 'javelin-behavior-device',
6 => 'javelin-history',
7 => 'javelin-vector',
8 => 'phabricator-shaped-request',
),
'7ee2b591' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-history',
),
'82947dda' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-workflow',
3 => 'javelin-dom',
),
'82f568cd' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-reactor-dom',
),
'845731b8' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-aphlict',
2 => 'javelin-stratcom',
3 => 'javelin-request',
4 => 'javelin-uri',
5 => 'javelin-dom',
6 => 'javelin-json',
7 => 'phabricator-notification',
),
'84845b5b' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-workflow',
4 => 'phabricator-draggable-list',
),
'84f34ab1' =>
array(
0 => 'javelin-install',
1 => 'javelin-typeahead-source',
2 => 'javelin-util',
),
'858f9728' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-reactor-dom',
),
'889c96f3' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'8a3ed18b' =>
array(
0 => 'javelin-magical-init',
1 => 'javelin-util',
),
'8ab282be' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-uri',
),
'8ef9ab58' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
),
'8f24abfc' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'8fd76bab' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-uri',
3 => 'javelin-mask',
4 => 'phabricator-drag-and-drop-file-upload',
),
'9084a36f' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-fx',
4 => 'javelin-request',
5 => 'phabricator-shaped-request',
),
'938aed89' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-json',
4 => 'phabricator-draggable-list',
),
'9414ff18' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-resource',
2 => 'javelin-stratcom',
3 => 'javelin-workflow',
4 => 'javelin-util',
),
'957a7fde' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-workflow',
3 => 'javelin-dom',
4 => 'phabricator-draggable-list',
),
'9b9197be' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'9c808199' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-behavior-device',
2 => 'javelin-stratcom',
3 => 'javelin-vector',
4 => 'phabricator-hovercard',
),
'9db3d160' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-vector',
2 => 'javelin-dom',
),
'9eb2cedb' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-uri',
3 => 'javelin-request',
),
'a3e2244e' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'a4ae61bf' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'phabricator-notification',
),
'a51fdb2e' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-request',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
),
'a5d7cf86' =>
array(
0 => 'javelin-dom',
),
'a79b75a4' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-request',
3 => 'javelin-typeahead-source',
),
'a82a7769' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'a8d8459d' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
),
'ad7a69ca' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
4 => 'javelin-vector',
),
'ae6abfba' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-request',
3 => 'javelin-dom',
4 => 'javelin-uri',
5 => 'phabricator-file-upload',
),
'b3a4b884' =>
array(
0 => 'javelin-behavior',
1 => 'phabricator-prefab',
),
'b3e5ee60' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phortune-credit-card-form',
),
'b3ec3cfc' =>
array(
0 => 'javelin-install',
),
'b4c30592' =>
array(
0 => 'javelin-install',
1 => 'javelin-reactor',
2 => 'javelin-util',
3 => 'javelin-reactor-node-calmer',
),
'b4eef37b' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-request',
3 => 'javelin-util',
),
'b5842a5e' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-behavior-device',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
4 => 'javelin-magical-init',
5 => 'javelin-vector',
6 => 'javelin-request',
7 => 'javelin-util',
),
'b657bdf8' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-uri',
2 => 'phabricator-keyboard-shortcut',
),
'b6d401d6' =>
array(
0 => 'javelin-dom',
1 => 'javelin-dynval',
2 => 'javelin-reactor',
3 => 'javelin-reactornode',
4 => 'javelin-install',
5 => 'javelin-util',
),
'b98fc918' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-vector',
3 => 'javelin-magical-init',
),
'b9f26029' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
),
'bc778103' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-history',
),
'bdaf4d04' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-request',
),
'be81801d' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'bf97561d' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-reactor-dom',
),
'c01153ea' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-dropdown-menu',
4 => 'phabricator-menu-item',
5 => 'javelin-workflow',
),
'c021950a' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'phabricator-phtize',
4 => 'phabricator-textareautils',
5 => 'javelin-workflow',
6 => 'javelin-vector',
),
'c293f7b9' =>
array(
0 => 'javelin-install',
1 => 'javelin-event',
2 => 'javelin-util',
3 => 'javelin-magical-init',
),
'c4b31646' =>
array(
0 => 'javelin-request',
1 => 'javelin-behavior',
2 => 'javelin-dom',
3 => 'phabricator-busy',
),
'c51a6616' =>
array(
0 => 'phabricator-notification',
1 => 'javelin-stratcom',
2 => 'javelin-behavior',
),
'c54eeefb' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-vector',
3 => 'javelin-util',
),
'c60f4327' =>
array(
0 => 'javelin-stratcom',
1 => 'javelin-install',
2 => 'javelin-uri',
3 => 'javelin-util',
),
'c81bc98f' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-vector',
3 => 'javelin-dom',
4 => 'javelin-uri',
),
'c8728c70' =>
array(
0 => 'javelin-behavior',
1 => 'phabricator-keyboard-shortcut',
2 => 'javelin-stratcom',
),
'ca3f91eb' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'phabricator-phtize',
),
'cd9e7094' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-typeahead',
3 => 'javelin-typeahead-ondemand-source',
4 => 'javelin-dom',
),
'cdde23f1' =>
array(
0 => 'javelin-install',
1 => 'javelin-typeahead-source',
),
'ce0c217a' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-workflow',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-stratcom',
5 => 'javelin-behavior-device',
6 => 'javelin-vector',
7 => 'phabricator-tooltip',
),
'cf76cfd5' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-workflow',
4 => 'javelin-fx',
5 => 'javelin-util',
),
'd16edeae' =>
array(
0 => 'javelin-stratcom',
1 => 'javelin-request',
2 => 'javelin-dom',
3 => 'javelin-vector',
4 => 'javelin-install',
5 => 'javelin-util',
6 => 'javelin-mask',
7 => 'javelin-uri',
),
'd254d646' =>
array(
0 => 'javelin-util',
),
'd4a14807' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-view',
),
'd6ca6b1c' =>
array(
0 => 'javelin-install',
1 => 'javelin-reactor-dom',
2 => 'javelin-view-html',
3 => 'javelin-view-interpreter',
4 => 'javelin-view-renderer',
),
'd75709e6' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-workflow',
2 => 'javelin-json',
3 => 'javelin-dom',
4 => 'phabricator-keyboard-shortcut',
),
'd8ef8659' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-workflow',
4 => 'javelin-util',
5 => 'phabricator-notification',
6 => 'javelin-behavior-device',
7 => 'phabricator-dropdown-menu',
8 => 'phabricator-menu-item',
),
'd9a9b862' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-stratcom',
),
'dab9253e' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'dd7e8ef5' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-workflow',
3 => 'javelin-util',
4 => 'javelin-stratcom',
),
'dddd43ac' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phabricator-prefab',
),
'dfa181a4' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-request',
),
'e12c760a' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'e1ff79b1' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'e5822781' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-json',
3 => 'javelin-workflow',
4 => 'javelin-magical-init',
),
'e5b406f9' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-view-visitor',
3 => 'javelin-util',
),
'e5dd1c6d' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-behavior-device',
2 => 'javelin-stratcom',
3 => 'phabricator-tooltip',
),
'e7c21fb3' =>
array(
0 => 'javelin-dom',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-install',
),
'e9fdb5e5' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-request',
5 => 'phabricator-keyboard-shortcut',
),
'ead554ec' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-util',
),
'efe49472' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'f2441746' =>
array(
0 => 'javelin-dom',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-install',
4 => 'javelin-request',
5 => 'javelin-workflow',
),
'f42bb8c6' =>
array(
0 => 'javelin-stratcom',
1 => 'javelin-behavior',
2 => 'javelin-vector',
3 => 'javelin-dom',
),
'f6555212' =>
array(
0 => 'javelin-install',
1 => 'javelin-reactornode',
2 => 'javelin-util',
3 => 'javelin-reactor',
),
'f6b56f7a' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-typeahead-ondemand-source',
2 => 'javelin-typeahead',
3 => 'javelin-dom',
4 => 'javelin-uri',
5 => 'javelin-util',
6 => 'javelin-stratcom',
),
'f7379f45' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'f778a573' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-request',
3 => 'javelin-typeahead-source',
),
'f7f1289f' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
),
'f7fc67ec' =>
array(
0 => 'javelin-install',
1 => 'javelin-typeahead',
2 => 'javelin-dom',
3 => 'javelin-request',
4 => 'javelin-typeahead-ondemand-source',
5 => 'javelin-util',
),
'f8248bc5' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-json',
4 => 'javelin-stratcom',
5 => 'phabricator-shaped-request',
),
'fb342e18' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-vector',
4 => 'javelin-stratcom',
5 => 'phabricator-menu-item',
),
'fbbce3bf' =>
array(
0 => 'phabricator-busy',
1 => 'javelin-behavior',
),
'fe2e0ba4' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-behavior-device',
2 => 'javelin-stratcom',
3 => 'javelin-vector',
4 => 'javelin-dom',
5 => 'javelin-magical-init',
),
'fe7fc914' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-request',
4 => 'phabricator-keyboard-shortcut',
5 => 'phabricator-notification',
),
28497740 =>
array(
0 => 'javelin-behavior',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
4 => 'javelin-vector',
5 => 'javelin-magical-init',
6 => 'javelin-request',
7 => 'javelin-history',
8 => 'javelin-workflow',
9 => 'javelin-mask',
10 => 'javelin-behavior-device',
11 => 'phabricator-keyboard-shortcut',
),
36903077 =>
array(
0 => 'aphront-typeahead-control-css',
),
42126667 =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-request',
),
44524435 =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-dynval',
4 => 'javelin-reactor-dom',
),
48086888 =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-workflow',
),
),
'packages' =>
array(
'core.pkg.css' =>
array(
0 => 'phabricator-core-css',
1 => 'phabricator-zindex-css',
2 => 'phui-button-css',
3 => 'phabricator-standard-page-view',
4 => 'aphront-dialog-view-css',
5 => 'phui-form-view-css',
6 => 'aphront-panel-view-css',
7 => 'aphront-table-view-css',
8 => 'aphront-tokenizer-control-css',
9 => 'aphront-typeahead-control-css',
10 => 'aphront-list-filter-view-css',
11 => 'phabricator-jump-nav',
12 => 'phabricator-remarkup-css',
13 => 'syntax-highlighting-css',
14 => 'aphront-pager-view-css',
15 => 'phabricator-transaction-view-css',
16 => 'aphront-tooltip-css',
17 => 'phabricator-flag-css',
18 => 'aphront-error-view-css',
19 => 'sprite-icons-css',
20 => 'sprite-gradient-css',
21 => 'sprite-menu-css',
22 => 'sprite-apps-large-css',
23 => 'sprite-status-css',
24 => 'phabricator-main-menu-view',
25 => 'phabricator-notification-css',
26 => 'phabricator-notification-menu-css',
27 => 'lightbox-attachment-css',
28 => 'phui-header-view-css',
29 => 'phabricator-filetree-view-css',
30 => 'phabricator-nav-view-css',
31 => 'phabricator-side-menu-view-css',
32 => 'phabricator-crumbs-view-css',
33 => 'phui-object-item-list-view-css',
34 => 'global-drag-and-drop-css',
35 => 'phui-spacing-css',
36 => 'phui-form-css',
37 => 'phui-icon-view-css',
38 => 'phabricator-application-launch-view-css',
39 => 'phabricator-action-list-view-css',
40 => 'phui-property-list-view-css',
41 => 'phui-tag-view-css',
42 => 'phui-list-view-css',
),
'core.pkg.js' =>
array(
0 => 'javelin-behavior-aphront-basic-tokenizer',
1 => 'javelin-behavior-workflow',
2 => 'javelin-behavior-aphront-form-disable-on-submit',
3 => 'phabricator-keyboard-shortcut-manager',
4 => 'phabricator-keyboard-shortcut',
5 => 'javelin-behavior-phabricator-keyboard-shortcuts',
6 => 'javelin-behavior-refresh-csrf',
7 => 'javelin-behavior-phabricator-watch-anchor',
8 => 'javelin-behavior-phabricator-autofocus',
9 => 'phabricator-menu-item',
10 => 'phabricator-dropdown-menu',
11 => 'phabricator-phtize',
12 => 'javelin-behavior-phabricator-oncopy',
13 => 'phabricator-tooltip',
14 => 'javelin-behavior-phabricator-tooltips',
15 => 'phabricator-prefab',
16 => 'javelin-behavior-device',
17 => 'javelin-behavior-toggle-class',
18 => 'javelin-behavior-lightbox-attachments',
19 => 'phabricator-busy',
20 => 'javelin-aphlict',
21 => 'phabricator-notification',
22 => 'javelin-behavior-aphlict-listen',
23 => 'javelin-behavior-phabricator-search-typeahead',
24 => 'javelin-behavior-konami',
25 => 'javelin-behavior-aphlict-dropdown',
26 => 'javelin-behavior-history-install',
27 => 'javelin-behavior-phabricator-gesture',
28 => 'javelin-behavior-phabricator-active-nav',
29 => 'javelin-behavior-phabricator-nav',
30 => 'javelin-behavior-phabricator-remarkup-assist',
31 => 'phabricator-textareautils',
32 => 'phabricator-file-upload',
33 => 'javelin-behavior-global-drag-and-drop',
34 => 'javelin-behavior-phabricator-reveal-content',
35 => 'phabricator-hovercard',
36 => 'javelin-behavior-phabricator-hovercards',
37 => 'javelin-color',
38 => 'javelin-fx',
),
'darkconsole.pkg.js' =>
array(
0 => 'javelin-behavior-dark-console',
1 => 'javelin-behavior-error-log',
),
'differential.pkg.css' =>
array(
0 => 'differential-core-view-css',
1 => 'differential-changeset-view-css',
2 => 'differential-results-table-css',
3 => 'differential-revision-history-css',
4 => 'differential-revision-list-css',
5 => 'differential-table-of-contents-css',
6 => 'differential-revision-comment-css',
7 => 'differential-revision-add-comment-css',
8 => 'phabricator-object-selector-css',
9 => 'phabricator-content-source-view-css',
10 => 'differential-local-commits-view-css',
11 => 'inline-comment-summary-css',
),
'differential.pkg.js' =>
array(
0 => 'phabricator-drag-and-drop-file-upload',
1 => 'phabricator-shaped-request',
2 => 'javelin-behavior-differential-feedback-preview',
3 => 'javelin-behavior-differential-edit-inline-comments',
4 => 'javelin-behavior-differential-populate',
5 => 'javelin-behavior-differential-show-more',
6 => 'javelin-behavior-differential-diff-radios',
7 => 'javelin-behavior-differential-accept-with-errors',
8 => 'javelin-behavior-differential-comment-jump',
9 => 'javelin-behavior-differential-add-reviewers-and-ccs',
10 => 'javelin-behavior-differential-keyboard-navigation',
11 => 'javelin-behavior-aphront-drag-and-drop-textarea',
12 => 'javelin-behavior-phabricator-object-selector',
13 => 'javelin-behavior-repository-crossreference',
14 => 'javelin-behavior-load-blame',
15 => 'differential-inline-comment-editor',
16 => 'javelin-behavior-differential-dropdown-menus',
17 => 'javelin-behavior-differential-toggle-files',
18 => 'javelin-behavior-differential-user-select',
),
'diffusion.pkg.css' =>
array(
0 => 'diffusion-commit-view-css',
1 => 'diffusion-icons-css',
),
'diffusion.pkg.js' =>
array(
0 => 'javelin-behavior-diffusion-pull-lastmodified',
1 => 'javelin-behavior-diffusion-commit-graph',
2 => 'javelin-behavior-audit-preview',
),
'javelin.pkg.js' =>
array(
0 => 'javelin-util',
1 => 'javelin-install',
2 => 'javelin-event',
3 => 'javelin-stratcom',
4 => 'javelin-behavior',
5 => 'javelin-resource',
6 => 'javelin-request',
7 => 'javelin-vector',
8 => 'javelin-dom',
9 => 'javelin-json',
10 => 'javelin-uri',
11 => 'javelin-workflow',
12 => 'javelin-mask',
13 => 'javelin-typeahead',
14 => 'javelin-typeahead-normalizer',
15 => 'javelin-typeahead-source',
16 => 'javelin-typeahead-preloaded-source',
17 => 'javelin-typeahead-ondemand-source',
18 => 'javelin-tokenizer',
19 => 'javelin-history',
),
'maniphest.pkg.css' =>
array(
0 => 'maniphest-task-summary-css',
1 => 'phabricator-project-tag-css',
),
'maniphest.pkg.js' =>
array(
0 => 'javelin-behavior-maniphest-batch-selector',
1 => 'javelin-behavior-maniphest-transaction-controls',
2 => 'javelin-behavior-maniphest-transaction-preview',
3 => 'javelin-behavior-maniphest-transaction-expand',
4 => 'javelin-behavior-maniphest-subpriority-editor',
),
),
);
diff --git a/src/aphront/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/configuration/AphrontDefaultApplicationConfiguration.php
index b67954185a..d42d0f0317 100644
--- a/src/aphront/configuration/AphrontDefaultApplicationConfiguration.php
+++ b/src/aphront/configuration/AphrontDefaultApplicationConfiguration.php
@@ -1,284 +1,284 @@
<?php
/**
* NOTE: Do not extend this!
*
* @concrete-extensible
* @group aphront
*/
class AphrontDefaultApplicationConfiguration
extends AphrontApplicationConfiguration {
public function __construct() {
}
public function getApplicationName() {
return 'aphront-default';
}
public function getURIMap() {
return $this->getResourceURIMapRules() + array(
'/oauthserver/' => array(
'auth/' => 'PhabricatorOAuthServerAuthController',
'test/' => 'PhabricatorOAuthServerTestController',
'token/' => 'PhabricatorOAuthServerTokenController',
'clientauthorization/' => array(
'' => 'PhabricatorOAuthClientAuthorizationListController',
'delete/(?P<phid>[^/]+)/' =>
'PhabricatorOAuthClientAuthorizationDeleteController',
'edit/(?P<phid>[^/]+)/' =>
'PhabricatorOAuthClientAuthorizationEditController',
),
'client/' => array(
'' => 'PhabricatorOAuthClientListController',
'create/' => 'PhabricatorOAuthClientEditController',
'delete/(?P<phid>[^/]+)/' => 'PhabricatorOAuthClientDeleteController',
'edit/(?P<phid>[^/]+)/' => 'PhabricatorOAuthClientEditController',
'view/(?P<phid>[^/]+)/' => 'PhabricatorOAuthClientViewController',
),
),
'/~/' => array(
'' => 'DarkConsoleController',
'data/(?P<key>[^/]+)/' => 'DarkConsoleDataController',
),
'/status/' => 'PhabricatorStatusController',
'/help/' => array(
'keyboardshortcut/' => 'PhabricatorHelpKeyboardShortcutController',
),
'/debug/' => 'PhabricatorDebugController',
);
}
protected function getResourceURIMapRules() {
return array(
'/res/' => array(
'(?:(?P<mtime>[0-9]+)T/)?'.
'(?P<library>[^/]+)/'.
'(?P<hash>[a-f0-9]{8})/'.
- '(?P<path>.+\.(?:css|js|jpg|png|swf|gif))'
+ '(?P<path>.+\.(?:css|js|jpg|png|swf|gif|woff))'
=> 'CelerityPhabricatorResourceController',
),
);
}
/**
* @phutil-external-symbol class PhabricatorStartup
*/
public function buildRequest() {
$parser = new PhutilQueryStringParser();
$data = array();
// If the request has "multipart/form-data" content, we can't use
// PhutilQueryStringParser to parse it, and the raw data supposedly is not
// available anyway (according to the PHP documentation, "php://input" is
// not available for "multipart/form-data" requests). However, it is
// available at least some of the time (see T3673), so double check that
// we aren't trying to parse data we won't be able to parse correctly by
// examining the Content-Type header.
$content_type = idx($_SERVER, 'CONTENT_TYPE');
$is_form_data = preg_match('@^multipart/form-data@i', $content_type);
$raw_input = PhabricatorStartup::getRawInput();
if (strlen($raw_input) && !$is_form_data) {
$data += $parser->parseQueryString($raw_input);
} else if ($_POST) {
$data += $_POST;
}
$data += $parser->parseQueryString(idx($_SERVER, 'QUERY_STRING', ''));
$cookie_prefix = PhabricatorEnv::getEnvConfig('phabricator.cookie-prefix');
$request = new AphrontRequest($this->getHost(), $this->getPath());
$request->setRequestData($data);
$request->setApplicationConfiguration($this);
$request->setCookiePrefix($cookie_prefix);
return $request;
}
public function handleException(Exception $ex) {
$request = $this->getRequest();
// For Conduit requests, return a Conduit response.
if ($request->isConduit()) {
$response = new ConduitAPIResponse();
$response->setErrorCode(get_class($ex));
$response->setErrorInfo($ex->getMessage());
return id(new AphrontJSONResponse())
->setAddJSONShield(false)
->setContent($response->toDictionary());
}
// For non-workflow requests, return a Ajax response.
if ($request->isAjax() && !$request->isJavelinWorkflow()) {
// Log these; they don't get shown on the client and can be difficult
// to debug.
phlog($ex);
$response = new AphrontAjaxResponse();
$response->setError(
array(
'code' => get_class($ex),
'info' => $ex->getMessage(),
));
return $response;
}
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
$user = $request->getUser();
if (!$user) {
// If we hit an exception very early, we won't have a user.
$user = new PhabricatorUser();
}
if ($ex instanceof PhabricatorPolicyException) {
if (!$user->isLoggedIn()) {
// If the user isn't logged in, just give them a login form. This is
// probably a generally more useful response than a policy dialog that
// they have to click through to get a login form.
//
// Possibly we should add a header here like "you need to login to see
// the thing you are trying to look at".
$login_controller = new PhabricatorAuthStartController($request);
$auth_app_class = 'PhabricatorApplicationAuth';
$auth_app = PhabricatorApplication::getByClass($auth_app_class);
$login_controller->setCurrentApplication($auth_app);
return $login_controller->processRequest();
}
$list = $ex->getMoreInfo();
foreach ($list as $key => $item) {
$list[$key] = phutil_tag('li', array(), $item);
}
if ($list) {
$list = phutil_tag('ul', array(), $list);
}
$content = array(
phutil_tag(
'div',
array(
'class' => 'aphront-policy-rejection',
),
$ex->getRejection()),
phutil_tag(
'div',
array(
'class' => 'aphront-capability-details',
),
pht('Users with the "%s" capability:', $ex->getCapabilityName())),
$list,
);
$dialog = new AphrontDialogView();
$dialog
->setTitle($ex->getTitle())
->setClass('aphront-access-dialog')
->setUser($user)
->appendChild($content);
if ($this->getRequest()->isAjax()) {
$dialog->addCancelButton('/', 'Close');
} else {
$dialog->addCancelButton('/', $is_serious ? 'OK' : 'Away With Thee');
}
$response = new AphrontDialogResponse();
$response->setDialog($dialog);
return $response;
}
if ($ex instanceof AphrontUsageException) {
$error = new AphrontErrorView();
$error->setTitle($ex->getTitle());
$error->appendChild($ex->getMessage());
$view = new PhabricatorStandardPageView();
$view->setRequest($this->getRequest());
$view->appendChild($error);
$response = new AphrontWebpageResponse();
$response->setContent($view->render());
$response->setHTTPResponseCode(500);
return $response;
}
// Always log the unhandled exception.
phlog($ex);
$class = get_class($ex);
$message = $ex->getMessage();
if ($ex instanceof AphrontQuerySchemaException) {
$message .=
"\n\n".
"NOTE: This usually indicates that the MySQL schema has not been ".
"properly upgraded. Run 'bin/storage upgrade' to ensure your ".
"schema is up to date.";
}
if (PhabricatorEnv::getEnvConfig('phabricator.developer-mode')) {
$trace = id(new AphrontStackTraceView())
->setUser($user)
->setTrace($ex->getTrace());
} else {
$trace = null;
}
$content = phutil_tag(
'div',
array('class' => 'aphront-unhandled-exception'),
array(
phutil_tag('div', array('class' => 'exception-message'), $message),
$trace,
));
$dialog = new AphrontDialogView();
$dialog
->setTitle('Unhandled Exception ("'.$class.'")')
->setClass('aphront-exception-dialog')
->setUser($user)
->appendChild($content);
if ($this->getRequest()->isAjax()) {
$dialog->addCancelButton('/', 'Close');
}
$response = new AphrontDialogResponse();
$response->setDialog($dialog);
$response->setHTTPResponseCode(500);
return $response;
}
public function willSendResponse(AphrontResponse $response) {
return $response;
}
public function build404Controller() {
return array(new Phabricator404Controller($this->getRequest()), array());
}
public function buildRedirectController($uri) {
return array(
new PhabricatorRedirectController($this->getRequest()),
array(
'uri' => $uri,
));
}
}
diff --git a/src/aphront/response/AphrontFileResponse.php b/src/aphront/response/AphrontFileResponse.php
index 08f3b82cb5..13d980d06e 100644
--- a/src/aphront/response/AphrontFileResponse.php
+++ b/src/aphront/response/AphrontFileResponse.php
@@ -1,83 +1,95 @@
<?php
/**
* @group aphront
*/
final class AphrontFileResponse extends AphrontResponse {
private $content;
private $mimeType;
private $download;
private $rangeMin;
private $rangeMax;
+ private $allowOrigins = array();
+
+ public function addAllowOrigin($origin) {
+ $this->allowOrigins[] = $origin;
+ return $this;
+ }
public function setDownload($download) {
$download = preg_replace('/[^A-Za-z0-9_.-]/', '_', $download);
if (!strlen($download)) {
$download = 'untitled_document.txt';
}
$this->download = $download;
return $this;
}
public function getDownload() {
return $this->download;
}
public function setMimeType($mime_type) {
$this->mimeType = $mime_type;
return $this;
}
public function getMimeType() {
return $this->mimeType;
}
public function setContent($content) {
$this->content = $content;
return $this;
}
public function buildResponseString() {
if ($this->rangeMin || $this->rangeMax) {
$length = ($this->rangeMax - $this->rangeMin) + 1;
return substr($this->content, $this->rangeMin, $length);
} else {
return $this->content;
}
}
public function setRange($min, $max) {
$this->rangeMin = $min;
$this->rangeMax = $max;
return $this;
}
public function getHeaders() {
$headers = array(
array('Content-Type', $this->getMimeType()),
array('Content-Length', strlen($this->buildResponseString())),
);
if ($this->rangeMin || $this->rangeMax) {
$len = strlen($this->content);
$min = $this->rangeMin;
$max = $this->rangeMax;
$headers[] = array('Content-Range', "bytes {$min}-{$max}/{$len}");
}
if (strlen($this->getDownload())) {
$headers[] = array('X-Download-Options', 'noopen');
$filename = $this->getDownload();
$headers[] = array(
'Content-Disposition',
'attachment; filename='.$filename,
);
}
+ if ($this->allowOrigins) {
+ $headers[] = array(
+ 'Access-Control-Allow-Origin',
+ implode(',', $this->allowOrigins));
+ }
+
$headers = array_merge(parent::getHeaders(), $headers);
return $headers;
}
}
diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php
index eb31ff9a18..3a535f0b8a 100644
--- a/src/applications/base/controller/PhabricatorController.php
+++ b/src/applications/base/controller/PhabricatorController.php
@@ -1,427 +1,431 @@
<?php
abstract class PhabricatorController extends AphrontController {
private $handles;
public function shouldRequireLogin() {
return true;
}
public function shouldRequireAdmin() {
return false;
}
public function shouldRequireEnabledUser() {
return true;
}
public function shouldAllowPublic() {
return false;
}
public function shouldRequireEmailVerification() {
return PhabricatorUserEmail::isEmailVerificationRequired();
}
public function willBeginExecution() {
$request = $this->getRequest();
if ($request->getUser()) {
// NOTE: Unit tests can set a user explicitly. Normal requests are not
// permitted to do this.
PhabricatorTestCase::assertExecutingUnitTests();
$user = $request->getUser();
} else {
$user = new PhabricatorUser();
$session_engine = new PhabricatorAuthSessionEngine();
$phsid = $request->getCookie(PhabricatorCookies::COOKIE_SESSION);
if (strlen($phsid)) {
$session_user = $session_engine->loadUserForSession(
PhabricatorAuthSession::TYPE_WEB,
$phsid);
if ($session_user) {
$user = $session_user;
}
} else {
// If the client doesn't have a session token, generate an anonymous
// session. This is used to provide CSRF protection to logged-out users.
$phsid = $session_engine->establishSession(
PhabricatorAuthSession::TYPE_WEB,
null);
// This may be a resource request, in which case we just don't set
// the cookie.
if ($request->canSetCookies()) {
$request->setCookie(PhabricatorCookies::COOKIE_SESSION, $phsid);
}
}
if (!$user->isLoggedIn()) {
$user->attachAlternateCSRFString(PhabricatorHash::digest($phsid));
}
$request->setUser($user);
}
$translation = $user->getTranslation();
if ($translation &&
$translation != PhabricatorEnv::getEnvConfig('translation.provider')) {
$translation = newv($translation, array());
PhutilTranslator::getInstance()
->setLanguage($translation->getLanguage())
->addTranslations($translation->getTranslations());
}
$preferences = $user->loadPreferences();
if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) {
$dark_console = PhabricatorUserPreferences::PREFERENCE_DARK_CONSOLE;
if ($preferences->getPreference($dark_console) ||
PhabricatorEnv::getEnvConfig('darkconsole.always-on')) {
$console = new DarkConsoleCore();
$request->getApplicationConfiguration()->setConsole($console);
}
}
if ($this->shouldRequireEnabledUser()) {
if ($user->isLoggedIn() && !$user->getIsApproved()) {
$controller = new PhabricatorAuthNeedsApprovalController($request);
return $this->delegateToController($controller);
}
if ($user->getIsDisabled()) {
$controller = new PhabricatorDisabledUserController($request);
return $this->delegateToController($controller);
}
}
$event = new PhabricatorEvent(
PhabricatorEventType::TYPE_CONTROLLER_CHECKREQUEST,
array(
'request' => $request,
'controller' => $this,
));
$event->setUser($user);
PhutilEventEngine::dispatchEvent($event);
$checker_controller = $event->getValue('controller');
if ($checker_controller != $this) {
return $this->delegateToController($checker_controller);
}
if ($this->shouldRequireLogin()) {
// This actually means we need either:
// - a valid user, or a public controller; and
// - permission to see the application.
$auth_class = 'PhabricatorApplicationAuth';
$auth_application = PhabricatorApplication::getByClass($auth_class);
$allow_public = $this->shouldAllowPublic() &&
PhabricatorEnv::getEnvConfig('policy.allow-public');
// If this controller isn't public, and the user isn't logged in, require
// login.
if (!$allow_public && !$user->isLoggedIn()) {
$login_controller = new PhabricatorAuthStartController($request);
$this->setCurrentApplication($auth_application);
return $this->delegateToController($login_controller);
}
if ($user->isLoggedIn()) {
if ($this->shouldRequireEmailVerification()) {
if (!$user->getIsEmailVerified()) {
$controller = new PhabricatorMustVerifyEmailController($request);
$this->setCurrentApplication($auth_application);
return $this->delegateToController($controller);
}
}
}
// If the user doesn't have access to the application, don't let them use
// any of its controllers. We query the application in order to generate
// a policy exception if the viewer doesn't have permission.
$application = $this->getCurrentApplication();
if ($application) {
id(new PhabricatorApplicationQuery())
->setViewer($user)
->withPHIDs(array($application->getPHID()))
->executeOne();
}
}
// NOTE: We do this last so that users get a login page instead of a 403
// if they need to login.
if ($this->shouldRequireAdmin() && !$user->getIsAdmin()) {
return new Aphront403Response();
}
}
public function buildStandardPageView() {
$view = new PhabricatorStandardPageView();
$view->setRequest($this->getRequest());
$view->setController($this);
return $view;
}
public function buildStandardPageResponse($view, array $data) {
$page = $this->buildStandardPageView();
$page->appendChild($view);
$response = new AphrontWebpageResponse();
$response->setContent($page->render());
return $response;
}
public function getApplicationURI($path = '') {
if (!$this->getCurrentApplication()) {
throw new Exception("No application!");
}
return $this->getCurrentApplication()->getApplicationURI($path);
}
public function buildApplicationPage($view, array $options) {
$page = $this->buildStandardPageView();
$title = PhabricatorEnv::getEnvConfig('phabricator.serious-business') ?
'Phabricator' :
pht('Bacon Ice Cream for Breakfast');
$application = $this->getCurrentApplication();
$page->setTitle(idx($options, 'title', $title));
if ($application) {
$page->setApplicationName($application->getName());
if ($application->getTitleGlyph()) {
$page->setGlyph($application->getTitleGlyph());
}
}
if (!($view instanceof AphrontSideNavFilterView)) {
$nav = new AphrontSideNavFilterView();
$nav->appendChild($view);
$view = $nav;
}
$user = $this->getRequest()->getUser();
$view->setUser($user);
$page->appendChild($view);
$object_phids = idx($options, 'pageObjects', array());
if ($object_phids) {
$page->appendPageObjects($object_phids);
foreach ($object_phids as $object_phid) {
PhabricatorFeedStoryNotification::updateObjectNotificationViews(
$user,
$object_phid);
}
}
if (idx($options, 'device')) {
$page->setDeviceReady(true);
}
+ if (idx($options, 'fonts')) {
+ $page->setExtraFonts(true);
+ }
+
$page->setShowChrome(idx($options, 'chrome', true));
$application_menu = $this->buildApplicationMenu();
if ($application_menu) {
$page->setApplicationMenu($application_menu);
}
$response = new AphrontWebpageResponse();
return $response->setContent($page->render());
}
public function didProcessRequest($response) {
$request = $this->getRequest();
$response->setRequest($request);
$seen = array();
while ($response instanceof AphrontProxyResponse) {
$hash = spl_object_hash($response);
if (isset($seen[$hash])) {
$seen[] = get_class($response);
throw new Exception(
"Cycle while reducing proxy responses: ".
implode(' -> ', $seen));
}
$seen[$hash] = get_class($response);
$response = $response->reduceProxyResponse();
}
if ($response instanceof AphrontDialogResponse) {
if (!$request->isAjax()) {
$view = new PhabricatorStandardPageView();
$view->setRequest($request);
$view->setController($this);
$view->appendChild(phutil_tag(
'div',
array('style' => 'padding: 2em 0;'),
$response->buildResponseString()));
$page_response = new AphrontWebpageResponse();
$page_response->setContent($view->render());
$page_response->setHTTPResponseCode($response->getHTTPResponseCode());
return $page_response;
} else {
$response->getDialog()->setIsStandalone(true);
return id(new AphrontAjaxResponse())
->setContent(array(
'dialog' => $response->buildResponseString(),
));
}
} else if ($response instanceof AphrontRedirectResponse) {
if ($request->isAjax()) {
return id(new AphrontAjaxResponse())
->setContent(
array(
'redirect' => $response->getURI(),
));
}
}
return $response;
}
protected function getHandle($phid) {
if (empty($this->handles[$phid])) {
throw new Exception(
"Attempting to access handle which wasn't loaded: {$phid}");
}
return $this->handles[$phid];
}
protected function loadHandles(array $phids) {
$phids = array_filter($phids);
$this->handles = $this->loadViewerHandles($phids);
return $this;
}
protected function getLoadedHandles() {
return $this->handles;
}
protected function loadViewerHandles(array $phids) {
return id(new PhabricatorHandleQuery())
->setViewer($this->getRequest()->getUser())
->withPHIDs($phids)
->execute();
}
/**
* Render a list of links to handles, identified by PHIDs. The handles must
* already be loaded.
*
* @param list<phid> List of PHIDs to render links to.
* @param string Style, one of "\n" (to put each item on its own line)
* or "," (to list items inline, separated by commas).
* @return string Rendered list of handle links.
*/
protected function renderHandlesForPHIDs(array $phids, $style = "\n") {
$style_map = array(
"\n" => phutil_tag('br'),
',' => ', ',
);
if (empty($style_map[$style])) {
throw new Exception("Unknown handle list style '{$style}'!");
}
return implode_selected_handle_links($style_map[$style],
$this->getLoadedHandles(),
array_filter($phids));
}
protected function buildApplicationMenu() {
return null;
}
protected function buildApplicationCrumbs() {
$crumbs = array();
$application = $this->getCurrentApplication();
if ($application) {
$sprite = $application->getIconName();
if (!$sprite) {
$sprite = 'application';
}
$crumbs[] = id(new PhabricatorCrumbView())
->setHref($this->getApplicationURI())
->setIcon($sprite);
}
$view = new PhabricatorCrumbsView();
foreach ($crumbs as $crumb) {
$view->addCrumb($crumb);
}
return $view;
}
protected function hasApplicationCapability($capability) {
return PhabricatorPolicyFilter::hasCapability(
$this->getRequest()->getUser(),
$this->getCurrentApplication(),
$capability);
}
protected function requireApplicationCapability($capability) {
PhabricatorPolicyFilter::requireCapability(
$this->getRequest()->getUser(),
$this->getCurrentApplication(),
$capability);
}
protected function explainApplicationCapability(
$capability,
$positive_message,
$negative_message) {
$can_act = $this->hasApplicationCapability($capability);
if ($can_act) {
$message = $positive_message;
$icon_name = 'enable-grey';
} else {
$message = $negative_message;
$icon_name = 'lock';
}
$icon = id(new PHUIIconView())
->setSpriteSheet(PHUIIconView::SPRITE_ICONS)
->setSpriteIcon($icon_name);
require_celerity_resource('policy-css');
$phid = $this->getCurrentApplication()->getPHID();
$explain_uri = "/policy/explain/{$phid}/{$capability}/";
$message = phutil_tag(
'div',
array(
'class' => 'policy-capability-explanation',
),
array(
$icon,
javelin_tag(
'a',
array(
'href' => $explain_uri,
'sigil' => 'workflow',
),
$message),
));
return array($can_act, $message);
}
public function getDefaultResourceSource() {
return 'phabricator';
}
}
diff --git a/src/applications/diviner/controller/DivinerAtomController.php b/src/applications/diviner/controller/DivinerAtomController.php
index 4a6e6c5aff..5b4d2207a4 100644
--- a/src/applications/diviner/controller/DivinerAtomController.php
+++ b/src/applications/diviner/controller/DivinerAtomController.php
@@ -1,675 +1,675 @@
<?php
final class DivinerAtomController extends DivinerController {
private $bookName;
private $atomType;
private $atomName;
private $atomContext;
private $atomIndex;
public function shouldAllowPublic() {
return true;
}
public function willProcessRequest(array $data) {
$this->bookName = $data['book'];
$this->atomType = $data['type'];
$this->atomName = $data['name'];
$this->atomContext = nonempty(idx($data, 'context'), null);
$this->atomIndex = nonempty(idx($data, 'index'), null);
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
require_celerity_resource('diviner-shared-css');
$book = id(new DivinerBookQuery())
->setViewer($viewer)
->withNames(array($this->bookName))
->executeOne();
if (!$book) {
return new Aphront404Response();
}
// TODO: This query won't load ghosts, because they'll fail `needAtoms()`.
// Instead, we might want to load ghosts and render a message like
// "this thing existed in an older version, but no longer does", especially
// if we add content like comments.
$symbol = id(new DivinerAtomQuery())
->setViewer($viewer)
->withBookPHIDs(array($book->getPHID()))
->withTypes(array($this->atomType))
->withNames(array($this->atomName))
->withContexts(array($this->atomContext))
->withIndexes(array($this->atomIndex))
->needAtoms(true)
->needExtends(true)
->needChildren(true)
->executeOne();
if (!$symbol) {
return new Aphront404Response();
}
$atom = $symbol->getAtom();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(
$book->getShortTitle(),
'/book/'.$book->getName().'/');
$atom_short_title = $atom->getDocblockMetaValue(
'short',
$symbol->getTitle());
$crumbs->addTextCrumb($atom_short_title);
$header = id(new PHUIHeaderView())
->setHeader($this->renderFullSignature($symbol))
->addTag(
id(new PHUITagView())
->setType(PHUITagView::TYPE_STATE)
->setBackgroundColor(PHUITagView::COLOR_BLUE)
->setName(DivinerAtom::getAtomTypeNameString($atom->getType())));
$properties = id(new PHUIPropertyListView());
$group = $atom->getProperty('group');
if ($group) {
$group_name = $book->getGroupName($group);
} else {
$group_name = null;
}
$this->buildDefined($properties, $symbol);
$this->buildExtendsAndImplements($properties, $symbol);
$warnings = $atom->getWarnings();
if ($warnings) {
$warnings = id(new AphrontErrorView())
->setErrors($warnings)
->setTitle(pht('Documentation Warnings'))
->setSeverity(AphrontErrorView::SEVERITY_WARNING);
}
$methods = $this->composeMethods($symbol);
$field = 'default';
$engine = id(new PhabricatorMarkupEngine())
->setViewer($viewer)
->addObject($symbol, $field);
foreach ($methods as $method) {
foreach ($method['atoms'] as $matom) {
$engine->addObject($matom, $field);
}
}
$engine->process();
$content = $this->renderDocumentationText($symbol, $engine);
$toc = $engine->getEngineMetadata(
$symbol,
$field,
PhutilRemarkupEngineRemarkupHeaderBlockRule::KEY_HEADER_TOC,
array());
$document = id(new PHUIDocumentView())
->setBook($book->getTitle(), $group_name)
->setHeader($header)
+ ->setFontKit(PHUIDocumentView::FONT_SOURCE_SANS)
->appendChild($properties)
->appendChild($warnings)
->appendChild($content);
$document->appendChild($this->buildParametersAndReturn(array($symbol)));
if ($methods) {
$tasks = $this->composeTasks($symbol);
if ($tasks) {
$methods_by_task = igroup($methods, 'task');
// Add phantom tasks for methods which have a "@task" name that isn't
// documented anywhere, or methods that have no "@task" name.
foreach ($methods_by_task as $task => $ignored) {
if (empty($tasks[$task])) {
$tasks[$task] = array(
'name' => $task,
'title' => $task ? $task : pht('Other Methods'),
'defined' => $symbol,
);
}
}
$section = id(new DivinerSectionView())
->setHeader(pht('Tasks'));
foreach ($tasks as $spec) {
$section->addContent(
id(new PHUIHeaderView())
->setNoBackground(true)
->setHeader($spec['title']));
$task_methods = idx($methods_by_task, $spec['name'], array());
$inner_box = id(new PHUIBoxView())
->addPadding(PHUI::PADDING_LARGE_LEFT)
->addPadding(PHUI::PADDING_LARGE_RIGHT)
->addPadding(PHUI::PADDING_LARGE_BOTTOM);
$box_content = array();
if ($task_methods) {
$list_items = array();
foreach ($task_methods as $task_method) {
$atom = last($task_method['atoms']);
$item = $this->renderFullSignature($atom, true);
if (strlen($atom->getSummary())) {
$item = array(
$item,
" \xE2\x80\x94 ",
$atom->getSummary());
}
$list_items[] = phutil_tag('li', array(), $item);
}
$box_content[] = phutil_tag(
'ul',
array(
'class' => 'diviner-list',
),
$list_items);
} else {
$no_methods = pht('No methods for this task.');
$box_content = phutil_tag('em', array(), $no_methods);
}
$inner_box->appendChild($box_content);
$section->addContent($inner_box);
}
$document->appendChild($section);
}
$section = id(new DivinerSectionView())
->setHeader(pht('Methods'));
foreach ($methods as $spec) {
$matom = last($spec['atoms']);
$method_header = id(new PHUIHeaderView())
->setNoBackground(true);
$inherited = $spec['inherited'];
if ($inherited) {
$method_header->addTag(
id(new PHUITagView())
->setType(PHUITagView::TYPE_STATE)
->setBackgroundColor(PHUITagView::COLOR_GREY)
->setName(pht('Inherited')));
}
$method_header->setHeader($this->renderFullSignature($matom));
$section->addContent(
array(
$method_header,
$this->renderMethodDocumentationText($symbol, $spec, $engine),
$this->buildParametersAndReturn($spec['atoms']),
));
}
$document->appendChild($section);
}
if ($toc) {
$side = new PHUIListView();
$side->addMenuItem(
id(new PHUIListItemView())
->setName(pht('Contents'))
->setType(PHUIListItemView::TYPE_LABEL));
foreach ($toc as $key => $entry) {
$side->addMenuItem(
id(new PHUIListItemView())
->setName($entry[1])
->setHref('#'.$key));
}
$document->setSideNav($side, PHUIDocumentView::NAV_TOP);
}
return $this->buildApplicationPage(
array(
$crumbs,
$document,
),
array(
'title' => $symbol->getTitle(),
'device' => true,
+ 'fonts' => true,
));
}
private function buildExtendsAndImplements(
PHUIPropertyListView $view,
DivinerLiveSymbol $symbol) {
$lineage = $this->getExtendsLineage($symbol);
if ($lineage) {
$tags = array();
foreach ($lineage as $item) {
$tags[] = $this->renderAtomTag($item);
}
$caret = phutil_tag('span', array('class' => 'caret-right msl msr'));
$tags = phutil_implode_html($caret, $tags);
$view->addProperty(pht('Extends'), $tags);
}
$implements = $this->getImplementsLineage($symbol);
if ($implements) {
$items = array();
foreach ($implements as $spec) {
$via = $spec['via'];
$iface = $spec['interface'];
if ($via == $symbol) {
$items[] = $this->renderAtomTag($iface);
} else {
$items[] = array(
$this->renderAtomTag($iface),
" \xE2\x97\x80 ",
$this->renderAtomTag($via));
}
}
$view->addProperty(
pht('Implements'),
phutil_implode_html(phutil_tag('br'), $items));
}
}
private function renderAtomTag(DivinerLiveSymbol $symbol) {
return id(new PHUITagView())
->setType(PHUITagView::TYPE_OBJECT)
->setName($symbol->getName())
->setHref($symbol->getURI());
}
private function getExtendsLineage(DivinerLiveSymbol $symbol) {
foreach ($symbol->getExtends() as $extends) {
if ($extends->getType() == 'class') {
$lineage = $this->getExtendsLineage($extends);
$lineage[] = $extends;
return $lineage;
}
}
return array();
}
private function getImplementsLineage(DivinerLiveSymbol $symbol) {
$implements = array();
// Do these first so we get interfaces ordered from most to least specific.
foreach ($symbol->getExtends() as $extends) {
if ($extends->getType() == 'interface') {
$implements[$extends->getName()] = array(
'interface' => $extends,
'via' => $symbol,
);
}
}
// Now do parent interfaces.
foreach ($symbol->getExtends() as $extends) {
if ($extends->getType() == 'class') {
$implements += $this->getImplementsLineage($extends);
}
}
return $implements;
}
private function buildDefined(
PHUIPropertyListView $view,
DivinerLiveSymbol $symbol) {
$atom = $symbol->getAtom();
$defined = $atom->getFile().':'.$atom->getLine();
$link = $symbol->getBook()->getConfig('uri.source');
if ($link) {
$link = strtr(
$link,
array(
'%%' => '%',
'%f' => phutil_escape_uri($atom->getFile()),
'%l' => phutil_escape_uri($atom->getLine()),
));
$defined = phutil_tag(
'a',
array(
'href' => $link,
'target' => '_blank',
),
$defined);
}
$view->addProperty(pht('Defined'), $defined);
}
private function composeMethods(DivinerLiveSymbol $symbol) {
$methods = $this->findMethods($symbol);
if (!$methods) {
return $methods;
}
foreach ($methods as $name => $method) {
// Check for "@task" on each parent, to find the most recently declared
// "@task".
$task = null;
foreach ($method['atoms'] as $key => $method_symbol) {
$atom = $method_symbol->getAtom();
if ($atom->getDocblockMetaValue('task')) {
$task = $atom->getDocblockMetaValue('task');
}
}
$methods[$name]['task'] = $task;
// Set 'inherited' if this atom has no implementation of the method.
if (last($method['implementations']) !== $symbol) {
$methods[$name]['inherited'] = true;
} else {
$methods[$name]['inherited'] = false;
}
}
return $methods;
}
private function findMethods(DivinerLiveSymbol $symbol) {
$child_specs = array();
foreach ($symbol->getExtends() as $extends) {
if ($extends->getType() == DivinerAtom::TYPE_CLASS) {
$child_specs = $this->findMethods($extends);
}
}
foreach ($symbol->getChildren() as $child) {
if ($child->getType() == DivinerAtom::TYPE_METHOD) {
$name = $child->getName();
if (isset($child_specs[$name])) {
$child_specs[$name]['atoms'][] = $child;
$child_specs[$name]['implementations'][] = $symbol;
} else {
$child_specs[$name] = array(
'atoms' => array($child),
'defined' => $symbol,
'implementations' => array($symbol),
);
}
}
}
return $child_specs;
}
private function composeTasks(DivinerLiveSymbol $symbol) {
$extends_task_specs = array();
foreach ($symbol->getExtends() as $extends) {
$extends_task_specs += $this->composeTasks($extends);
}
$task_specs = array();
$tasks = $symbol->getAtom()->getDocblockMetaValue('task');
if (strlen($tasks)) {
$tasks = phutil_split_lines($tasks, $retain_endings = false);
foreach ($tasks as $task) {
list($name, $title) = explode(' ', $task, 2);
$name = trim($name);
$title = trim($title);
$task_specs[$name] = array(
'name' => $name,
'title' => $title,
'defined' => $symbol,
);
}
}
$specs = $task_specs + $extends_task_specs;
// Reorder "@tasks" in original declaration order. Basically, we want to
// use the documentation of the closest subclass, but put tasks which
// were declared by parents first.
$keys = array_keys($extends_task_specs);
$specs = array_select_keys($specs, $keys) + $specs;
return $specs;
}
private function renderFullSignature(
DivinerLiveSymbol $symbol,
$is_link = false) {
switch ($symbol->getType()) {
case DivinerAtom::TYPE_CLASS:
case DivinerAtom::TYPE_INTERFACE:
case DivinerAtom::TYPE_METHOD:
case DivinerAtom::TYPE_FUNCTION:
break;
- case DivinerAtom::TYPE_ARTICLE:
- return $symbol->getTitle();
default:
- return null;
+ return $symbol->getTitle();
}
$atom = $symbol->getAtom();
$out = array();
if ($atom->getProperty('final')) {
$out[] = 'final';
}
if ($atom->getProperty('abstract')) {
$out[] = 'abstract';
}
if ($atom->getProperty('access')) {
$out[] = $atom->getProperty('access');
}
if ($atom->getProperty('static')) {
$out[] = 'static';
}
switch ($symbol->getType()) {
case DivinerAtom::TYPE_CLASS:
case DivinerAtom::TYPE_INTERFACE:
$out[] = $symbol->getType();
break;
case DivinerAtom::TYPE_FUNCTION:
switch ($atom->getLanguage()) {
case 'php':
$out[] = $symbol->getType();
break;
}
break;
case DivinerAtom::TYPE_METHOD:
switch ($atom->getLanguage()) {
case 'php':
$out[] = DivinerAtom::TYPE_FUNCTION;
break;
}
break;
}
$anchor = null;
switch ($symbol->getType()) {
case DivinerAtom::TYPE_METHOD:
$anchor = $symbol->getType().'/'.$symbol->getName();
break;
default:
break;
}
$out[] = phutil_tag(
$anchor ? 'a' : 'span',
array(
'class' => 'diviner-atom-signature-name',
'href' => $anchor ? '#'.$anchor : null,
'name' => $is_link ? null : $anchor,
),
$symbol->getName());
$out = phutil_implode_html(' ', $out);
$parameters = $atom->getProperty('parameters');
if ($parameters !== null) {
$pout = array();
foreach ($parameters as $parameter) {
$pout[] = idx($parameter, 'name', '...');
}
$out = array($out, '('.implode(', ', $pout).')');
}
return phutil_tag(
'span',
array(
'class' => 'diviner-atom-signature',
),
$out);
}
private function buildParametersAndReturn(array $symbols) {
assert_instances_of($symbols, 'DivinerLiveSymbol');
$symbols = array_reverse($symbols);
$out = array();
$collected_parameters = null;
foreach ($symbols as $symbol) {
$parameters = $symbol->getAtom()->getProperty('parameters');
if ($parameters !== null) {
if ($collected_parameters === null) {
$collected_parameters = array();
}
foreach ($parameters as $key => $parameter) {
if (isset($collected_parameters[$key])) {
$collected_parameters[$key] += $parameter;
} else {
$collected_parameters[$key] = $parameter;
}
}
}
}
if (nonempty($parameters)) {
$out[] = id(new DivinerParameterTableView())
->setHeader(pht('Parameters'))
->setParameters($parameters);
}
$collected_return = null;
foreach ($symbols as $symbol) {
$return = $symbol->getAtom()->getProperty('return');
if ($return) {
if ($collected_return) {
$collected_return += $return;
} else {
$collected_return = $return;
}
}
}
if (nonempty($return)) {
$out[] = id(new DivinerReturnTableView())
->setHeader(pht('Return'))
->setReturn($collected_return);
}
return $out;
}
private function renderDocumentationText(
DivinerLiveSymbol $symbol,
PhabricatorMarkupEngine $engine) {
$field = 'default';
$content = $engine->getOutput($symbol, $field);
if (strlen(trim($symbol->getMarkupText($field)))) {
$content = phutil_tag(
'div',
array(
'class' => 'phabricator-remarkup',
),
$content);
} else {
$atom = $symbol->getAtom();
$content = phutil_tag(
'div',
array(
'class' => 'diviner-message-not-documented',
),
DivinerAtom::getThisAtomIsNotDocumentedString($atom->getType()));
}
return $content;
}
private function renderMethodDocumentationText(
DivinerLiveSymbol $parent,
array $spec,
PhabricatorMarkupEngine $engine) {
$symbols = array_values($spec['atoms']);
$implementations = array_values($spec['implementations']);
$field = 'default';
$out = array();
foreach ($symbols as $key => $symbol) {
$impl = $implementations[$key];
if ($impl !== $parent) {
if (!strlen(trim($symbol->getMarkupText($field)))) {
continue;
}
}
$doc = $this->renderDocumentationText($symbol, $engine);
if (($impl !== $parent) || $out) {
$where = id(new PHUIBoxView())
->addPadding(PHUI::PADDING_MEDIUM_LEFT)
->addPadding(PHUI::PADDING_MEDIUM_RIGHT)
->addClass('diviner-method-implementation-header')
->appendChild($impl->getName());
$doc = array($where, $doc);
if ($impl !== $parent) {
$doc = phutil_tag(
'div',
array(
'class' => 'diviner-method-implementation-inherited',
),
$doc);
}
}
$out[] = $doc;
}
// If we only have inherited implementations but none have documentation,
// render the last one here so we get the "this thing has no documentation"
// element.
if (!$out) {
$out[] = $this->renderDocumentationText($symbol, $engine);
}
return $out;
}
}
diff --git a/src/applications/diviner/controller/DivinerBookController.php b/src/applications/diviner/controller/DivinerBookController.php
index f932b8a1d2..c9552cd530 100644
--- a/src/applications/diviner/controller/DivinerBookController.php
+++ b/src/applications/diviner/controller/DivinerBookController.php
@@ -1,110 +1,115 @@
<?php
final class DivinerBookController extends DivinerController {
private $bookName;
public function shouldAllowPublic() {
return true;
}
public function willProcessRequest(array $data) {
$this->bookName = $data['book'];
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$book = id(new DivinerBookQuery())
->setViewer($viewer)
->withNames(array($this->bookName))
->executeOne();
if (!$book) {
return new Aphront404Response();
}
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(
$book->getShortTitle(),
'/book/'.$book->getName().'/');
$header = id(new PHUIHeaderView())
->setHeader($book->getTitle())
->setUser($viewer)
->setPolicyObject($book);
$document = new PHUIDocumentView();
$document->setHeader($header);
+ $document->setFontKit(PHUIDocumentView::FONT_SOURCE_SANS);
$properties = $this->buildPropertyList($book);
$atoms = id(new DivinerAtomQuery())
->setViewer($viewer)
->withBookPHIDs(array($book->getPHID()))
->execute();
$atoms = msort($atoms, 'getSortKey');
$group_spec = $book->getConfig('groups');
if (!is_array($group_spec)) {
$group_spec = array();
}
$groups = mgroup($atoms, 'getGroupName');
$groups = array_select_keys($groups, array_keys($group_spec)) + $groups;
if (isset($groups[''])) {
$no_group = $groups[''];
unset($groups['']);
$groups[''] = $no_group;
}
$out = array();
foreach ($groups as $group => $atoms) {
$group_name = $book->getGroupName($group);
$section = id(new DivinerSectionView())
->setHeader($group_name);
$section->addContent($this->renderAtomList($atoms));
$out[] = $section;
}
+
+ $preface = $book->getPreface();
+ $preface_view = null;
+ if (strlen($preface)) {
+ $preface_view =
+ PhabricatorMarkupEngine::renderOneObject(
+ id(new PhabricatorMarkupOneOff())->setContent($preface),
+ 'default',
+ $viewer);
+ }
+
$document->appendChild($properties);
+ $document->appendChild($preface_view);
$document->appendChild($out);
return $this->buildApplicationPage(
array(
$crumbs,
$document,
),
array(
'title' => $book->getTitle(),
'device' => true,
+ 'fonts' => true,
));
}
private function buildPropertyList(DivinerLiveBook $book) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer);
$policies = PhabricatorPolicyQuery::renderPolicyDescriptions(
$viewer,
$book);
$view->addProperty(
pht('Updated'),
phabricator_datetime($book->getDateModified(), $viewer));
- $preface = $book->getPreface();
- if (strlen($preface)) {
- $view->addTextContent(
- PhabricatorMarkupEngine::renderOneObject(
- id(new PhabricatorMarkupOneOff())->setContent($preface),
- 'default',
- $viewer));
- }
-
return $view;
}
}
diff --git a/src/applications/diviner/controller/DivinerFindController.php b/src/applications/diviner/controller/DivinerFindController.php
index 56b6af89b7..16ac0e1372 100644
--- a/src/applications/diviner/controller/DivinerFindController.php
+++ b/src/applications/diviner/controller/DivinerFindController.php
@@ -1,92 +1,93 @@
<?php
final class DivinerFindController extends DivinerController {
public function shouldAllowPublic() {
return true;
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$book_name = $request->getStr('book');
$query_text = $request->getStr('name');
$book = null;
if ($book_name) {
$book = id(new DivinerBookQuery())
->setViewer($viewer)
->withNames(array($book_name))
->executeOne();
if (!$book) {
return new Aphront404Response();
}
}
$query = id(new DivinerAtomQuery())
->setViewer($viewer);
if ($book) {
$query->withBookPHIDs(array($book->getPHID()));
}
$context = $request->getStr('context');
if (strlen($context)) {
$query->withContexts(array($context));
}
$type = $request->getStr('type');
if (strlen($type)) {
$query->withTypes(array($type));
}
$name_query = clone $query;
$name_query->withNames(
array(
$query_text,
// TODO: This could probably be more smartly normalized in the DB,
// but just fake it for now.
phutil_utf8_strtolower($query_text),
));
$atoms = $name_query->execute();
if (!$atoms) {
$title_query = clone $query;
$title_query->withTitles(array($query_text));
$atoms = $title_query->execute();
}
$not_found_uri = $this->getApplicationURI();
if (!$atoms) {
$dialog = id(new AphrontDialogView())
->setUser($viewer)
->setTitle(pht('Documentation Not Found'))
->appendChild(
pht(
'Unable to find the specified documentation. You may have '.
'followed a bad or outdated link.'))
->addCancelButton($not_found_uri, pht('Read More Documentation'));
return id(new AphrontDialogResponse())->setDialog($dialog);
}
if (count($atoms) == 1 && $request->getBool('jump')) {
$atom_uri = head($atoms)->getURI();
return id(new AphrontRedirectResponse())->setURI($atom_uri);
}
$list = $this->renderAtomList($atoms);
return $this->buildApplicationPage(
$list,
array(
'title' => array(pht('Find'), pht('"%s"', $query_text)),
'device' => true,
+ 'fonts' => true,
));
}
}
diff --git a/src/applications/diviner/controller/DivinerMainController.php b/src/applications/diviner/controller/DivinerMainController.php
index 2ac8f4d69d..31ece08328 100644
--- a/src/applications/diviner/controller/DivinerMainController.php
+++ b/src/applications/diviner/controller/DivinerMainController.php
@@ -1,89 +1,94 @@
<?php
final class DivinerMainController extends DivinerController {
public function shouldAllowPublic() {
return true;
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$books = id(new DivinerBookQuery())
->setViewer($viewer)
->execute();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Books'));
$search_icon = id(new PHUIIconView())
->setSpriteIcon('search')
->setSpriteSheet(PHUIIconView::SPRITE_ICONS);
$query_button = id(new PHUIButtonView())
->setTag('a')
->setHref($this->getApplicationURI('query/'))
->setText(pht('Advanced Search'))
->setIcon($search_icon);
$header = id(new PHUIHeaderView())
->setHeader(pht('Documentation Books'))
->addActionLink($query_button);
$document = new PHUIDocumentView();
$document->setHeader($header);
+ $document->setFontKit(PHUIDocumentView::FONT_SOURCE_SANS);
if ($books) {
- $list = id(new PHUIObjectItemListView())
- ->setUser($viewer)
- ->setPlain(true);
-
$books = msort($books, 'getTitle');
+ $list = array();
foreach ($books as $book) {
- $item = id(new PHUIObjectItemView())
+ $item = id(new DivinerBookItemView())
+ ->setTitle($book->getTitle())
->setHref('/book/'.$book->getName().'/')
- ->setHeader($book->getTitle())
- ->addAttribute($book->getPreface());
-
- $list->addItem($item);
+ ->setSubtitle($book->getPreface());
+ $list[] = $item;
}
+ $list = id(new PHUIBoxView())
+ ->addPadding(PHUI::PADDING_LARGE_LEFT)
+ ->addPadding(PHUI::PADDING_LARGE_RIGHT)
+ ->addPadding(PHUI::PADDING_SMALL_TOP)
+ ->addPadding(PHUI::PADDING_SMALL_BOTTOM)
+ ->appendChild($list);
$document->appendChild($list);
+
} else {
$text = pht(
"(NOTE) **Looking for Phabricator documentation?** If you're looking ".
"for help and information about Phabricator, you can ".
"[[ https://secure.phabricator.com/diviner/ | browse the public ".
"Phabricator documentation ]] on the live site.\n\n".
"Diviner is the documentation generator used to build the Phabricator ".
"documentation.\n\n".
"You haven't generated any Diviner documentation books yet, so ".
"there's nothing to show here. If you'd like to generate your own ".
"local copy of the Phabricator documentation and have it appear ".
"here, run this command:\n\n".
" phabricator/ $ ./bin/diviner generate\n\n".
"Right now, Diviner isn't very useful for generating documentation ".
"for projects other than Phabricator. If you're interested in using ".
"it in your own projects, leave feedback for us on ".
"[[ https://secure.phabricator.com/T4558 | T4558 ]].");
$text = PhabricatorMarkupEngine::renderOneObject(
id(new PhabricatorMarkupOneOff())->setContent($text),
'default',
$viewer);
$document->appendChild($text);
}
return $this->buildApplicationPage(
array(
$crumbs,
$document,
),
array(
'title' => pht('Documentation Books'),
'device' => true,
+ 'fonts' => true,
));
}
}
diff --git a/src/infrastructure/celerity/CelerityResourceController.php b/src/infrastructure/celerity/CelerityResourceController.php
index 17b8403276..7e8ccc299d 100644
--- a/src/infrastructure/celerity/CelerityResourceController.php
+++ b/src/infrastructure/celerity/CelerityResourceController.php
@@ -1,94 +1,106 @@
<?php
abstract class CelerityResourceController extends PhabricatorController {
protected function buildResourceTransformer() {
return null;
}
public function shouldRequireLogin() {
return false;
}
public function shouldRequireEnabledUser() {
return false;
}
abstract public function getCelerityResourceMap();
protected function serveResource($path, $package_hash = null) {
// Sanity checking to keep this from exposing anything sensitive, since it
// ultimately boils down to disk reads.
if (preg_match('@(//|\.\.)@', $path)) {
return new Aphront400Response();
}
$type = CelerityResourceTransformer::getResourceType($path);
$type_map = $this->getSupportedResourceTypes();
if (empty($type_map[$type])) {
throw new Exception("Only static resources may be served.");
}
if (AphrontRequest::getHTTPHeader('If-Modified-Since') &&
!PhabricatorEnv::getEnvConfig('phabricator.developer-mode')) {
// Return a "304 Not Modified". We don't care about the value of this
// field since we never change what resource is served by a given URI.
return $this->makeResponseCacheable(new Aphront304Response());
}
$map = $this->getCelerityResourceMap();
if ($map->isPackageResource($path)) {
$resource_names = $map->getResourceNamesForPackageName($path);
if (!$resource_names) {
return new Aphront404Response();
}
try {
$data = array();
foreach ($resource_names as $resource_name) {
$data[] = $map->getResourceDataForName($resource_name);
}
$data = implode("\n\n", $data);
} catch (Exception $ex) {
return new Aphront404Response();
}
} else {
try {
$data = $map->getResourceDataForName($path);
} catch (Exception $ex) {
return new Aphront404Response();
}
}
$xformer = $this->buildResourceTransformer();
if ($xformer) {
$data = $xformer->transformResource($path, $data);
}
$response = new AphrontFileResponse();
$response->setContent($data);
$response->setMimeType($type_map[$type]);
+
+ // NOTE: This is a piece of magic required to make WOFF fonts work in
+ // Firefox. Possibly we should generalize this.
+ if ($type == 'woff') {
+ // We could be more tailored here, but it's not currently trivial to
+ // generate a comprehensive list of valid origins (an install may have
+ // arbitrarily many Phame blogs, for example), and we lose nothing by
+ // allowing access from anywhere.
+ $response->addAllowOrigin("*");
+ }
+
return $this->makeResponseCacheable($response);
}
protected function getSupportedResourceTypes() {
return array(
'css' => 'text/css; charset=utf-8',
'js' => 'text/javascript; charset=utf-8',
'png' => 'image/png',
'gif' => 'image/gif',
'jpg' => 'image/jpg',
'swf' => 'application/x-shockwave-flash',
+ 'woff' => 'font/woff',
);
}
private function makeResponseCacheable(AphrontResponse $response) {
$response->setCacheDurationInSeconds(60 * 60 * 24 * 30);
$response->setLastModified(time());
return $response;
}
}
diff --git a/src/infrastructure/celerity/resources/CelerityResourcesOnDisk.php b/src/infrastructure/celerity/resources/CelerityResourcesOnDisk.php
index 0aa46bb3d9..2abaaebbc1 100644
--- a/src/infrastructure/celerity/resources/CelerityResourcesOnDisk.php
+++ b/src/infrastructure/celerity/resources/CelerityResourcesOnDisk.php
@@ -1,69 +1,70 @@
<?php
/**
* Defines the location of static resources on disk.
*/
abstract class CelerityResourcesOnDisk extends CelerityPhysicalResources {
abstract public function getPathToResources();
private function getPathToResource($name) {
return $this->getPathToResources().DIRECTORY_SEPARATOR.$name;
}
public function getResourceData($name) {
return Filesystem::readFile($this->getPathToResource($name));
}
public function findBinaryResources() {
return $this->findResourcesWithSuffixes($this->getBinaryFileSuffixes());
}
public function findTextResources() {
return $this->findResourcesWithSuffixes($this->getTextFileSuffixes());
}
public function getResourceModifiedTime($name) {
return (int)filemtime($this->getPathToResource($name));
}
protected function getBinaryFileSuffixes() {
return array(
'png',
'jpg',
'gif',
'swf',
+ 'woff',
);
}
protected function getTextFileSuffixes() {
return array(
'js',
'css',
);
}
private function findResourcesWithSuffixes(array $suffixes) {
$root = $this->getPathToResources();
$finder = id(new FileFinder($root))
->withType('f')
->withFollowSymlinks(true)
->setGenerateChecksums(true);
foreach ($suffixes as $suffix) {
$finder->withSuffix($suffix);
}
$raw_files = $finder->find();
$results = array();
foreach ($raw_files as $path => $hash) {
$readable = Filesystem::readablePath($path, $root);
$results[$readable] = $hash;
}
return $results;
}
}
diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php
index f4cd10be14..615a10fabd 100644
--- a/src/view/page/PhabricatorStandardPageView.php
+++ b/src/view/page/PhabricatorStandardPageView.php
@@ -1,427 +1,446 @@
<?php
/**
* This is a standard Phabricator page with menus, Javelin, DarkConsole, and
* basic styles.
*
*/
final class PhabricatorStandardPageView extends PhabricatorBarePageView {
private $baseURI;
private $applicationName;
private $glyph;
private $menuContent;
private $showChrome = true;
+ private $extraFonts;
private $disableConsole;
private $pageObjects = array();
private $applicationMenu;
public function setApplicationMenu(PHUIListView $application_menu) {
$this->applicationMenu = $application_menu;
return $this;
}
public function getApplicationMenu() {
return $this->applicationMenu;
}
public function setApplicationName($application_name) {
$this->applicationName = $application_name;
return $this;
}
public function setDisableConsole($disable) {
$this->disableConsole = $disable;
return $this;
}
public function getApplicationName() {
return $this->applicationName;
}
public function setBaseURI($base_uri) {
$this->baseURI = $base_uri;
return $this;
}
public function getBaseURI() {
return $this->baseURI;
}
public function setShowChrome($show_chrome) {
$this->showChrome = $show_chrome;
return $this;
}
public function getShowChrome() {
return $this->showChrome;
}
+ public function setExtraFonts($extra) {
+ $this->extraFonts = $extra;
+ return $this;
+ }
+
+ public function getExtraFonts() {
+ return $this->extraFonts;
+ }
+
public function appendPageObjects(array $objs) {
foreach ($objs as $obj) {
$this->pageObjects[] = $obj;
}
}
public function getTitle() {
$use_glyph = true;
$request = $this->getRequest();
if ($request) {
$user = $request->getUser();
if ($user && $user->loadPreferences()->getPreference(
PhabricatorUserPreferences::PREFERENCE_TITLES) !== 'glyph') {
$use_glyph = false;
}
}
$title = parent::getTitle();
$prefix = null;
if ($use_glyph) {
$prefix = $this->getGlyph();
} else {
$application_name = $this->getApplicationName();
if (strlen($application_name)) {
$prefix = '['.$application_name.']';
}
}
if (strlen($prefix)) {
$title = $prefix.' '.$title;
}
return $title;
}
protected function willRenderPage() {
parent::willRenderPage();
if (!$this->getRequest()) {
throw new Exception(
pht(
"You must set the Request to render a PhabricatorStandardPageView."));
}
$console = $this->getConsole();
require_celerity_resource('phabricator-core-css');
require_celerity_resource('phabricator-zindex-css');
require_celerity_resource('phui-button-css');
require_celerity_resource('phui-spacing-css');
require_celerity_resource('phui-form-css');
require_celerity_resource('sprite-gradient-css');
require_celerity_resource('phabricator-standard-page-view');
Javelin::initBehavior('workflow', array());
$request = $this->getRequest();
$user = null;
if ($request) {
$user = $request->getUser();
}
if ($user) {
$default_img_uri =
PhabricatorEnv::getCDNURI(
'/rsrc/image/icon/fatcow/document_black.png');
$download_form = phabricator_form(
$user,
array(
'action' => '#',
'method' => 'POST',
'class' => 'lightbox-download-form',
'sigil' => 'download',
),
phutil_tag(
'button',
array(),
pht('Download')));
Javelin::initBehavior(
'lightbox-attachments',
array(
'defaultImageUri' => $default_img_uri,
'downloadForm' => $download_form,
));
}
Javelin::initBehavior('aphront-form-disable-on-submit');
Javelin::initBehavior('toggle-class', array());
Javelin::initBehavior('konami', array());
Javelin::initBehavior('history-install');
Javelin::initBehavior('phabricator-gesture');
$current_token = null;
if ($user) {
$current_token = $user->getCSRFToken();
}
Javelin::initBehavior(
'refresh-csrf',
array(
'tokenName' => AphrontRequest::getCSRFTokenName(),
'header' => AphrontRequest::getCSRFHeaderName(),
'current' => $current_token,
));
Javelin::initBehavior('device');
if ($console) {
require_celerity_resource('aphront-dark-console-css');
$headers = array();
if (DarkConsoleXHProfPluginAPI::isProfilerStarted()) {
$headers[DarkConsoleXHProfPluginAPI::getProfilerHeader()] = 'page';
}
if (DarkConsoleServicesPlugin::isQueryAnalyzerRequested()) {
$headers[DarkConsoleServicesPlugin::getQueryAnalyzerHeader()] = true;
}
Javelin::initBehavior(
'dark-console',
array(
// NOTE: We use a generic label here to prevent input reflection
// and mitigate compression attacks like BREACH. See discussion in
// T3684.
'uri' => pht('Main Request'),
'selected' => $user ? $user->getConsoleTab() : null,
'visible' => $user ? (int)$user->getConsoleVisible() : true,
'headers' => $headers,
));
// Change this to initBehavior when there is some behavior to initialize
require_celerity_resource('javelin-behavior-error-log');
}
if ($user) {
$viewer = $user;
} else {
$viewer = new PhabricatorUser();
}
$menu = id(new PhabricatorMainMenuView())
->setUser($viewer);
if ($this->getController()) {
$menu->setController($this->getController());
}
if ($this->getApplicationMenu()) {
$menu->setApplicationMenu($this->getApplicationMenu());
}
$this->menuContent = $menu->render();
}
protected function getHead() {
$monospaced = PhabricatorEnv::getEnvConfig('style.monospace');
$monospaced_win = PhabricatorEnv::getEnvConfig('style.monospace.windows');
$request = $this->getRequest();
if ($request) {
$user = $request->getUser();
if ($user) {
$pref = $user->loadPreferences()->getPreference(
PhabricatorUserPreferences::PREFERENCE_MONOSPACED);
$monospaced = nonempty($pref, $monospaced);
$monospaced_win = nonempty($pref, $monospaced_win);
}
}
$response = CelerityAPI::getStaticResourceResponse();
+ $fonts = null;
+ if ($this->getExtraFonts()) {
+ $fonts = hsprintf("<link
+ href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700'
+ rel='stylesheet'
+ type='text/css'>");
+ }
+
return hsprintf(
- '%s<style type="text/css">'.
+ '%s%s<style type="text/css">'.
'.PhabricatorMonospaced, '.
'.phabricator-remarkup .remarkup-code-block { font: %s; } '.
'.platform-windows .PhabricatorMonospaced, '.
'.platform-windows .phabricator-remarkup '.
'.remarkup-code-block { font: %s; }'.
'</style>%s',
parent::getHead(),
+ $fonts,
phutil_safe_html($monospaced),
phutil_safe_html($monospaced_win),
$response->renderSingleResource('javelin-magical-init', 'phabricator'));
}
public function setGlyph($glyph) {
$this->glyph = $glyph;
return $this;
}
public function getGlyph() {
return $this->glyph;
}
protected function willSendResponse($response) {
$request = $this->getRequest();
$response = parent::willSendResponse($response);
$console = $request->getApplicationConfiguration()->getConsole();
if ($console) {
$response = PhutilSafeHTML::applyFunction(
'str_replace',
hsprintf('<darkconsole />'),
$console->render($request),
$response);
}
return $response;
}
protected function getBody() {
$console = $this->getConsole();
$user = null;
$request = $this->getRequest();
if ($request) {
$user = $request->getUser();
}
$header_chrome = null;
if ($this->getShowChrome()) {
$header_chrome = $this->menuContent;
}
$developer_warning = null;
if (PhabricatorEnv::getEnvConfig('phabricator.developer-mode') &&
DarkConsoleErrorLogPluginAPI::getErrors()) {
$developer_warning = phutil_tag_div(
'aphront-developer-error-callout',
pht(
'This page raised PHP errors. Find them in DarkConsole '.
'or the error log.'));
}
// Render the "you have unresolved setup issues..." warning.
$setup_warning = null;
if ($user && $user->getIsAdmin()) {
$open = PhabricatorSetupCheck::getOpenSetupIssueCount();
if ($open) {
$setup_warning = phutil_tag_div(
'setup-warning-callout',
phutil_tag(
'a',
array(
'href' => '/config/issue/',
),
pht('You have %d unresolved setup issue(s)...', $open)));
}
}
return
phutil_tag(
'div',
array(
'id' => 'base-page',
'class' => 'phabricator-standard-page',
),
array(
$developer_warning,
$setup_warning,
$header_chrome,
phutil_tag_div('phabricator-standard-page-body', array(
($console ? hsprintf('<darkconsole />') : null),
parent::getBody(),
phutil_tag('div', array('style' => 'clear: both;')),
)),
));
}
protected function getTail() {
$request = $this->getRequest();
$user = $request->getUser();
$container = null;
if ($user && $user->isLoggedIn()) {
$aphlict_object_id = celerity_generate_unique_node_id();
$aphlict_container_id = celerity_generate_unique_node_id();
$client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri');
$client_uri = new PhutilURI($client_uri);
if ($client_uri->getDomain() == 'localhost') {
$this_host = $this->getRequest()->getHost();
$this_host = new PhutilURI('http://'.$this_host.'/');
$client_uri->setDomain($this_host->getDomain());
}
$enable_debug = PhabricatorEnv::getEnvConfig('notification.debug');
Javelin::initBehavior(
'aphlict-listen',
array(
'id' => $aphlict_object_id,
'containerID' => $aphlict_container_id,
'server' => $client_uri->getDomain(),
'port' => $client_uri->getPort(),
'debug' => $enable_debug,
'pageObjects' => array_fill_keys($this->pageObjects, true),
));
$container = phutil_tag(
'div',
array(
'id' => $aphlict_container_id,
'style' =>
'position: absolute; width: 0; height: 0; overflow: hidden;',
),
'');
}
$response = CelerityAPI::getStaticResourceResponse();
$tail = array(
parent::getTail(),
$container,
$response->renderHTMLFooter(),
);
return phutil_implode_html("\n", $tail);
}
protected function getBodyClasses() {
$classes = array();
if (!$this->getShowChrome()) {
$classes[] = 'phabricator-chromeless-page';
}
$agent = AphrontRequest::getHTTPHeader('User-Agent');
// Try to guess the device resolution based on UA strings to avoid a flash
// of incorrectly-styled content.
$device_guess = 'device-desktop';
if (preg_match('@iPhone|iPod|(Android.*Chrome/[.0-9]* Mobile)@', $agent)) {
$device_guess = 'device-phone device';
} else if (preg_match('@iPad|(Android.*Chrome/)@', $agent)) {
$device_guess = 'device-tablet device';
}
$classes[] = $device_guess;
if (preg_match('@Windows@', $agent)) {
$classes[] = 'platform-windows';
} else if (preg_match('@Macintosh@', $agent)) {
$classes[] = 'platform-mac';
} else if (preg_match('@X11@', $agent)) {
$classes[] = 'platform-linux';
}
if ($this->getRequest()->getStr('__print__')) {
$classes[] = 'printable';
}
return implode(' ', $classes);
}
private function getConsole() {
if ($this->disableConsole) {
return null;
}
return $this->getRequest()->getApplicationConfiguration()->getConsole();
}
}
diff --git a/src/view/phui/PHUIDocumentView.php b/src/view/phui/PHUIDocumentView.php
index 8056951682..2b6feb7036 100644
--- a/src/view/phui/PHUIDocumentView.php
+++ b/src/view/phui/PHUIDocumentView.php
@@ -1,161 +1,182 @@
<?php
final class PHUIDocumentView extends AphrontTagView {
/* For mobile displays, where do you want the sidebar */
const NAV_BOTTOM = 'nav_bottom';
const NAV_TOP = 'nav_top';
+ const FONT_SOURCE_SANS = 'source-sans';
private $offset;
private $header;
private $sidenav;
private $topnav;
private $crumbs;
private $bookname;
private $bookdescription;
private $mobileview;
+ private $fontKit;
public function setOffset($offset) {
$this->offset = $offset;
return $this;
}
public function setHeader(PHUIHeaderView $header) {
$header->setGradient(PhabricatorActionHeaderView::HEADER_LIGHTBLUE);
$this->header = $header;
return $this;
}
public function setSideNav(PHUIListView $list, $display = self::NAV_BOTTOM) {
$list->setType(PHUIListView::SIDENAV_LIST);
$this->sidenav = $list;
$this->mobileview = $display;
return $this;
}
public function setTopNav(PHUIListView $list) {
$list->setType(PHUIListView::NAVBAR_LIST);
$this->topnav = $list;
return $this;
}
public function setCrumbs(PHUIListView $list) {
$this->crumbs = $list;
return $this;
}
public function setBook($name, $description) {
$this->bookname = $name;
$this->bookdescription = $description;
return $this;
}
+ public function setFontKit($kit) {
+ $this->fontKit = $kit;
+ return $this;
+ }
+
public function getTagAttributes() {
$classes = array();
if ($this->offset) {
$classes[] = 'phui-document-offset';
};
return array(
'class' => $classes,
);
}
public function getTagContent() {
require_celerity_resource('phui-document-view-css');
+ if ($this->fontKit) {
+ require_celerity_resource('phui-fontkit-css');
+ }
$classes = array();
$classes[] = 'phui-document-view';
if ($this->offset) {
$classes[] = 'phui-offset-view';
}
if ($this->sidenav) {
$classes[] = 'phui-sidenav-view';
}
$sidenav = null;
if ($this->sidenav) {
$sidenav = phutil_tag(
'div',
array(
'class' => 'phui-document-sidenav'
),
$this->sidenav);
}
$book = null;
if ($this->bookname) {
$book = phutil_tag(
'div',
array(
'class' => 'phui-document-bookname grouped'
),
array(
phutil_tag(
'span',
array('class' => 'bookname'),
$this->bookname),
phutil_tag(
'span',
array('class' => 'bookdescription'),
$this->bookdescription)));
}
$topnav = null;
if ($this->topnav) {
$topnav = phutil_tag(
'div',
array(
'class' => 'phui-document-topnav'
),
$this->topnav);
}
$crumbs = null;
if ($this->crumbs) {
$crumbs = phutil_tag(
'div',
array(
'class' => 'phui-document-crumbs'
),
$this->bookName);
}
+ if ($this->fontKit) {
+ $main_content = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'phui-font-'.$this->fontKit
+ ),
+ $this->renderChildren());
+ } else {
+ $main_content = $this->renderChildren();
+ }
+
$content_inner = phutil_tag(
'div',
array(
'class' => 'phui-document-inner',
),
array(
$book,
$this->header,
$topnav,
- $this->renderChildren(),
+ $main_content,
$crumbs
));
if ($this->mobileview == self::NAV_BOTTOM) {
$order = array($content_inner, $sidenav);
} else {
$order = array($sidenav, $content_inner);
}
$content = phutil_tag(
'div',
array(
'class' => 'phui-document-content',
),
$order);
$view = phutil_tag(
'div',
array(
'class' => implode(' ', $classes),
),
$content);
return $view;
}
}
diff --git a/webroot/rsrc/css/diviner/diviner-shared.css b/webroot/rsrc/css/diviner/diviner-shared.css
index b96987e074..7057c51c5a 100644
--- a/webroot/rsrc/css/diviner/diviner-shared.css
+++ b/webroot/rsrc/css/diviner/diviner-shared.css
@@ -1,161 +1,166 @@
/**
* @provides diviner-shared-css
*/
.diviner-monospace {
font-family: monospace;
font-size: 13px;
}
.diviner-table-view {
margin: 0 16px 24px;
}
.device-phone .diviner-table-view {
margin: 0 8px 16px;
}
-a.diviner-atom-signature-name {
- color: {$violet};
-}
-
.diviner-table-header {
padding: 4px 16px;
background-color: {$greybackground};
border-left: 1px solid {$lightblueborder};
border-right: 1px solid {$lightblueborder};
border-top: 1px solid {$lightblueborder};
display: inline-block;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
font-weight: bold;
color: {$bluetext};
}
.diviner-return-table-view,
.diviner-parameter-table-view {
width: 100%;
background: {$lightgreybackground};
border: 1px solid {$lightblueborder};
}
.diviner-return-table-type,
.diviner-parameter-table-type {
padding: 6px 8px 6px 12px;
white-space: nowrap;
text-align: right;
color: {$bluetext};
width: 20%;
}
.diviner-parameter-table-name {
padding: 6px 8px;
white-space: nowrap;
font-weight: bold;
}
.diviner-return-table-docs,
.diviner-parameter-table-docs {
padding: 6px 12px 6px 8px;
width: 80%;
background-color: #fff;
}
.diviner-document-section {
padding: 0 0 16px 0;
}
.device-phone .diviner-document-section {
padding: 0 8px 16px 0;
}
body .diviner-document-section .phui-header-view {
width: 100%;
+ font-size: 20px;
+ font-weight: 400;
}
.phui-property-list-view + .diviner-document-section {
margin-top: -1px;
}
.diviner-message-not-documented {
color: {$lightgreytext};
font-style: italic;
margin: 16px;
}
.diviner-atom-signature {
font-weight: normal;
}
.diviner-atom-signature-name {
font-weight: bold;
}
.diviner-list .diviner-atom-signature {
- color: {$greytext};
+ color: {$violet};
+ margin-left: -16px;
}
.diviner-list a {
font-weight: bold;
}
.diviner-method-implementation-header {
color: {$greytext};
margin-bottom: -8px;
}
.diviner-method-implementation-inherited {
color: {$darkgreytext};
}
.diviner-method-implementation-inherited .diviner-method-implementation-header {
color: {$lightgreytext};
}
/**
* Fix excessive padding between method headers and method documentation for
* methods with no inherited context.
*/
.diviner-document-section .phui-header-shell + .phabricator-remarkup {
padding-top: 0;
}
+.diviner-list {
+ padding-left: 12px;
+}
+
.diviner-list li {
- line-height: 18px;
- padding-bottom: 4px;
+ line-height: 20px;
+ padding-bottom: 12px;
}
/* - Book Index ----------------------------------------------------------------
How big lists of book indexes get displayed
*/
.diviner-book-item {
display: block;
- padding: 4px 16px;
- margin: 0 -16px;
+ padding: 6px 16px;
+ margin: 4px -16px;
}
.diviner-book-item:hover {
text-decoration: none;
}
.device-desktop .diviner-book-item:hover {
- background-color: {$lightgreybackground};
+ background-color: #F5EEFF;
}
.diviner-book-item-title {
- font-weight: bold;
+ font-weight: 700;
+ font-size: 16px;
+ color: {$darkbluetext};
}
.diviner-book-item-type {
color: {$lightgreytext};
padding-left: 8px
}
.diviner-book-item-subtitle {
display: block;
- line-height: 18px;
- color: {$lightbluetext};
+ line-height: 20px;
+ color: {$lightgreytext};
}
diff --git a/webroot/rsrc/css/font/font-source-sans-pro.css b/webroot/rsrc/css/font/font-source-sans-pro.css
new file mode 100644
index 0000000000..880042991c
--- /dev/null
+++ b/webroot/rsrc/css/font/font-source-sans-pro.css
@@ -0,0 +1,23 @@
+/**
+ * @provides font-source-sans-pro
+ */
+
+@font-face {
+ font-family: 'Source Sans Pro';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Source Sans Pro'),
+ local('SourceSansPro-Regular'),
+ url(/rsrc/externals/font/SourceSansPro.woff)
+ format('woff');
+}
+
+@font-face {
+ font-family: 'Source Sans Pro';
+ font-style: normal;
+ font-weight: 700;
+ src: local('Source Sans Pro Bold'),
+ local('SourceSansPro-Bold'),
+ url(/rsrc/externals/font/SourceSansProBold.woff)
+ format('woff');
+}
diff --git a/webroot/rsrc/css/phui/phui-document.css b/webroot/rsrc/css/phui/phui-document.css
index b3de223869..d944f634d9 100644
--- a/webroot/rsrc/css/phui/phui-document.css
+++ b/webroot/rsrc/css/phui/phui-document.css
@@ -1,159 +1,159 @@
/**
* @provides phui-document-view-css
*/
.phui-document-view {
margin-bottom: 16px;
position: relative;
}
.device-desktop .phui-document-view {
border: 1px solid {$lightblueborder};
border-bottom: 1px solid {$blueborder};
max-width: 960px;
margin: 16px auto;
}
.device-desktop .phui-document-view.phui-offset-view {
max-width: 800px;
}
.phui-document-sidenav {
position:absolute;
width: 200px;
text-overflow: ellipsis;
top: 0;
right: 0;
}
.device-phone .phui-document-sidenav {
position: static;
width: auto;
border-top: 1px solid #d7d7d7;
border-bottom: 1px solid #d7d7d7;
}
.device-phone .phui-sidenav-view .phui-document-inner {
margin: 0;
}
.phui-sidenav-view .phui-document-inner {
margin-right: 200px;
border-right: 1px solid #e7e7e7;
background: #fff;
}
.phui-document-bookname {
padding: 8px 16px;
color: #9ca5b5;
background-color: #fff;
border-bottom: 1px solid {$lightblueborder};
}
.device-phone .phui-document-bookname {
padding: 8px;
}
.phui-document-bookname .bookname {
float: left;
}
.phui-document-bookname .bookdescription {
float: right;
}
.phui-document-content .phui-header-shell {
border-top: none;
border-bottom: 1px solid {$lightblueborder};
}
.phui-document-content
.phui-header-shell.phui-header-no-backgound {
border-bottom: 1px solid {$thinblueborder};
margin: 0 0 16px 0;
}
.phui-document-content
.phui-header-shell.phui-header-no-backgound
.phui-header-view {
padding: 8px 0 4px;
- font-size: 14px;
+ font-size: 15px;
}
.phui-document-content .phui-header-view {
padding: 16px;
color: {$bluetext};
text-shadow: 0 1px 2px #fff;
}
.phui-document-content .phui-property-list-container {
border-color: #dde8ef;
}
.phui-document-content .phui-property-list-view {
border: none;
box-shadow: none;
margin: 0;
background-color: #f6f7f8;
}
.phui-document-content {
min-height: 240px;
background: #fff;
/* NOTE: This fixes margins, not floats, and can not be replaced with
the ".group" class. See T3150.
*/
overflow: hidden;
}
.device-desktop .phui-document-content .phabricator-action-list-view {
margin: 10px 10px 0 0;
background: {$lightgreybackground};
}
.device-phone .phui-document-content .phabricator-action-list-view {
margin: 0;
border-bottom: 1px solid #c0c5d1;
background: {$lightgreybackground};
}
.phui-document-content .phabricator-remarkup {
padding: 16px;
}
.device-phone .phui-document-content .phabricator-remarkup {
padding: 8px;
}
.device-desktop .phui-document-content .phabricator-action-list-view {
position: absolute;
top: 50px;
right: -172px;
float: none;
background: #fff;
border-radius: 0;
box-shadow: none;
border: none;
border-top: 1px solid {$thinblueborder};
border-bottom: 1px solid {$thinblueborder};
border-right: 1px solid {$thinblueborder};
width: 160px;
}
.device-phone .phui-document-content .phabricator-remarkup-toc {
width: 120px;
}
.phui-document-content .phabricator-remarkup .remarkup-code-block {
clear: both;
margin: 16px 0;
}
.device-desktop .phui-document-offset {
padding-right: 160px;
}
.phui-document-view .phui-property-list-view {
border-bottom: 1px solid {$thinblueborder};
}
diff --git a/webroot/rsrc/css/phui/phui-fontkit.css b/webroot/rsrc/css/phui/phui-fontkit.css
new file mode 100644
index 0000000000..cbd5890697
--- /dev/null
+++ b/webroot/rsrc/css/phui/phui-fontkit.css
@@ -0,0 +1,38 @@
+/**
+ * @provides phui-fontkit-css
+ */
+
+.phui-font-source-sans {
+ font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
+ font-size: 15px;
+ font-weight: 400;
+ line-height: 20px;
+}
+
+.phui-font-source-sans .phabricator-remarkup h2 {
+ padding: 8px 24px 8px 0;
+ border-bottom: 1px solid {$thinblueborder};
+ font-size: 20px;
+ font-weight: 400;
+ color: {$bluetext};
+ margin: 0 0 16px;
+}
+
+.phui-font-source-sans .phabricator-remarkup tt {
+ font-size: 13px;
+ padding: 1px 3px 2px;
+}
+
+.phui-font-source-sans .phui-property-list-section {
+ border-bottom: 1px solid {$thinblueborder};
+ margin-bottom: 8px;
+ background: {$lightgreybackground};
+}
+
+.phui-font-source-sans .phui-property-list-container {
+ padding-bottom: 6px;
+}
+
+.phui-font-source-sans a {
+ color: {$blue};
+}
diff --git a/webroot/rsrc/css/phui/phui-header-view.css b/webroot/rsrc/css/phui/phui-header-view.css
index e2959375c6..dbe094cc23 100644
--- a/webroot/rsrc/css/phui/phui-header-view.css
+++ b/webroot/rsrc/css/phui/phui-header-view.css
@@ -1,124 +1,123 @@
/**
* @provides phui-header-view-css
*/
.phui-header-shell {
background-color: #e0e3ec;
border-width: 1px 0;
border-style: solid;
border-color: #c0c5d1;
overflow: hidden;
}
body .phui-header-shell.phui-header-no-backgound {
background-color: transparent;
border: none;
}
body .phui-header-shell.phui-bleed-header {
- background-color: {$lightgreybackground};
- border-top: 1px solid {$thinblueborder};
- border-bottom: none;
+ background-color: #fff;
+ border-bottom: 1px solid {$thinblueborder};
width: auto;
- margin-bottom: 16px;
+ margin: 16px;
}
body .phui-header-shell.phui-bleed-header
.phui-header-view {
- padding: 8px 24px 8px 16px;
+ padding: 8px 24px 8px 0;
color: {$bluetext};
}
.phui-header-shell + .phabricator-form-view {
border-top-width: 0;
}
.phui-property-list-view + .diviner-document-section {
margin-top: -1px;
}
.phui-header-view {
padding: 16px;
font-size: 15px;
color: {$darkbluetext};
position: relative;
}
.phui-header-view a,
.phui-header-view a.simple {
color: {$darkbluetext};
}
.phui-header-view .phui-header-action-links {
position: absolute;
top: 5px;
right: 0;
}
.device-phone .phui-header-action-link .phui-button-text {
visibility: hidden;
width: 0;
margin-left: 12px;
}
.phui-header-divider {
margin: 0 4px;
font-weight: normal;
color: {$lightbluetext};
}
body.device-phone .phui-header-view {
padding: 12px 8px;
}
.phui-header-tags {
margin-left: 12px;
font-size: 13px;
}
.phui-header-tags .phui-tag-view {
margin-left: 4px;
}
.phui-header-image {
display: inline-block;
background-repeat: no-repeat;
border: 1px solid white;
width: 50px;
height: 50px;
margin: 12px;
float: left;
}
.phui-header-subheader {
color: {$lightbluetext};
font-weight: normal;
font-size: 13px;
margin-top: 4px;
}
.phui-header-subheader .sprite-status {
display: inline-block;
margin: -2px 4px -2px 0;
}
.phui-header-subheader {
color: {$bluetext};
}
.phui-header-subheader .policy-link {
color: {$bluetext};
}
.phui-header-subheader .phui-header-status-dark {
color: #111;
text-shadow: 0 1px #fff;
}
.phui-header-subheader .phui-header-status-red {
color: {$red};
}
.phui-header-subheader .phui-header-status-green {
color: {$green};
}
diff --git a/webroot/rsrc/externals/font/LICENSE b/webroot/rsrc/externals/font/LICENSE
new file mode 100644
index 0000000000..07542572e3
--- /dev/null
+++ b/webroot/rsrc/externals/font/LICENSE
@@ -0,0 +1,93 @@
+Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+
+This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/webroot/rsrc/externals/font/SourceSansPro.woff b/webroot/rsrc/externals/font/SourceSansPro.woff
new file mode 100644
index 0000000000..58651d266d
Binary files /dev/null and b/webroot/rsrc/externals/font/SourceSansPro.woff differ
diff --git a/webroot/rsrc/externals/font/SourceSansProBold.woff b/webroot/rsrc/externals/font/SourceSansProBold.woff
new file mode 100644
index 0000000000..12bd5526c9
Binary files /dev/null and b/webroot/rsrc/externals/font/SourceSansProBold.woff differ

File Metadata

Mime Type
text/x-diff
Expires
Sun, Sep 7, 10:02 AM (1 d, 3 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
223017
Default Alt Text
(174 KB)

Event Timeline