From 31006b86a2e9883d8a4c5fe18128821b325773ab Mon Sep 17 00:00:00 2001 From: Jan Szejko <janek37@gmail.com> Date: Thu, 15 Dec 2016 12:43:14 +0100 Subject: [PATCH] pep8, style, dead code cleanup etc. --- .gitignore | 1 + apps/build/management/commands/build.py | 26 +- apps/catalogue/admin.py | 5 + apps/catalogue/ebook_utils.py | 15 - apps/catalogue/helpers.py | 21 +- .../catalogue/locale/pl/LC_MESSAGES/django.mo | Bin 10336 -> 10337 bytes .../catalogue/locale/pl/LC_MESSAGES/django.po | 2 +- apps/catalogue/management/__init__.py | 122 - .../catalogue/management/commands/__init__.py | 43 - apps/catalogue/management/commands/fixdc.py | 54 - .../management/commands/import_wl.py | 91 - apps/catalogue/models/__init__.py | 2 - apps/catalogue/models/book.py | 436 -- apps/catalogue/models/document.py | 5 +- apps/catalogue/models/listeners.py | 46 - apps/catalogue/models/plan.py | 1 + apps/catalogue/models/publish_log.py | 4 +- apps/catalogue/models/template.py | 5 + apps/catalogue/signals.py | 5 + apps/catalogue/tasks.py | 6 + .../templates/catalogue/activity.html | 16 - .../templates/catalogue/book_append_to.html | 14 - .../templates/catalogue/book_detail.html | 90 - .../templates/catalogue/book_edit.html | 14 - .../templates/catalogue/book_list/chunk.html | 26 - .../templates/catalogue/chunk_add.html | 16 - .../templates/catalogue/chunk_edit.html | 20 - .../templates/catalogue/document_upload.html | 69 - .../templates/catalogue/user_list.html | 18 - .../templates/catalogue/user_page.html | 14 - apps/catalogue/templates/catalogue/wall.html | 35 - apps/catalogue/templatetags/catalogue.py | 20 +- .../catalogue/templatetags/catalogue_files.py | 6 +- apps/catalogue/templatetags/common_tags.py | 5 + apps/catalogue/templatetags/document_list.py | 143 +- apps/catalogue/templatetags/flat_lang.py | 9 +- .../templatetags/set_get_parameter.py | 7 +- apps/catalogue/templatetags/wall.py | 155 - apps/catalogue/tests/__init__.py | 4 - apps/catalogue/tests/book.py | 54 - apps/catalogue/tests/files/chunk1.xml | 42 - apps/catalogue/tests/files/chunk2.xml | 11 - apps/catalogue/tests/files/expected.xml | 49 - apps/catalogue/tests/gallery.py | 148 - apps/catalogue/tests/publish.py | 40 - apps/catalogue/tests/xml_updater.py | 35 - apps/catalogue/urls.py | 37 +- apps/catalogue/views.py | 317 +- apps/catalogue/xml_tools.py | 12 +- apps/cover/__init__.py | 0 apps/cover/forms.py | 102 - apps/cover/locale/pl/LC_MESSAGES/django.mo | Bin 1365 -> 0 bytes apps/cover/locale/pl/LC_MESSAGES/django.po | 95 - apps/cover/models.py | 48 - apps/cover/templates/cover/add_image.html | 67 - apps/cover/templates/cover/image_detail.html | 54 - apps/cover/templates/cover/image_list.html | 30 - apps/cover/tests.py | 20 - apps/cover/urls.py | 20 - apps/cover/utils.py | 13 - apps/cover/views.py | 139 - apps/dvcs/models.py | 69 +- apps/dvcs/signals.py | 7 +- apps/dvcs/storage.py | 10 +- apps/dvcs/tests/__init__.py | 183 +- apps/dvcs/version.py | 7 +- apps/email_mangler/templatetags/email.py | 8 +- apps/fileupload/forms.py | 6 + apps/fileupload/models.py | 1 - apps/fileupload/templatetags/upload_tags.py | 22 +- apps/fileupload/urls.py | 9 +- apps/fileupload/views.py | 33 +- apps/organizations/admin.py | 6 +- apps/organizations/forms.py | 10 +- apps/organizations/templatetags/urlinfo.py | 6 + apps/organizations/urls.py | 3 +- apps/organizations/views.py | 13 +- apps/wiki/forms.py | 6 +- apps/wiki/helpers.py | 5 + apps/wiki/models.py | 0 apps/wiki/nice_diff.py | 4 +- apps/wiki/settings.py | 5 + .../browser/common.js | 201 - .../browser/css/global-vars/simple.css | 3 - .../browser/css/modify-vars/simple.css | 7 - .../browser/css/relative-urls/urls.css | 34 - .../browser/css/rootpath-relative/urls.css | 34 - .../browser/css/rootpath/urls.css | 31 - .../browser/css/urls.css | 49 - .../browser/es5.js | 27 - .../browser/jasmine-html.js | 681 -- .../browser/jasmine.css | 82 - .../browser/jasmine.js | 2600 ------ .../browser/less.js | 6937 ----------------- .../less/console-errors/test-error.less | 3 - .../less/console-errors/test-error.txt | 2 - .../browser/less/global-vars/simple.less | 3 - .../browser/less/imports/urls.less | 4 - .../browser/less/imports/urls2.less | 4 - .../less/modify-vars/imports/simple2.less | 4 - .../browser/less/modify-vars/simple.less | 6 - .../browser/less/relative-urls/urls.less | 32 - .../browser/less/rootpath-relative/urls.less | 32 - .../browser/less/rootpath/urls.less | 32 - .../browser/less/urls.less | 56 - .../browser/phantom-runner.js | 150 - .../browser/runner-browser-options.js | 42 - .../browser/runner-browser-spec.js | 12 - .../browser/runner-console-errors.js | 5 - .../browser/runner-errors-options.js | 5 - .../browser/runner-errors-spec.js | 4 - .../browser/runner-global-vars-options.js | 4 - .../browser/runner-global-vars-spec.js | 3 - .../browser/runner-legacy-options.js | 4 - .../browser/runner-legacy-spec.js | 3 - .../browser/runner-main-options.js | 15 - .../browser/runner-main-spec.js | 3 - .../browser/runner-modify-vars-options.js | 2 - .../browser/runner-modify-vars-spec.js | 42 - .../browser/runner-no-js-errors-options.js | 4 - .../browser/runner-no-js-errors-spec.js | 4 - .../browser/runner-production-options.js | 3 - .../browser/runner-production-spec.js | 5 - .../browser/runner-relative-urls-options.js | 3 - .../browser/runner-relative-urls-spec.js | 3 - .../browser/runner-rootpath-options.js | 3 - .../runner-rootpath-relative-options.js | 4 - .../browser/runner-rootpath-relative-spec.js | 3 - .../browser/runner-rootpath-spec.js | 3 - .../browser/test-runner-template.tmpl | 47 - .../css/charsets.css | 1 - .../css/colors.css | 80 - .../css/comments.css | 69 - .../css/compression/compression.css | 3 - .../css/css-3.css | 125 - .../css/css-escapes.css | 24 - .../css/css-guards.css | 18 - .../css/css.css | 94 - .../css/debug/linenumbers-all.css | 43 - .../css/debug/linenumbers-comments.css | 35 - .../css/debug/linenumbers-mediaquery.css | 35 - .../css/extend-chaining.css | 81 - .../css/extend-clearfix.css | 19 - .../css/extend-exact.css | 37 - .../css/extend-media.css | 24 - .../css/extend-nest.css | 57 - .../css/extend-selector.css | 80 - .../css/extend.css | 76 - .../css/extract-and-length.css | 133 - .../css/functions.css | 139 - .../css/ie-filters.css | 9 - .../css/import-inline.css | 5 - .../css/import-interpolation.css | 6 - .../css/import-once.css | 15 - .../css/import-reference.css | 55 - .../css/import.css | 36 - .../css/javascript.css | 23 - .../css/lazy-eval.css | 3 - .../css/legacy/legacy.css | 7 - .../css/media.css | 219 - .../css/merge.css | 22 - .../css/mixins-args.css | 113 - .../css/mixins-closure.css | 9 - .../css/mixins-guards.css | 82 - .../css/mixins-important.css | 45 - .../css/mixins-named-args.css | 27 - .../css/mixins-nested.css | 14 - .../css/mixins-pattern.css | 47 - .../css/mixins.css | 141 - .../css/no-output.css | 0 .../css/operations.css | 49 - .../css/parens.css | 33 - .../css/rulesets.css | 33 - .../css/scope.css | 35 - .../css/selectors.css | 142 - .../css/static-urls/urls.css | 40 - .../css/strings.css | 43 - .../css/urls.css | 62 - .../css/variables.css | 45 - .../css/whitespace.css | 42 - .../data/data-uri-fail.png | Bin 52420 -> 0 bytes .../data/image.jpg | 1 - .../data/page.html | 1 - .../less-test.js | 260 - .../less/charsets.less | 3 - .../less/colors.less | 92 - .../less/comments.less | 83 - .../less/compression/compression.less | 32 - .../less/css-3.less | 125 - .../less/css-escapes.less | 33 - .../less/css-guards.less | 64 - .../less/css.less | 107 - .../less/debug/import/test.less | 25 - .../less/debug/linenumbers.less | 23 - .../less/errors/add-mixed-units.less | 3 - .../less/errors/add-mixed-units.txt | 2 - .../less/errors/add-mixed-units2.less | 3 - .../less/errors/add-mixed-units2.txt | 2 - .../errors/bad-variable-declaration1.less | 1 - .../less/errors/bad-variable-declaration1.txt | 2 - .../less/errors/color-func-invalid-color.less | 3 - .../less/errors/color-func-invalid-color.txt | 4 - .../less/errors/color-operation-error.less | 3 - .../less/errors/color-operation-error.txt | 2 - .../less/errors/comment-in-selector.less | 1 - .../less/errors/comment-in-selector.txt | 2 - .../less/errors/divide-mixed-units.less | 3 - .../less/errors/divide-mixed-units.txt | 4 - .../less/errors/extend-no-selector.less | 3 - .../less/errors/extend-no-selector.txt | 3 - .../less/errors/extend-not-at-end.less | 3 - .../less/errors/extend-not-at-end.txt | 3 - .../less/errors/import-missing.less | 6 - .../less/errors/import-missing.txt | 3 - .../less/errors/import-no-semi.less | 1 - .../less/errors/import-no-semi.txt | 2 - .../less/errors/import-subfolder1.less | 1 - .../less/errors/import-subfolder1.txt | 3 - .../less/errors/import-subfolder2.less | 1 - .../less/errors/import-subfolder2.txt | 2 - .../errors/imports/import-subfolder1.less | 1 - .../errors/imports/import-subfolder2.less | 1 - .../less/errors/imports/import-test.less | 4 - .../imports/subfolder/mixin-not-defined.less | 1 - .../subfolder/parse-error-curly-bracket.less | 1 - .../less/errors/javascript-error.less | 3 - .../less/errors/javascript-error.txt | 4 - .../errors/mixed-mixin-definition-args-1.less | 6 - .../errors/mixed-mixin-definition-args-1.txt | 4 - .../errors/mixed-mixin-definition-args-2.less | 6 - .../errors/mixed-mixin-definition-args-2.txt | 4 - .../less/errors/mixin-not-defined.less | 11 - .../less/errors/mixin-not-defined.txt | 3 - .../less/errors/mixin-not-matched.less | 6 - .../less/errors/mixin-not-matched.txt | 3 - .../less/errors/mixin-not-matched2.less | 6 - .../less/errors/mixin-not-matched2.txt | 3 - .../multiple-guards-on-css-selectors.less | 4 - .../multiple-guards-on-css-selectors.txt | 4 - .../less/errors/multiply-mixed-units.less | 7 - .../less/errors/multiply-mixed-units.txt | 4 - .../less/errors/parens-error-1.less | 3 - .../less/errors/parens-error-1.txt | 4 - .../less/errors/parens-error-2.less | 3 - .../less/errors/parens-error-2.txt | 4 - .../less/errors/parens-error-3.less | 3 - .../less/errors/parens-error-3.txt | 4 - .../errors/parse-error-curly-bracket.less | 1 - .../less/errors/parse-error-curly-bracket.txt | 2 - .../errors/parse-error-missing-bracket.less | 2 - .../errors/parse-error-missing-bracket.txt | 3 - .../less/errors/parse-error-with-import.less | 13 - .../less/errors/parse-error-with-import.txt | 4 - .../less/errors/property-ie5-hack.less | 3 - .../less/errors/property-ie5-hack.txt | 4 - .../less/errors/property-in-root.less | 4 - .../less/errors/property-in-root.txt | 4 - .../less/errors/property-in-root2.less | 1 - .../less/errors/property-in-root2.txt | 4 - .../less/errors/property-in-root3.less | 4 - .../less/errors/property-in-root3.txt | 3 - .../less/errors/recursive-variable.less | 1 - .../less/errors/recursive-variable.txt | 2 - .../less/errors/svg-gradient1.less | 3 - .../less/errors/svg-gradient1.txt | 4 - .../less/errors/svg-gradient2.less | 3 - .../less/errors/svg-gradient2.txt | 4 - .../less/errors/svg-gradient3.less | 3 - .../less/errors/svg-gradient3.txt | 4 - .../less/errors/unit-function.less | 3 - .../less/errors/unit-function.txt | 4 - .../less/extend-chaining.less | 91 - .../less/extend-clearfix.less | 19 - .../less/extend-exact.less | 46 - .../less/extend-media.less | 24 - .../less/extend-nest.less | 65 - .../less/extend-selector.less | 99 - .../less/extend.less | 81 - .../less/extract-and-length.less | 133 - .../less/functions.less | 153 - .../less/ie-filters.less | 15 - .../less/import-inline.less | 2 - .../less/import-interpolation.less | 8 - .../less/import-once.less | 6 - .../less/import-reference.less | 18 - .../less/import.less | 21 - .../import/deeper/import-once-test-a.less | 1 - .../import-and-relative-paths-test.less | 6 - .../less/import/import-charset-test.less | 1 - .../less/import/import-interpolation.less | 1 - .../less/import/import-interpolation2.less | 5 - .../less/import/import-once-test-c.less | 6 - .../less/import/import-reference.less | 43 - .../less/import/import-test-a.less | 3 - .../less/import/import-test-b.less | 8 - .../less/import/import-test-c.less | 6 - .../less/import/import-test-d.css | 1 - .../less/import/import-test-e.less | 2 - .../less/import/import-test-f.less | 5 - .../less/import/imports/font.less | 8 - .../less/import/imports/logo.less | 5 - .../less/import/invalid-css.less | 1 - .../less/import/urls.less | 1 - .../less/javascript.less | 29 - .../less/lazy-eval.less | 6 - .../less/legacy/legacy.less | 7 - .../less/media.less | 234 - .../less/merge.less | 51 - .../less/mixins-args.less | 215 - .../less/mixins-closure.less | 26 - .../less/mixins-guards.less | 153 - .../less/mixins-important.less | 25 - .../less/mixins-named-args.less | 36 - .../less/mixins-nested.less | 22 - .../less/mixins-pattern.less | 99 - .../less/mixins.less | 141 - .../less/no-js-errors/no-js-errors.less | 3 - .../less/no-js-errors/no-js-errors.txt | 4 - .../less/no-output.less | 2 - .../less/operations.less | 62 - .../less/parens.less | 41 - .../less/rulesets.less | 30 - .../less/scope.less | 79 - .../less/selectors.less | 144 - .../less/sourcemaps/basic.less | 27 - .../less/sourcemaps/imported.css | 7 - .../less/static-urls/urls.less | 32 - .../less/strings.less | 57 - .../less/urls.less | 66 - .../less/variables.less | 83 - .../less/whitespace.less | 44 - .../sourcemaps/basic.json | 1 - .../sourcemaps/index.html | 17 - .../expected/cleancss.css | 1 - .../expected/cleancssReport.css | 1 - .../expected/compress.css | 1 - .../expected/concat.css | 12 - .../expected/customFunctions.css | 5 - .../expected/ieCompatFalse.css | 5 - .../expected/ieCompatTrue.css | 5 - .../expected/individual/level2/style3.css | 3 - .../expected/individual/style.css | 3 - .../expected/individual/style2.css | 3 - .../expected/individual_flatten/style.css | 3 - .../expected/individual_flatten/style2.css | 3 - .../expected/individual_flatten/style3.css | 3 - .../expected/less.css | 3 - .../expected/nomatches.css | 0 .../expected/nopaths.css | 3 - .../expected/variablesAsLess.css | 3 - .../fixtures/customFunctions.less | 5 - .../fixtures/ieCompat.less | 5 - .../fixtures/include/bob.jpg | Bin 65127 -> 0 bytes .../fixtures/include/variables.less | 1 - .../fixtures/include/variablesAsLess.css | 1 - .../fixtures/level2/style3.less | 4 - .../fixtures/nopaths.less | 4 - .../fixtures/style.less | 4 - .../fixtures/style2.less | 4 - .../fixtures/style3.less | 4 - .../fixtures/variablesAsLess.less | 4 - .../less_test.js | 130 - .../wiki/templates/wiki/document_details.html | 49 - .../templates/wiki/document_details_base.html | 58 - .../wiki/document_details_readonly.html | 27 - .../templates/wiki/tabs/history_view.html | 41 - .../wiki/tabs/history_view_item.html | 4 - .../templates/wiki/tabs/summary_view.html | 44 - .../wiki/tabs/summary_view_item.html | 4 - apps/wiki/urls.py | 9 +- apps/wiki/views.py | 157 +- deployment.py | 14 +- lib/librarian | 2 +- redakcja/context_processors.py | 1 + redakcja/forms.py | 6 + redakcja/settings/__init__.py | 15 +- redakcja/settings/common.py | 42 +- redakcja/settings/compress.py | 19 +- redakcja/settings/integration_test.py | 6 +- redakcja/settings/test.py | 15 +- redakcja/static/css/html.css | 5 +- redakcja/static/js/wiki/loader.js | 151 - redakcja/static/js/wiki/view_summary.js | 4 +- redakcja/static/js/wiki/wikiapi.js | 549 +- .../templates/registration/head_login.html | 6 +- redakcja/urls.py | 28 +- redakcja/views.py | 13 +- redakcja/wsgi.py | 6 +- tests/integration/__init__.py | 7 +- tests/integration/base.py | 28 +- tests/integration/smoke_test.py | 12 +- 391 files changed, 733 insertions(+), 21676 deletions(-) delete mode 100644 apps/catalogue/management/__init__.py delete mode 100644 apps/catalogue/management/commands/__init__.py delete mode 100644 apps/catalogue/management/commands/fixdc.py delete mode 100644 apps/catalogue/management/commands/import_wl.py delete mode 100755 apps/catalogue/models/book.py delete mode 100755 apps/catalogue/models/listeners.py delete mode 100755 apps/catalogue/templates/catalogue/activity.html delete mode 100755 apps/catalogue/templates/catalogue/book_append_to.html delete mode 100755 apps/catalogue/templates/catalogue/book_edit.html delete mode 100755 apps/catalogue/templates/catalogue/book_list/chunk.html delete mode 100755 apps/catalogue/templates/catalogue/chunk_add.html delete mode 100755 apps/catalogue/templates/catalogue/chunk_edit.html delete mode 100644 apps/catalogue/templates/catalogue/document_upload.html delete mode 100755 apps/catalogue/templates/catalogue/user_list.html delete mode 100755 apps/catalogue/templates/catalogue/wall.html delete mode 100755 apps/catalogue/templatetags/wall.py delete mode 100644 apps/catalogue/tests/book.py delete mode 100755 apps/catalogue/tests/files/chunk1.xml delete mode 100755 apps/catalogue/tests/files/chunk2.xml delete mode 100755 apps/catalogue/tests/files/expected.xml delete mode 100644 apps/catalogue/tests/gallery.py delete mode 100644 apps/catalogue/tests/publish.py delete mode 100644 apps/catalogue/tests/xml_updater.py delete mode 100644 apps/cover/__init__.py delete mode 100755 apps/cover/forms.py delete mode 100644 apps/cover/locale/pl/LC_MESSAGES/django.mo delete mode 100644 apps/cover/locale/pl/LC_MESSAGES/django.po delete mode 100644 apps/cover/models.py delete mode 100755 apps/cover/templates/cover/add_image.html delete mode 100755 apps/cover/templates/cover/image_detail.html delete mode 100755 apps/cover/templates/cover/image_list.html delete mode 100644 apps/cover/tests.py delete mode 100644 apps/cover/urls.py delete mode 100755 apps/cover/utils.py delete mode 100644 apps/cover/views.py delete mode 100644 apps/fileupload/models.py delete mode 100644 apps/wiki/models.py delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/common.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/global-vars/simple.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/modify-vars/simple.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/relative-urls/urls.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/rootpath-relative/urls.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/rootpath/urls.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/urls.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/es5.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/jasmine-html.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/jasmine.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/jasmine.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/console-errors/test-error.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/console-errors/test-error.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/global-vars/simple.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/imports/urls.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/imports/urls2.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/modify-vars/imports/simple2.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/modify-vars/simple.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/relative-urls/urls.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/rootpath-relative/urls.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/rootpath/urls.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/urls.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/phantom-runner.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-browser-options.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-browser-spec.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-console-errors.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-errors-options.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-errors-spec.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-global-vars-options.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-global-vars-spec.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-legacy-options.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-legacy-spec.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-main-options.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-main-spec.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-modify-vars-options.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-modify-vars-spec.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-no-js-errors-options.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-no-js-errors-spec.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-production-options.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-production-spec.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-relative-urls-options.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-relative-urls-spec.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-options.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-relative-options.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-relative-spec.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-spec.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/test-runner-template.tmpl delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/charsets.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/colors.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/comments.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/compression/compression.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css-3.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css-escapes.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css-guards.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/debug/linenumbers-all.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/debug/linenumbers-comments.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/debug/linenumbers-mediaquery.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-chaining.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-clearfix.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-exact.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-media.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-nest.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-selector.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extract-and-length.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/functions.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/ie-filters.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-inline.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-interpolation.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-once.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-reference.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/javascript.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/lazy-eval.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/legacy/legacy.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/media.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/merge.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-args.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-closure.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-guards.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-important.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-named-args.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-nested.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-pattern.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/no-output.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/operations.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/parens.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/rulesets.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/scope.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/selectors.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/static-urls/urls.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/strings.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/urls.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/variables.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/whitespace.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/data/data-uri-fail.png delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/data/image.jpg delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/data/page.html delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less-test.js delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/charsets.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/colors.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/comments.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/compression/compression.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css-3.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css-escapes.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css-guards.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/debug/import/test.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/debug/linenumbers.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units2.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units2.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/bad-variable-declaration1.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/bad-variable-declaration1.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-func-invalid-color.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-func-invalid-color.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-operation-error.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-operation-error.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/comment-in-selector.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/comment-in-selector.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/divide-mixed-units.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/divide-mixed-units.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-no-selector.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-no-selector.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-not-at-end.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-not-at-end.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-missing.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-missing.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-no-semi.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-no-semi.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder1.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder1.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder2.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder2.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/import-subfolder1.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/import-subfolder2.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/import-test.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/subfolder/mixin-not-defined.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/subfolder/parse-error-curly-bracket.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/javascript-error.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/javascript-error.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-1.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-1.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-2.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-2.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-defined.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-defined.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched2.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched2.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiple-guards-on-css-selectors.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiple-guards-on-css-selectors.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiply-mixed-units.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiply-mixed-units.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-1.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-1.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-2.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-2.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-3.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-3.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-curly-bracket.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-curly-bracket.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-missing-bracket.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-missing-bracket.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-with-import.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-with-import.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-ie5-hack.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-ie5-hack.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root2.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root2.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root3.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root3.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/recursive-variable.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/recursive-variable.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient1.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient1.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient2.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient2.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient3.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient3.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/unit-function.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/unit-function.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-chaining.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-clearfix.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-exact.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-media.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-nest.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-selector.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extract-and-length.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/functions.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/ie-filters.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-inline.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-interpolation.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-once.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-reference.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/deeper/import-once-test-a.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-and-relative-paths-test.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-charset-test.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-interpolation.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-interpolation2.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-once-test-c.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-reference.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-a.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-b.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-c.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-d.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-e.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-f.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/imports/font.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/imports/logo.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/invalid-css.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/urls.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/javascript.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/lazy-eval.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/legacy/legacy.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/media.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/merge.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-args.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-closure.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-guards.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-important.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-named-args.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-nested.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-pattern.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/no-js-errors/no-js-errors.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/no-js-errors/no-js-errors.txt delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/no-output.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/operations.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/parens.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/rulesets.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/scope.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/selectors.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/sourcemaps/basic.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/sourcemaps/imported.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/static-urls/urls.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/strings.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/urls.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/variables.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/whitespace.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/sourcemaps/basic.json delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/sourcemaps/index.html delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/cleancss.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/cleancssReport.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/compress.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/concat.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/customFunctions.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/ieCompatFalse.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/ieCompatTrue.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual/level2/style3.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual/style.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual/style2.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual_flatten/style.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual_flatten/style2.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual_flatten/style3.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/less.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/nomatches.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/nopaths.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/variablesAsLess.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/customFunctions.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/ieCompat.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/include/bob.jpg delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/include/variables.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/include/variablesAsLess.css delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/level2/style3.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/nopaths.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/style.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/style2.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/style3.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/variablesAsLess.less delete mode 100644 apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/less_test.js delete mode 100644 apps/wiki/templates/wiki/document_details.html delete mode 100644 apps/wiki/templates/wiki/document_details_base.html delete mode 100644 apps/wiki/templates/wiki/document_details_readonly.html delete mode 100644 apps/wiki/templates/wiki/tabs/history_view.html delete mode 100644 apps/wiki/templates/wiki/tabs/history_view_item.html delete mode 100644 apps/wiki/templates/wiki/tabs/summary_view.html delete mode 100644 apps/wiki/templates/wiki/tabs/summary_view_item.html delete mode 100644 redakcja/static/js/wiki/loader.js diff --git a/.gitignore b/.gitignore index a9dc4e6e..a040bd6f 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ nbproject/* .idea node_modules +static--wiki--editor--node_modules* /static_test chromedriver.log diff --git a/apps/build/management/commands/build.py b/apps/build/management/commands/build.py index 50097cff..f0d1df8f 100644 --- a/apps/build/management/commands/build.py +++ b/apps/build/management/commands/build.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# import os from subprocess import call from optparse import make_option @@ -9,25 +14,29 @@ from django.core.management import call_command class Command(BaseCommand): option_list = BaseCommand.option_list + ( - make_option('--node-bin-path', + make_option( + '--node-bin-path', action='store', dest='node_bin_path', type='string', default=None, help='Path to node binary'), - make_option('--npm-bin', + make_option( + '--npm-bin', action='store', dest='npm_bin', type='string', default='npm', help='Path to npm binary'), - make_option('--editor-npm-env', + make_option( + '--editor-npm-env', action='store', dest='editor_npm_env', type='string', default=None, help='Destination path of npm environment, defaults to ./node_modules'), - make_option('--editor-optimize', + make_option( + '--editor-optimize', action='store', dest='editor_optimize', type='string', @@ -48,7 +57,7 @@ class Command(BaseCommand): assert os.path.isdir(npm_env) os.symlink(npm_env, os.path.join(rng_base_dir, 'node_modules')) try: - call([options['npm_bin'], 'install'], cwd = rng_base_dir) + call([options['npm_bin'], 'install'], cwd=rng_base_dir) except OSError: raise CommandError('Something went wrong, propably npm binary not found. Tried: %s' % options['npm_bin']) @@ -56,9 +65,10 @@ class Command(BaseCommand): if options['node_bin_path']: # grunt needs npm binary to be foundable in PATH os.environ['PATH'] = '%s:%s' % (options['node_bin_path'], os.environ['PATH']) - args = ['./node_modules/.bin/grunt', 'build', '--output-dir=%s' % build_dir] + args = ['./node_modules/.bin/grunt', 'build', '--output-dir=%s' % build_dir] if options['editor_optimize']: args.append('--optimize=%s' % options['editor_optimize']) - call(args, cwd = rng_base_dir) + self.stdout.write('Calling %s at %s' % (' '.join(args), rng_base_dir)) + call(args, cwd=rng_base_dir) - call_command('collectstatic', interactive = False, ignore_patterns = ['editor']) + call_command('collectstatic', interactive=False, ignore_patterns=['editor']) diff --git a/apps/catalogue/admin.py b/apps/catalogue/admin.py index 93298174..454035bc 100644 --- a/apps/catalogue/admin.py +++ b/apps/catalogue/admin.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django.contrib import admin from catalogue import models diff --git a/apps/catalogue/ebook_utils.py b/apps/catalogue/ebook_utils.py index 56b73402..b27f0728 100644 --- a/apps/catalogue/ebook_utils.py +++ b/apps/catalogue/ebook_utils.py @@ -1,22 +1,7 @@ # -*- coding: utf-8 -*- -from StringIO import StringIO -#from catalogue.models import Book -#from librarian import DocProvider from django.http import HttpResponse -#~ class RedakcjaDocProvider(DocProvider): - #~ """Used for getting books' children.""" -#~ - #~ def __init__(self, publishable): - #~ self.publishable = publishable -#~ - #~ def by_slug(self, slug): - #~ return StringIO(Book.objects.get(dc_slug=slug - #~ ).materialize(publishable=self.publishable - #~ ).encode('utf-8')) - - def serve_file(file_path, name, mime_type): def read_chunks(f, size=8192): chunk = f.read(size) diff --git a/apps/catalogue/helpers.py b/apps/catalogue/helpers.py index 7e4ce526..e88c7e24 100644 --- a/apps/catalogue/helpers.py +++ b/apps/catalogue/helpers.py @@ -1,14 +1,17 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from datetime import date from functools import wraps from os.path import join -from os import listdir, stat +from os import listdir from shutil import move, rmtree from django.conf import settings import re import filecmp -from django.db.models import Count - def active_tab(tab): """ @@ -70,7 +73,7 @@ class GalleryMerger(object): @property def was_merged(self): - "Check if we have gallery size recorded" + """Check if we have gallery size recorded""" return self.dest_size is not None def merge(self): @@ -105,7 +108,8 @@ class GalleryMerger(object): for f in files: p = self.get_prefix(f) if p: - if p > last_pfx: last_pfx = p + if p > last_pfx: + last_pfx = p else: files_prefixed = False break @@ -121,7 +125,7 @@ class GalleryMerger(object): for f in files_other: pfx = self.get_prefix(f) if pfx is not None: - if not pfx in prefixes: + if pfx not in prefixes: last_pfx += 1 prefixes[pfx] = last_pfx renamed_files_other[f] = self.set_prefix(f, prefixes[pfx]) @@ -138,10 +142,10 @@ class GalleryMerger(object): # finally, move / rename files. for frm, to in renamed_files.items(): move(join(self.path(self.dest), frm), - join(self.path(self.dest), to)) + join(self.path(self.dest), to)) for frm, to in renamed_files_other.items(): move(join(self.path(self.src), frm), - join(self.path(self.dest), to)) + join(self.path(self.dest), to)) rmtree(join(self.path(self.src))) return self.dest @@ -149,7 +153,6 @@ class GalleryMerger(object): # Maybe subclass? def sstdocument(text): - #from catalogue.ebook_utils import RedakcjaDocProvider from librarian.document import Document return Document.from_string( diff --git a/apps/catalogue/locale/pl/LC_MESSAGES/django.mo b/apps/catalogue/locale/pl/LC_MESSAGES/django.mo index 4149f3072778f309a3c41a1a8effaadce5b3695a..c3fccf26c03f6cbb4714379cf6740db7ad0f2625 100644 GIT binary patch delta 347 zcmXZYKMO%o7{~EP`I}2*5DJBhl7*rqDP^JVB3^>U3ouF9SWQYsrKHTVm{?^p@CKAu z!1r*c&v|}5=Q)2K#?#mp?W3BA1QQ}T?4lhf7{e(BaD#3<q7yHu;nnnsE$SDpu#yz1 z;~fVWO^GaUhCR&aWH{DkBv}?Kf+3z!9neUNgt3hg?BnlZ=%SvY>YJPO5^dCL^x_s( z{{j7YLbdOPK761D-|6Q6B_DziftC?*ppI6|n-)yVs0LS24QinJna+Ob*hMVyeKt|D FeF2=CD0ct= delta 345 zcmXZYzixq17{~G7P_#j#F*FDUUatyE(?lX7X$)Nq1`&5)asj4SVq@*rh;9;zL}C?- ziB(JnT!6$CNWVwl>2rQhp7WeP=lZEW|L{5$Nv|m>k4^MqACox1Fiz2rD}2N)25{$k z!W#L4zgS93pLoCy#x3awhuA_pBPFnxk)t;jV+vi|pgEvwOHr(04BL3W7(S5)X!^e0 zJVFn7g3mZZ)4#+QT%*~y#}FPdh*$gT|0OpH5eojS<U<P|u;BXcT0}FrjAl?3&CfIz MUEe&m$fb&&KQav{E&u=k diff --git a/apps/catalogue/locale/pl/LC_MESSAGES/django.po b/apps/catalogue/locale/pl/LC_MESSAGES/django.po index d1a798c4..4a7d185a 100644 --- a/apps/catalogue/locale/pl/LC_MESSAGES/django.po +++ b/apps/catalogue/locale/pl/LC_MESSAGES/django.po @@ -261,7 +261,7 @@ msgstr "" #: templates/catalogue/book_text.html:80 #, python-format msgid "This resource has a <a href=\"%(url)s\">published version</a>." -msgstr "Ten zasób posiada<a href=\"%(url)s\">opublikowanÄ wersjÄ</a>." +msgstr "Ten zasób posiada <a href=\"%(url)s\">opublikowanÄ wersjÄ</a>." #: templates/catalogue/book_text.html:83 msgid "This resource hasn't been published yet." diff --git a/apps/catalogue/management/__init__.py b/apps/catalogue/management/__init__.py deleted file mode 100644 index f7731d72..00000000 --- a/apps/catalogue/management/__init__.py +++ /dev/null @@ -1,122 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -from collections import defaultdict -from django.db import transaction -from lxml import etree - - -class XmlUpdater(object): - """A base class for massive XML updates. - - In a subclass, override `fix_tree` and/or use `fixes_field` decorator. - Attributes: - * commit_desc: commits description - * retain_publishable: set publishable if head is (default: True) - * only_first_chunk: process only first chunks of books (default: False) - """ - commit_desc = "auto-update" - retain_publishable = True - only_first_chunk = False - - _element_fixers = defaultdict(list) - - def __init__(self): - self.counters = defaultdict(lambda: 0) - - @classmethod - def fixes_elements(cls, xpath): - """Decorator, registering a function as a fixer for given field type. - - Any decorated function will be called like - f(element, change=..., verbose=...) - providing changeset as context. - - :param xpath: element lookup, e.g. ".//{namespace-uri}tag-name" - :returns: True if anything changed - """ - def wrapper(fixer): - cls._element_fixers[xpath].append(fixer) - return fixer - return wrapper - - def fix_tree(self, tree, verbose): - """Override to provide general tree-fixing mechanism. - - :param tree: the parsed XML tree - :param verbose: verbosity level - :returns: True if anythig changed - """ - return False - - def fix_chunk(self, chunk, user, verbose=0, dry_run=False): - """Runs the update for a single chunk.""" - if verbose >= 2: - print chunk.get_absolute_url() - old_head = chunk.head - src = old_head.materialize() - try: - tree = etree.fromstring(src) - except: - if verbose: - print "%s: invalid XML" % chunk.get_absolute_url() - self.counters['Bad XML'] += 1 - return - - dirty = False - # Call the general fixing function. - if self.fix_tree(tree, verbose=verbose): - dirty = True - # Call the registered fixers. - for xpath, fixers in self._element_fixers.items(): - for elem in tree.findall(xpath): - for fixer in fixers: - if fixer(elem, change=old_head, verbose=verbose): - dirty = True - - if not dirty: - self.counters['Clean'] += 1 - return - - if not dry_run: - new_head = chunk.commit( - etree.tostring(tree, encoding=unicode), - author=user, - description=self.commit_desc - ) - if self.retain_publishable: - if old_head.publishable: - new_head.set_publishable(True) - if verbose >= 2: - print "done" - self.counters['Updated chunks'] += 1 - - def run(self, user, verbose=0, dry_run=False, books=None): - """Runs the actual update.""" - if books is None: - from catalogue.models import Book - books = Book.objects.all() - - # Start transaction management. - transaction.commit_unless_managed() - transaction.enter_transaction_management() - transaction.managed(True) - - for book in books: - self.counters['All books'] += 1 - chunks = book.chunk_set.all() - if self.only_first_chunk: - chunks = chunks[:1] - for chunk in chunks: - self.counters['All chunks'] += 1 - self.fix_chunk(chunk, user, verbose, dry_run) - - transaction.commit() - transaction.leave_transaction_management() - - def print_results(self): - """Prints the counters.""" - for item in sorted(self.counters.items()): - print "%s: %d" % item diff --git a/apps/catalogue/management/commands/__init__.py b/apps/catalogue/management/commands/__init__.py deleted file mode 100644 index e6f146f8..00000000 --- a/apps/catalogue/management/commands/__init__.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -import sys -from optparse import make_option -from django.contrib.auth.models import User -from django.core.management.base import BaseCommand -from catalogue.models import Book - - -class XmlUpdaterCommand(BaseCommand): - """Base class for creating massive XML-updating commands. - - In a subclass, provide an XmlUpdater class in the `updater' attribute. - """ - option_list = BaseCommand.option_list + ( - make_option('-q', '--quiet', action='store_false', dest='verbose', - default=True, help='Less output'), - make_option('-d', '--dry-run', action='store_true', dest='dry_run', - default=False, help="Don't actually touch anything"), - make_option('-u', '--username', dest='username', metavar='USER', - help='Assign commits to this user (required, preferably yourself).'), - ) - args = "[slug]..." - - def handle(self, *args, **options): - verbose = options.get('verbose') - dry_run = options.get('dry_run') - username = options.get('username') - - if username: - user = User.objects.get(username=username) - else: - print 'Please provide a username.' - sys.exit(1) - - books = Book.objects.filter(slug__in=args) if args else None - - updater = self.updater() - updater.run(user, verbose=verbose, dry_run=dry_run, books=books) - updater.print_results() diff --git a/apps/catalogue/management/commands/fixdc.py b/apps/catalogue/management/commands/fixdc.py deleted file mode 100644 index 3f997d0c..00000000 --- a/apps/catalogue/management/commands/fixdc.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -from librarian import RDFNS, WLURI, ValidationError -from librarian.dcparser import BookInfo -from catalogue.management import XmlUpdater -from catalogue.management.commands import XmlUpdaterCommand - - -class FixDC(XmlUpdater): - commit_desc = "auto-fixing DC" - retain_publishable = True - only_first_chunk = True - - def fix_wluri(elem, change, verbose): - try: - WLURI.strict(elem.text) - except ValidationError: - correct_field = unicode(WLURI.from_slug( - WLURI(elem.text.strip()).slug)) - try: - WLURI.strict(correct_field) - except ValidationError: - # Can't make a valid WLURI out of it, leave as is. - return False - if verbose: - print "Changing %s from %s to %s" % ( - elem.tag, elem.text, correct_field - ) - elem.text = correct_field - return True - for field in BookInfo.FIELDS: - if field.validator == WLURI: - XmlUpdater.fixes_elements('.//' + field.uri)(fix_wluri) - - @XmlUpdater.fixes_elements(".//" + RDFNS("Description")) - def fix_rdfabout(elem, change, verbose): - correct_about = change.tree.book.correct_about() - attr_name = RDFNS("about") - current_about = elem.get(attr_name) - if current_about != correct_about: - if verbose: - print "Changing rdf:about from %s to %s" % ( - current_about, correct_about - ) - elem.set(attr_name, correct_about) - return True - - -class Command(XmlUpdaterCommand): - updater = FixDC - help = 'Fixes obvious errors in DC: rdf:about and WLURI format.' diff --git a/apps/catalogue/management/commands/import_wl.py b/apps/catalogue/management/commands/import_wl.py deleted file mode 100644 index 5f603883..00000000 --- a/apps/catalogue/management/commands/import_wl.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- coding: utf-8 -*- - -from collections import defaultdict -import json -from optparse import make_option -import urllib2 - -from django.core.management.base import BaseCommand -from django.core.management.color import color_style -from django.db import transaction -from librarian.dcparser import BookInfo -from librarian import ParseError, ValidationError - -from catalogue.models import Book - - -WL_API = 'http://www.wolnelektury.pl/api/books/' - - -class Command(BaseCommand): - option_list = BaseCommand.option_list + ( - make_option('-q', '--quiet', action='store_false', dest='verbose', default=True, - help='Less output'), - ) - help = 'Imports XML files from WL.' - - def handle(self, *args, **options): - - self.style = color_style() - - verbose = options.get('verbose') - - # Start transaction management. - transaction.commit_unless_managed() - transaction.enter_transaction_management() - transaction.managed(True) - - if verbose: - print 'Reading currently managed files (skipping hidden ones).' - slugs = defaultdict(list) - for b in Book.objects.exclude(slug__startswith='.').all(): - if verbose: - print b.slug - text = b.materialize().encode('utf-8') - try: - info = BookInfo.from_string(text) - except (ParseError, ValidationError): - pass - else: - slugs[info.slug].append(b) - - book_count = 0 - commit_args = { - "author_name": 'Platforma', - "description": 'Automatycznie zaimportowane z Wolnych Lektur', - "publishable": True, - } - - if verbose: - print 'Opening books list' - for book in json.load(urllib2.urlopen(WL_API)): - book_detail = json.load(urllib2.urlopen(book['href'])) - xml_text = urllib2.urlopen(book_detail['xml']).read() - info = BookInfo.from_string(xml_text) - previous_books = slugs.get(info.slug) - if previous_books: - if len(previous_books) > 1: - print self.style.ERROR("There is more than one book " - "with slug %s:"), - previous_book = previous_books[0] - comm = previous_book.slug - else: - previous_book = None - comm = '*' - print book_count, info.slug , '-->', comm - Book.import_xml_text(xml_text, title=info.title[:255], - slug=info.slug[:128], previous_book=previous_book, - commit_args=commit_args) - book_count += 1 - - # Print results - print - print "Results:" - print "Imported %d books from WL:" % ( - book_count, ) - print - - - transaction.commit() - transaction.leave_transaction_management() - diff --git a/apps/catalogue/models/__init__.py b/apps/catalogue/models/__init__.py index a940dd00..5e8adb3e 100755 --- a/apps/catalogue/models/__init__.py +++ b/apps/catalogue/models/__init__.py @@ -8,8 +8,6 @@ from catalogue.models.document import Document from catalogue.models.plan import Plan from catalogue.models.publish_log import PublishRecord from catalogue.models.tag import Category, Tag -# from catalogue.models.book import Book -# from catalogue.models.listeners import * from django.contrib.auth.models import User as AuthUser diff --git a/apps/catalogue/models/book.py b/apps/catalogue/models/book.py deleted file mode 100755 index 34ac796c..00000000 --- a/apps/catalogue/models/book.py +++ /dev/null @@ -1,436 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -from django.contrib.auth.models import User -from django.contrib.sites.models import Site -from django.db import models, transaction -from django.template.loader import render_to_string -from django.utils.translation import ugettext_lazy as _ -from django.conf import settings -from slughifi import slughifi - -import apiclient -from catalogue.helpers import cached_in_field, GalleryMerger -from catalogue.models import BookPublishRecord, ChunkPublishRecord, Project -from catalogue.signals import post_publish -from catalogue.tasks import refresh_instance, book_content_updated -from catalogue.xml_tools import compile_text, split_xml -from cover.models import Image -from organizations.models import Organization -import os -import shutil -import re - - -class Book(models.Model): - """ A document edited on the wiki """ - - title = models.CharField(_('title'), max_length=255, db_index=True) - slug = models.SlugField(_('slug'), max_length=128, unique=True, db_index=True) - public = models.BooleanField(_('public'), default=True, db_index=True) - gallery = models.CharField(u'materiaÅy', max_length=255, blank=True) - project = models.ForeignKey(Project, null=True, blank=True) - - owner_user = models.ForeignKey(User, null=True) - owner_organization = models.ForeignKey(Organization, null=True) - - #wl_slug = models.CharField(_('title'), max_length=255, null=True, db_index=True, editable=False) - parent = models.ForeignKey('self', null=True, blank=True, verbose_name=_('parent'), related_name="children", editable=False) - parent_number = models.IntegerField(_('parent number'), null=True, blank=True, db_index=True, editable=False) - - # Cache - _short_html = models.TextField(null=True, blank=True, editable=False) - _single = models.NullBooleanField(editable=False, db_index=True) - _new_publishable = models.NullBooleanField(editable=False) - _published = models.NullBooleanField(editable=False) - _on_track = models.IntegerField(null=True, blank=True, db_index=True, editable=False) - dc_cover_image = models.ForeignKey(Image, blank=True, null=True, - db_index=True, on_delete=models.SET_NULL, editable=False) - dc_slug = models.CharField(max_length=128, null=True, blank=True, - editable=False, db_index=True) - - class NoTextError(BaseException): - pass - - class Meta: - app_label = 'catalogue' - ordering = ['title', 'slug'] - verbose_name = u'moduÅ' - verbose_name_plural = u'moduÅy' - - - # Representing - # ============ - - def __iter__(self): - return iter(self.chunk_set.all()) - - def __getitem__(self, chunk): - return self.chunk_set.all()[chunk] - - def __len__(self): - return self.chunk_set.count() - - def __nonzero__(self): - """ - Necessary so that __len__ isn't used for bool evaluation. - """ - return True - - def __unicode__(self): - return self.title - - @models.permalink - def get_absolute_url(self): - return ("catalogue_book", [self.slug]) - - def correct_about(self): - return "http://%s%s" % ( - Site.objects.get_current().domain, - self.get_absolute_url() - ) - - # Creating & manipulating - # ======================= - - def accessible(self, request): - return self.public or request.user.is_authenticated() - - @classmethod - @transaction.commit_on_success - def create(cls, creator, text, *args, **kwargs): - b = cls.objects.create(*args, **kwargs) - b.chunk_set.all().update(creator=creator) - b[0].commit(text, author=creator) - return b - - def add(self, *args, **kwargs): - """Add a new chunk at the end.""" - return self.chunk_set.reverse()[0].split(*args, **kwargs) - - @classmethod - @transaction.commit_on_success - def import_xml_text(cls, text=u'', previous_book=None, - commit_args=None, **kwargs): - """Imports a book from XML, splitting it into chunks as necessary.""" - texts = split_xml(text) - if previous_book: - instance = previous_book - else: - instance = cls(**kwargs) - instance.save() - - # if there are more parts, set the rest to empty strings - book_len = len(instance) - for i in range(book_len - len(texts)): - texts.append((u'pusta czÄÅÄ %d' % (i + 1), u'')) - - i = 0 - for i, (title, text) in enumerate(texts): - if not title: - title = u'czÄÅÄ %d' % (i + 1) - - slug = slughifi(title) - - if i < book_len: - chunk = instance[i] - chunk.slug = slug[:50] - chunk.title = title[:255] - chunk.save() - else: - chunk = instance.add(slug, title) - - chunk.commit(text, **commit_args) - - return instance - - def make_chunk_slug(self, proposed): - """ - Finds a chunk slug not yet used in the book. - """ - slugs = set(c.slug for c in self) - i = 1 - new_slug = proposed[:50] - while new_slug in slugs: - new_slug = "%s_%d" % (proposed[:45], i) - i += 1 - return new_slug - - @transaction.commit_on_success - def append(self, other, slugs=None, titles=None): - """Add all chunks of another book to self.""" - assert self != other - - number = self[len(self) - 1].number + 1 - len_other = len(other) - single = len_other == 1 - - if slugs is not None: - assert len(slugs) == len_other - if titles is not None: - assert len(titles) == len_other - if slugs is None: - slugs = [slughifi(t) for t in titles] - - for i, chunk in enumerate(other): - # move chunk to new book - chunk.book = self - chunk.number = number - - if titles is None: - # try some title guessing - if other.title.startswith(self.title): - other_title_part = other.title[len(self.title):].lstrip(' /') - else: - other_title_part = other.title - - if single: - # special treatment for appending one-parters: - # just use the guessed title and original book slug - chunk.title = other_title_part - if other.slug.startswith(self.slug): - chunk.slug = other.slug[len(self.slug):].lstrip('-_') - else: - chunk.slug = other.slug - else: - chunk.title = ("%s, %s" % (other_title_part, chunk.title))[:255] - else: - chunk.slug = slugs[i] - chunk.title = titles[i] - - chunk.slug = self.make_chunk_slug(chunk.slug) - chunk.save() - number += 1 - assert not other.chunk_set.exists() - - gm = GalleryMerger(self.gallery, other.gallery) - self.gallery = gm.merge() - - # and move the gallery starts - if gm.was_merged: - for chunk in self[len(self) - len_other:]: - old_start = chunk.gallery_start or 1 - chunk.gallery_start = old_start + gm.dest_size - gm.num_deleted - chunk.save() - - other.delete() - - - @transaction.commit_on_success - def prepend_history(self, other): - """Prepend history from all the other book's chunks to own.""" - assert self != other - - for i in range(len(self), len(other)): - title = u"pusta czÄÅÄ %d" % i - chunk = self.add(slughifi(title), title) - chunk.commit('') - - for i in range(len(other)): - self[i].prepend_history(other[0]) - - assert not other.chunk_set.exists() - other.delete() - - def split(self): - """Splits all the chunks into separate books.""" - self.title - for chunk in self: - book = Book.objects.create(title=chunk.title, slug=chunk.slug, - public=self.public, gallery=self.gallery) - book[0].delete() - chunk.book = book - chunk.number = 1 - chunk.save() - assert not self.chunk_set.exists() - self.delete() - - # State & cache - # ============= - - def last_published(self): - try: - return self.publish_log.all()[0].timestamp - except IndexError: - return None - - def assert_publishable(self): - assert self.chunk_set.exists(), _('No chunks in the book.') - try: - changes = self.get_current_changes(publishable=True) - except self.NoTextError: - raise AssertionError(_('Not all chunks have publishable revisions.')) - - from librarian import NoDublinCore, ParseError, ValidationError - - try: - bi = self.wldocument(changes=changes, strict=True).book_info - except ParseError, e: - raise AssertionError(_('Invalid XML') + ': ' + unicode(e)) - except NoDublinCore: - raise AssertionError(_('No Dublin Core found.')) - except ValidationError, e: - raise AssertionError(_('Invalid Dublin Core') + ': ' + unicode(e)) - - valid_about = self.correct_about() - assert bi.about == valid_about, _("rdf:about is not") + " " + valid_about - - def publishable_error(self): - try: - return self.assert_publishable() - except AssertionError, e: - return e - else: - return None - - def hidden(self): - return self.slug.startswith('.') - - def is_new_publishable(self): - """Checks if book is ready for publishing. - - Returns True if there is a publishable version newer than the one - already published. - - """ - new_publishable = False - if not self.chunk_set.exists(): - return False - for chunk in self: - change = chunk.publishable() - if not change: - return False - if not new_publishable and not change.publish_log.exists(): - new_publishable = True - return new_publishable - new_publishable = cached_in_field('_new_publishable')(is_new_publishable) - - def is_published(self): - return self.publish_log.exists() - published = cached_in_field('_published')(is_published) - - def get_on_track(self): - if self.published: - return -1 - stages = [ch.stage.ordering if ch.stage is not None else 0 - for ch in self] - if not len(stages): - return 0 - return min(stages) - on_track = cached_in_field('_on_track')(get_on_track) - - def is_single(self): - return len(self) == 1 - single = cached_in_field('_single')(is_single) - - #@cached_in_field('_short_html') - def short_html(self): - return render_to_string('catalogue/book_list/book.html', {'book': self}) - - def book_info(self, publishable=True): - try: - book_xml = self.materialize(publishable=publishable) - except self.NoTextError: - pass - else: - from librarian.dcparser import BookInfo - from librarian import NoDublinCore, ParseError, ValidationError - try: - return BookInfo.from_string(book_xml.encode('utf-8')) - except (self.NoTextError, ParseError, NoDublinCore, ValidationError): - return None - - def refresh_dc_cache(self): - update = { - 'dc_slug': None, - 'dc_cover_image': None, - } - - info = self.book_info() - if info is not None: - update['dc_slug'] = info.url.slug - if info.cover_source: - try: - image = Image.objects.get(pk=int(info.cover_source.rstrip('/').rsplit('/', 1)[-1])) - except: - pass - else: - if info.cover_source == image.get_full_url(): - update['dc_cover_image'] = image - Book.objects.filter(pk=self.pk).update(**update) - - def touch(self): - # this should only really be done when text or publishable status changes - book_content_updated.delay(self) - - update = { - "_new_publishable": self.is_new_publishable(), - "_published": self.is_published(), - "_single": self.is_single(), - "_on_track": self.get_on_track(), - "_short_html": None, - } - Book.objects.filter(pk=self.pk).update(**update) - refresh_instance(self) - - def refresh(self): - """This should be done offline.""" - self.short_html - self.single - self.new_publishable - self.published - - # Materializing & publishing - # ========================== - - def get_current_changes(self, publishable=True): - """ - Returns a list containing one Change for every Chunk in the Book. - Takes the most recent revision (publishable, if set). - Throws an error, if a proper revision is unavailable for a Chunk. - """ - if publishable: - changes = [chunk.publishable() for chunk in self] - else: - changes = [chunk.head for chunk in self if chunk.head is not None] - if None in changes: - raise self.NoTextError('Some chunks have no available text.') - return changes - - def materialize(self, publishable=False, changes=None): - """ - Get full text of the document compiled from chunks. - Takes the current versions of all texts - or versions most recently tagged for publishing, - or a specified iterable changes. - """ - if changes is None: - changes = self.get_current_changes(publishable) - return compile_text(change.materialize() for change in changes) - - def wldocument(self, publishable=True, changes=None, - parse_dublincore=True, strict=False): - from catalogue.ebook_utils import RedakcjaDocProvider - from librarian.parser import WLDocument - - return WLDocument.from_string( - self.materialize(publishable=publishable, changes=changes), - provider=RedakcjaDocProvider(publishable=publishable), - parse_dublincore=parse_dublincore, - strict=strict) - - def publish(self, user): - """ - Publishes a book on behalf of a (local) user. - """ - self.assert_publishable() - changes = self.get_current_changes(publishable=True) - book_xml = self.materialize(changes=changes) - apiclient.api_call(user, "books/", {"book_xml": book_xml}) - # record the publish - br = BookPublishRecord.objects.create(book=self, user=user) - for c in changes: - ChunkPublishRecord.objects.create(book_record=br, change=c) - post_publish.send(sender=br) diff --git a/apps/catalogue/models/document.py b/apps/catalogue/models/document.py index 70f50f25..d58a4d1f 100755 --- a/apps/catalogue/models/document.py +++ b/apps/catalogue/models/document.py @@ -7,6 +7,7 @@ from __future__ import unicode_literals from datetime import date from django.conf import settings +from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from django.db import models from django.template.loader import render_to_string from django.utils.translation import ugettext_lazy as _ @@ -53,7 +54,7 @@ class Document(Ref): if header is None: header = etree.fromstring(data).find('.//{http://nowoczesnapolska.org.pl/sst#}header') metadata['title'] = getattr(header, 'text', ' ') or ' ' - #print 'meta', d['title'] + # print 'meta', d['title'] m = t.find('metadata') if m is None: @@ -86,7 +87,7 @@ class Document(Ref): def get_plan(self): try: plan = self.plan_set.get(stage=self.stage) - except: + except (ObjectDoesNotExist, MultipleObjectsReturned): return None return plan diff --git a/apps/catalogue/models/listeners.py b/apps/catalogue/models/listeners.py deleted file mode 100755 index 91d39ffb..00000000 --- a/apps/catalogue/models/listeners.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -from django.contrib.auth.models import User -from django.db import models -from catalogue.models import Book, Chunk -from catalogue.signals import post_publish - - -def book_changed(sender, instance, created, **kwargs): - instance.touch() - for c in instance: - c.touch() -models.signals.post_save.connect(book_changed, sender=Book) - - -def chunk_changed(sender, instance, created, **kwargs): - instance.book.touch() - instance.touch() -models.signals.post_save.connect(chunk_changed, sender=Chunk) - - -def user_changed(sender, instance, *args, **kwargs): - books = set() - for c in instance.chunk_set.all(): - books.add(c.book) - c.touch() - for b in books: - b.touch() -models.signals.post_save.connect(user_changed, sender=User) - - -def publish_listener(sender, *args, **kwargs): - sender.book.touch() - for c in sender.book: - c.touch() -post_publish.connect(publish_listener) - - -def listener_create(sender, instance, created, **kwargs): - if created: - instance.chunk_set.create(number=1, slug='1') -models.signals.post_save.connect(listener_create, sender=Book) - diff --git a/apps/catalogue/models/plan.py b/apps/catalogue/models/plan.py index ff5cd168..3f05fdf4 100644 --- a/apps/catalogue/models/plan.py +++ b/apps/catalogue/models/plan.py @@ -7,6 +7,7 @@ from django.conf import settings from django.db import models from catalogue.models import Document + class Plan(models.Model): document = models.ForeignKey(Document) stage = models.CharField(max_length=128) diff --git a/apps/catalogue/models/publish_log.py b/apps/catalogue/models/publish_log.py index cbbcf9ae..2dfff9ec 100755 --- a/apps/catalogue/models/publish_log.py +++ b/apps/catalogue/models/publish_log.py @@ -12,7 +12,7 @@ from dvcs.models import Revision class PublishRecord(models.Model): """A record left after publishing a Document.""" - document = models.ForeignKey('Document', verbose_name=_('document'), related_name='publish_log') + document = models.ForeignKey('catalogue.Document', verbose_name=_('document'), related_name='publish_log') revision = models.ForeignKey(Revision, verbose_name=_('revision'), related_name='publish_log') timestamp = models.DateTimeField(_('time'), auto_now_add=True) user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('user')) @@ -20,4 +20,4 @@ class PublishRecord(models.Model): class Meta: ordering = ['-timestamp'] verbose_name = _('book publish record') - verbose_name = _('book publish records') + verbose_name_plural = _('book publish records') diff --git a/apps/catalogue/models/template.py b/apps/catalogue/models/template.py index dded859e..fcb2f4bb 100644 --- a/apps/catalogue/models/template.py +++ b/apps/catalogue/models/template.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django.db import models diff --git a/apps/catalogue/signals.py b/apps/catalogue/signals.py index 62ca5145..c884df74 100644 --- a/apps/catalogue/signals.py +++ b/apps/catalogue/signals.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django.dispatch import Signal post_publish = Signal() diff --git a/apps/catalogue/tasks.py b/apps/catalogue/tasks.py index c386c22b..9186705a 100644 --- a/apps/catalogue/tasks.py +++ b/apps/catalogue/tasks.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from celery.task import task from django.utils import translation @@ -11,6 +16,7 @@ def _refresh_by_pk(cls, pk, language=None): finally: translation.activate(prev_language) + def refresh_instance(instance): _refresh_by_pk.delay(type(instance), instance.pk, translation.get_language()) diff --git a/apps/catalogue/templates/catalogue/activity.html b/apps/catalogue/templates/catalogue/activity.html deleted file mode 100755 index c88b5388..00000000 --- a/apps/catalogue/templates/catalogue/activity.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends "catalogue/base.html" %} -{% load i18n %} -{% load wall %} - - -{% block content %} - -<h1><a href='{% url "catalogue_activity" prev_day.isoformat %}'><</a> - {% trans "Activity" %}: {{ day }} - {% if next_day %} - <a href='{% url "catalogue_activity" next_day.isoformat %}'>></a> - {% endif %} -</h1> - - {% day_wall day %} -{% endblock content %} diff --git a/apps/catalogue/templates/catalogue/book_append_to.html b/apps/catalogue/templates/catalogue/book_append_to.html deleted file mode 100755 index 76a59621..00000000 --- a/apps/catalogue/templates/catalogue/book_append_to.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "catalogue/base.html" %} -{% load i18n %} - -{% block leftcolumn %} - <form enctype="multipart/form-data" method="POST" action=""> - {% csrf_token %} - {{ form.as_p }} - - <p><button type="submit">{% trans "Append book" %}</button></p> - </form> -{% endblock leftcolumn %} - -{% block rightcolumn %} -{% endblock rightcolumn %} diff --git a/apps/catalogue/templates/catalogue/book_detail.html b/apps/catalogue/templates/catalogue/book_detail.html index 1bdbad92..20a7d6da 100755 --- a/apps/catalogue/templates/catalogue/book_detail.html +++ b/apps/catalogue/templates/catalogue/book_detail.html @@ -15,94 +15,4 @@ {% endif %} -{% comment %} - - -{% if editable %}<form method='POST'>{% csrf_token %}{% endif %} -<table class='editable'><tbody> - {{ form.as_table }} - {% if editable %} - <tr><td></td><td><button type="submit">{% trans "Save" %}</button></td></tr> - {% endif %} -</tbody></table> -{% if editable %}</form>{% endif %} - -{% if editable %} - {% if book.gallery %} - <p><a href="{% url 'catalogue_book_gallery' book.slug %}">{% trans "Edit gallery" %}</a></p> - {% endif %} - - <p><a href="{% url 'catalogue_book_append' book.slug %}">{% trans "Append to other book" %}</a></p> -{% endif %} - - -<div class='section'> - - <h2>{% trans "Edit" %}</h2> - - <table class='single-book-list'><tbody> - {% for chunk in book %} - {{ chunk.short_html|safe }} - {% endfor %} - </tbody></table> - -</div> - - -<div class='section'> - - -<h2>{% trans "Publication" %}</h2> - -<div class="cover-preview"> -<img class="cover-preview" src="{% url 'cover_preview' book.slug %}" /> -{% if book.dc_cover_image %} - <a href="{{ book.dc_cover_image.get_absolute_url }}">{{ book.dc_cover_image }}</a> -{% endif %} -</div> - -<p>{% trans "Last published" %}: - {% if book.last_published %} - {{ book.last_published }} - {% else %} - — - {% endif %} -</p> - -{% if publishable %} - <p> - <a href="{% url 'catalogue_book_xml' book.slug %}" rel="nofollow">{% trans "Full XML" %}</a><br/> - <a target="_blank" href="{% url 'catalogue_book_html' book.slug %}" rel="nofollow">{% trans "HTML version" %}</a><br/> - <a href="{% url 'catalogue_book_txt' book.slug %}" rel="nofollow">{% trans "TXT version" %}</a><br/> - <a href="{% url 'catalogue_book_pdf' book.slug %}" rel="nofollow">{% trans "PDF version" %}</a><br/> - <a href="{% url 'catalogue_book_epub' book.slug %}" rel="nofollow">{% trans "EPUB version" %}</a><br/> - </p> - - {% if user.is_authenticated %} - <!-- - Angel photos: - Angels in Ely Cathedral (http://www.flickr.com/photos/21804434@N02/4483220595/) / - mira66 (http://www.flickr.com/photos/21804434@N02/) / - CC BY 2.0 (http://creativecommons.org/licenses/by/2.0/) - --> - <form method="POST" action="{% url 'catalogue_publish' book.slug %}">{% csrf_token %} - <img src="{{ STATIC_URL }}img/angel-left.png" style="vertical-align: middle" /> - <button id="publish-button" type="submit"> - <span>{% trans "Publish" %}</span></button> - <img src="{{ STATIC_URL }}img/angel-right.png" style="vertical-align: middle" /> - </form> - {% else %} - <a href="{% url 'login' %}">{% trans "Log in to publish." %}</a> - {% endif %} -{% else %} - <p>{% trans "This book can't be published yet, because:" %}</p> - <ul><li>{{ publishable_error }}</li></ul> -{% endif %} - -<div style="clear: both;"></div> -</div> - - -{% endcomment %} - {% endblock %} diff --git a/apps/catalogue/templates/catalogue/book_edit.html b/apps/catalogue/templates/catalogue/book_edit.html deleted file mode 100755 index 3fffa963..00000000 --- a/apps/catalogue/templates/catalogue/book_edit.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "catalogue/base.html" %} -{% load i18n %} - -{% block leftcolumn %} - <form enctype="multipart/form-data" method="POST" action=""> - {% csrf_token %} - {{ form.as_p }} - - <p><button type="submit">{% trans "Save" %}</button></p> - </form> -{% endblock leftcolumn %} - -{% block rightcolumn %} -{% endblock rightcolumn %} diff --git a/apps/catalogue/templates/catalogue/book_list/chunk.html b/apps/catalogue/templates/catalogue/book_list/chunk.html deleted file mode 100755 index 7bdf3aa9..00000000 --- a/apps/catalogue/templates/catalogue/book_list/chunk.html +++ /dev/null @@ -1,26 +0,0 @@ -{% load i18n %} - -<tr> - <td><input type="checkbox" name="select_chunk" value="{{chunk.id}}" data-book-id="{{chunk.book.id}}" /></td> - <td class='book-settings-column'></td> - <td><a href="{% url 'catalogue_chunk_edit' chunk.book.slug chunk.slug %}" title='{% trans "Chunk settings" %}'>[c]</a></td> - <td><a target="_blank" href="{{ chunk.get_absolute_url }}"> - <span class='chunkno'>{{ chunk.number }}.</span> - {{ chunk.title }}</a></td> - <td>{% if chunk.stage %} - {{ chunk.stage }} - {% else %} - â - {% endif %}</td> - <td class='user-column'>{% if chunk.user %} - <a href="{% url 'catalogue_user' chunk.user.username %}"> - {{ chunk.user.first_name }} {{ chunk.user.last_name }} - </a>{% else %} - - {% endif %}</td> -</td> -<td> - {% if chunk.new_publishable %}p{% endif %} - {% if chunk.changed %}+{% endif %} -</td> -</tr> diff --git a/apps/catalogue/templates/catalogue/chunk_add.html b/apps/catalogue/templates/catalogue/chunk_add.html deleted file mode 100755 index b287479c..00000000 --- a/apps/catalogue/templates/catalogue/chunk_add.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends "catalogue/base.html" %} -{% load i18n %} - -{% block content %} - <h1>{% trans "Split chunk" %}</h1> - - <form enctype="multipart/form-data" method="POST"> - {% csrf_token %} - <table class='editable'> - <tr><th>{% trans "Insert empty chunk after" %}:</th> - <td><a href="{{ chunk.get_absolute_url }}">{{ chunk.pretty_name }}</a></td></tr> - {{ form.as_table }} - <tr><td></td><td><button type="submit">{% trans "Add chunk" %}</button></td></tr> - </table> - </form> -{% endblock content %} diff --git a/apps/catalogue/templates/catalogue/chunk_edit.html b/apps/catalogue/templates/catalogue/chunk_edit.html deleted file mode 100755 index 3c1f3bf5..00000000 --- a/apps/catalogue/templates/catalogue/chunk_edit.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "catalogue/base.html" %} -{% load i18n %} - -{% block content %} - <h1>{% trans "Chunk settings" %}</h1> - - <form enctype="multipart/form-data" method="POST" action="{% if go_next %}?next={{ go_next }}{% endif %}"> - {% csrf_token %} - <table class='editable'> - <tr><th>{% trans "Book" %}:</th><td>{{ chunk.book }} ({{ chunk.number }}/{{ chunk.book|length }})</td></tr> - {{ form.as_table}} - <tr><td></td><td><button type="submit">{% trans "Save" %}</button></td></tr> - </table> - - </form> - - - <p><a href="{% url "catalogue_chunk_add" chunk.book.slug chunk.slug %}">{% trans "Split chunk" %}</a></p> - -{% endblock content %} diff --git a/apps/catalogue/templates/catalogue/document_upload.html b/apps/catalogue/templates/catalogue/document_upload.html deleted file mode 100644 index 18637749..00000000 --- a/apps/catalogue/templates/catalogue/document_upload.html +++ /dev/null @@ -1,69 +0,0 @@ -{% extends "catalogue/base.html" %} -{% load i18n %} - - -{% block leftcolumn %} - - -<h2>{% trans "Bulk documents upload" %}</h2> - -<p> -{% trans "Please submit a ZIP with UTF-8 encoded XML files. Files not ending with <code>.xml</code> will be ignored." %} -</p> - -<form enctype="multipart/form-data" method="POST" action=""> -{% csrf_token %} -{{ form.as_p }} -<p><button type="submit">{% trans "Upload" %}</button></p> -</form> - -<hr/> - -{% if error_list %} - - <p class='error'>{% trans "There have been some errors. No files have been added to the repository." %} - <h3>{% trans "Offending files" %}</h3> - <ul id='error-list'> - {% for filename, title, error in error_list %} - <li>{{ title }} (<code>{{ filename }}</code>): {{ error }}</li> - {% endfor %} - </ul> - - {% if ok_list %} - <h3>{% trans "Correct files" %}</h3> - <ul> - {% for filename, slug, title in ok_list %} - <li>{{ title }} (<code>{{ filename }}</code>)</li> - {% endfor %} - </ul> - {% endif %} - -{% else %} - - {% if ok_list %} - <p class='success'>{% trans "Files have been successfully uploaded to the repository." %}</p> - <h3>{% trans "Uploaded files" %}</h3> - <ul id='ok-list'> - {% for filename, slug, title in ok_list %} - <li><a href='{% url "wiki_editor" slug %}'>{{ title }}</a> (<code>{{ filename }})</a></li> - {% endfor %} - </ul> - {% endif %} -{% endif %} - -{% if skipped_list %} - <h3>{% trans "Skipped files" %}</h3> - <p>{% trans "Files skipped due to no <code>.xml</code> extension" %}</p> - <ul id='skipped-list'> - {% for filename in skipped_list %} - <li>{{ filename }}</li> - {% endfor %} - </ul> -{% endif %} - - -{% endblock leftcolumn %} - - -{% block rightcolumn %} -{% endblock rightcolumn %} diff --git a/apps/catalogue/templates/catalogue/user_list.html b/apps/catalogue/templates/catalogue/user_list.html deleted file mode 100755 index c4b1dfc4..00000000 --- a/apps/catalogue/templates/catalogue/user_list.html +++ /dev/null @@ -1,18 +0,0 @@ -{% extends "catalogue/base.html" %} - -{% load i18n %} - -{% block leftcolumn %} - -<h1>{% trans "Users" %}</h1> - -<ul> -{% for user in users %} - <li><a href="{% url 'catalogue_user' user.username %}"> - <span class="chunkno">{{ forloop.counter }}.</span> - {{ user.first_name }} {{ user.last_name }}</a> - ({{ user.count }})</li> -{% endfor %} -</ul> - -{% endblock leftcolumn %} diff --git a/apps/catalogue/templates/catalogue/user_page.html b/apps/catalogue/templates/catalogue/user_page.html index 89b4ecef..1bfa97eb 100755 --- a/apps/catalogue/templates/catalogue/user_page.html +++ b/apps/catalogue/templates/catalogue/user_page.html @@ -1,15 +1 @@ {% extends "catalogue/base.html" %} - -{% load i18n %} -{% load catalogue book_list wall %} - - -{% block leftcolumn %} - <h1>{{ viewed_user|nice_name }}</h1> - {% book_list viewed_user %} -{% endblock leftcolumn %} - -{% block rightcolumn %} - <h2>{% trans "Recent activity for" %} {{ viewed_user|nice_name }}</h2> - {% wall viewed_user 10 %} -{% endblock rightcolumn %} diff --git a/apps/catalogue/templates/catalogue/wall.html b/apps/catalogue/templates/catalogue/wall.html deleted file mode 100755 index 25550fe6..00000000 --- a/apps/catalogue/templates/catalogue/wall.html +++ /dev/null @@ -1,35 +0,0 @@ -{% load i18n %} -{% load gravatar %} -{% load email %} - -<ul class='wall'> -{% for item in wall %} - <li class="{{ item.tag }}{% if not item.user %} anonymous{% endif %}"> - <div class='gravatar'> - {% if item.get_email %} - {% gravatar_img_for_email item.get_email 32 %} - <br/> - {% endif %} - </div> - - <div class="time">{{ item.timestamp }}</div> - <h3>{{ item.header }}</h3> - <a target="_blank" href='{{ item.url }}'>{{ item.title }}</a> - <br/><strong>{% trans "user" %}:</strong> - {% if item.user %} - <a href="{% url 'catalogue_user' item.user.username %}"> - {{ item.user.first_name }} {{ item.user.last_name }}</a> - <{{ item.user.email|email_link }}> - {% else %} - {{ item.user_name }} - {% if item.email %} - <{{ item.email|email_link }}> - {% endif %} - ({% trans "not logged in" %}) - {% endif %} - <br/>{{ item.summary|linebreaksbr }} - </li> -{% empty %} - <li>{% trans "No activity recorded." %}</li> -{% endfor %} -</ul> diff --git a/apps/catalogue/templatetags/catalogue.py b/apps/catalogue/templatetags/catalogue.py index eceed763..a98aa62a 100644 --- a/apps/catalogue/templatetags/catalogue.py +++ b/apps/catalogue/templatetags/catalogue.py @@ -1,8 +1,11 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from __future__ import absolute_import -from django.core.urlresolvers import reverse from django import template -from django.utils.translation import ugettext as _ register = template.Library() @@ -23,15 +26,9 @@ def main_tabs(context): active = getattr(context['request'], 'catalogue_active_tab', None) tabs = [] - user = context['user'] - #tabs.append(Tab('my', _('My page'), reverse("catalogue_user"))) - - #tabs.append(Tab('activity', _('Activity'), reverse("catalogue_activity"))) - #tabs.append(Tab('all', _('All'), reverse("catalogue_document_list"))) - #tabs.append(Tab('users', _('Users'), reverse("catalogue_users"))) - - #if user.has_perm('catalogue.add_book'): - # tabs.append(Tab('create', _('Add'), reverse("catalogue_create_missing"))) + # tabs.append(Tab('my', _('My page'), reverse("catalogue_user"))) + # + # tabs.append(Tab('all', _('All'), reverse("catalogue_document_list"))) return {"tabs": tabs, "active_tab": active} @@ -39,4 +36,3 @@ def main_tabs(context): @register.filter def nice_name(user): return user.get_full_name() or user.username - diff --git a/apps/catalogue/templatetags/catalogue_files.py b/apps/catalogue/templatetags/catalogue_files.py index 8b6ea85f..6ee86f5a 100644 --- a/apps/catalogue/templatetags/catalogue_files.py +++ b/apps/catalogue/templatetags/catalogue_files.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django import template from django.conf import settings register = template.Library() @@ -8,4 +13,3 @@ def as_media_for(uri, document): if uri.startswith('file://'): uri = "https://milpeer.eu%suploads/%d/%s" % (settings.MEDIA_URL, document.pk, uri[len('file://'):]) return uri - diff --git a/apps/catalogue/templatetags/common_tags.py b/apps/catalogue/templatetags/common_tags.py index ccaf03bf..bbdf2d85 100755 --- a/apps/catalogue/templatetags/common_tags.py +++ b/apps/catalogue/templatetags/common_tags.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django import template register = template.Library() diff --git a/apps/catalogue/templatetags/document_list.py b/apps/catalogue/templatetags/document_list.py index b43de9e9..f9de2d6e 100755 --- a/apps/catalogue/templatetags/document_list.py +++ b/apps/catalogue/templatetags/document_list.py @@ -1,86 +1,18 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from __future__ import absolute_import -from re import split -from django.db.models import Q, Count +from django.db.models import Q from django import template from django.utils.translation import ugettext_lazy as _ -from django.contrib.auth.models import User from catalogue.models import Document register = template.Library() -class ChunksList(object): - def __init__(self, chunk_qs): - #self.chunk_qs = chunk_qs#.annotate( - #book_length=Count('book__chunk')).select_related( - #'book')#, 'stage__name', - #'user') - self.chunk_qs = chunk_qs.select_related('book__hidden') - - self.book_qs = chunk_qs.values('book_id') - - def __getitem__(self, key): - if isinstance(key, slice): - return self.get_slice(key) - elif isinstance(key, int): - return self.get_slice(slice(key, key+1))[0] - else: - raise TypeError('Unsupported list index. Must be a slice or an int.') - - def __len__(self): - return self.book_qs.count() - - def get_slice(self, slice_): - book_ids = [x['book_id'] for x in self.book_qs[slice_]] - chunk_qs = self.chunk_qs.filter(book__in=book_ids) - - chunks_list = [] - book = None - for chunk in chunk_qs: - if chunk.book != book: - book = chunk.book - chunks_list.append(ChoiceChunks(book, [chunk])) - else: - chunks_list[-1].chunks.append(chunk) - return chunks_list - - -class ChoiceChunks(object): - """ - Associates the given chunks iterable for a book. - """ - - chunks = None - - def __init__(self, book, chunks): - self.book = book - self.chunks = chunks - - -def foreign_filter(qs, value, filter_field, model, model_field='slug', unset='-'): - #print qs, value, filter_field, model, model_field, unset - if value == unset: - return qs.filter(**{filter_field: None}) - if not value: - return qs - try: - obj = model._default_manager.get(**{model_field: value}) - except model.DoesNotExist: - return qs.none() - else: - return qs.filter(**{filter_field: obj}) - - -def search_filter(qs, value, filter_fields): - if not value: - return qs - q = Q(**{"%s__icontains" % filter_fields[0]: value}) - for field in filter_fields[1:]: - q |= Q(**{"%s__icontains" % field: value}) - return qs.filter(q) - - _states = [ ('publishable', _('publishable'), Q(book___new_publishable=True)), ('changed', _('changed'), Q(_changed=True)), @@ -92,65 +24,38 @@ _states_options = [s[:2] for s in _states] _states_dict = dict([(s[0], s[2]) for s in _states]) -def document_list_filter(request, **kwargs): - - def arg_or_GET(field): - return kwargs.get(field, request.GET.get(field)) - - if arg_or_GET('all'): - chunks = Chunk.objects.all() - else: - chunks = Chunk.visible_objects.all() - - chunks = chunks.order_by('book__title', 'book', 'number') - - if not request.user.is_authenticated(): - chunks = chunks.filter(book__public=True) - - state = arg_or_GET('status') - if state in _states_dict: - chunks = chunks.filter(_states_dict[state]) - - chunks = foreign_filter(chunks, arg_or_GET('user'), 'user', User, 'username') - chunks = foreign_filter(chunks, arg_or_GET('stage'), 'stage', Chunk.tag_model, 'slug') - chunks = search_filter(chunks, arg_or_GET('title'), ['book__title', 'title']) - chunks = foreign_filter(chunks, arg_or_GET('project'), 'book__project', Project, 'pk') - return chunks - - @register.inclusion_tag('catalogue/book_list/book_list.html', takes_context=True) def document_list(context, user=None, organization=None): request = context['request'] - #~ if user: - #~ filters = {"user": user} - #~ new_context = {"viewed_user": user} - #~ else: - #~ filters = {} - #~ new_context = { - #~ "users": User.objects.annotate( - #~ count=Count('chunk')).filter(count__gt=0).order_by( - #~ '-count', 'last_name', 'first_name'), - #~ "other_users": User.objects.annotate( - #~ count=Count('chunk')).filter(count=0).order_by( - #~ 'last_name', 'first_name'), - #~ } + # if user: + # filters = {"user": user} + # new_context = {"viewed_user": user} + # else: + # filters = {} + # new_context = { + # "users": User.objects.annotate( + # count=Count('chunk')).filter(count__gt=0).order_by( + # '-count', 'last_name', 'first_name'), + # "other_users": User.objects.annotate( + # count=Count('chunk')).filter(count=0).order_by( + # 'last_name', 'first_name'), + # } docs = Document.objects.filter(deleted=False) if user is not None: - docs = docs.filter(Q(owner_user=user) | Q(owner_organization__membership__user=user) | Q(assigned_to=user)).distinct() + docs = docs.filter( + Q(owner_user=user) | Q(owner_organization__membership__user=user) | Q(assigned_to=user)).distinct() if organization is not None: docs = docs.filter(owner_organization=organization) new_context = {} new_context.update({ - #"filters": True, + # "filters": True, "request": request, "books": docs, - #"books": ChunksList(document_list_filter(request, **filters)), - #"stages": Chunk.tag_model.objects.all(), - #"states": _states_options, - #"projects": Project.objects.all(), + # "stages": Chunk.tag_model.objects.all(), + # "states": _states_options, }) return new_context diff --git a/apps/catalogue/templatetags/flat_lang.py b/apps/catalogue/templatetags/flat_lang.py index 35577787..91590706 100755 --- a/apps/catalogue/templatetags/flat_lang.py +++ b/apps/catalogue/templatetags/flat_lang.py @@ -1,3 +1,9 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# +from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from django.utils import translation from django import template @@ -9,6 +15,5 @@ register = template.Library() def flat_lang(page): try: return type(page).objects.get(url="%s%s/" % (page.url, translation.get_language())) - except: + except (ObjectDoesNotExist, MultipleObjectsReturned): return page - diff --git a/apps/catalogue/templatetags/set_get_parameter.py b/apps/catalogue/templatetags/set_get_parameter.py index b3d44d73..87b3e7f8 100755 --- a/apps/catalogue/templatetags/set_get_parameter.py +++ b/apps/catalogue/templatetags/set_get_parameter.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from re import split from django import template @@ -31,7 +36,7 @@ class SetGetParameter(template.Node): del(params[key]) else: params[key] = template.Variable(value).resolve(context) - return '?%s' % params.urlencode() + return '?%s' % params.urlencode() @register.tag diff --git a/apps/catalogue/templatetags/wall.py b/apps/catalogue/templatetags/wall.py deleted file mode 100755 index 28671fb7..00000000 --- a/apps/catalogue/templatetags/wall.py +++ /dev/null @@ -1,155 +0,0 @@ -from __future__ import absolute_import - -from datetime import timedelta -from django.db.models import Q -from django.core.urlresolvers import reverse -from django.contrib.comments.models import Comment -from django import template -from django.utils.translation import ugettext as _ - -from catalogue.models import Chunk, BookPublishRecord - -register = template.Library() - - -class WallItem(object): - title = '' - summary = '' - url = '' - timestamp = '' - user = None - user_name = '' - email = '' - - def __init__(self, tag): - self.tag = tag - - def get_email(self): - if self.user: - return self.user.email - else: - return self.email - - -def changes_wall(user=None, max_len=None, day=None): - qs = Chunk.change_model.objects.order_by('-created_at') - qs = qs.select_related('author', 'tree', 'tree__book__title') - if user is not None: - qs = qs.filter(Q(author=user) | Q(tree__user=user)) - if max_len is not None: - qs = qs[:max_len] - if day is not None: - next_day = day + timedelta(1) - qs = qs.filter(created_at__gte=day, created_at__lt=next_day) - for item in qs: - tag = 'stage' if item.tags.count() else 'change' - chunk = item.tree - w = WallItem(tag) - if user and item.author != user: - w.header = _('Related edit') - else: - w.header = _('Edit') - w.title = chunk.pretty_name() - w.summary = item.description - w.url = reverse('wiki_editor', - args=[chunk.book.slug, chunk.slug]) + '?diff=%d' % item.revision - w.timestamp = item.created_at - w.user = item.author - w.user_name = item.author_name - w.email = item.author_email - yield w - - -# TODO: marked for publishing - - -def published_wall(user=None, max_len=None, day=None): - qs = BookPublishRecord.objects.select_related('book__title') - if user: - # TODO: published my book - qs = qs.filter(Q(user=user)) - if max_len is not None: - qs = qs[:max_len] - if day is not None: - next_day = day + timedelta(1) - qs = qs.filter(timestamp__gte=day, timestamp__lt=next_day) - for item in qs: - w = WallItem('publish') - w.header = _('Publication') - w.title = item.book.title - w.timestamp = item.timestamp - w.url = item.book.get_absolute_url() - w.user = item.user - w.email = item.user.email - yield w - - -def comments_wall(user=None, max_len=None, day=None): - qs = Comment.objects.filter(is_public=True).select_related().order_by('-submit_date') - if user: - # TODO: comments concerning my books - qs = qs.filter(Q(user=user)) - if max_len is not None: - qs = qs[:max_len] - if day is not None: - next_day = day + timedelta(1) - qs = qs.filter(submit_date__gte=day, submit_date__lt=next_day) - for item in qs: - w = WallItem('comment') - w.header = _('Comment') - w.title = item.content_object - w.summary = item.comment - w.url = item.content_object.get_absolute_url() - w.timestamp = item.submit_date - w.user = item.user - ui = item.userinfo - w.email = item.email - w.user_name = item.name - yield w - - -def big_wall(walls, max_len=None): - """ - Takes some WallItem iterators and zips them into one big wall. - Input iterators must already be sorted by timestamp. - """ - subwalls = [] - for w in walls: - try: - subwalls.append([next(w), w]) - except StopIteration: - pass - - if max_len is None: - max_len = -1 - while max_len and subwalls: - i, next_item = max(enumerate(subwalls), key=lambda x: x[1][0].timestamp) - yield next_item[0] - max_len -= 1 - try: - next_item[0] = next(next_item[1]) - except StopIteration: - del subwalls[i] - - -@register.inclusion_tag("catalogue/wall.html", takes_context=True) -def wall(context, user=None, max_len=100): - return { - "request": context['request'], - "STATIC_URL": context['STATIC_URL'], - "wall": big_wall([ - changes_wall(user, max_len), - published_wall(user, max_len), - comments_wall(user, max_len), - ], max_len)} - -@register.inclusion_tag("catalogue/wall.html", takes_context=True) -def day_wall(context, day): - return { - "request": context['request'], - "STATIC_URL": context['STATIC_URL'], - "wall": big_wall([ - changes_wall(day=day), - published_wall(day=day), - comments_wall(day=day), - ])} diff --git a/apps/catalogue/tests/__init__.py b/apps/catalogue/tests/__init__.py index 533a6c53..b685324b 100644 --- a/apps/catalogue/tests/__init__.py +++ b/apps/catalogue/tests/__init__.py @@ -3,7 +3,3 @@ # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # -from catalogue.tests.book import * -from catalogue.tests.gallery import * -from catalogue.tests.publish import * -from catalogue.tests.xml_updater import * diff --git a/apps/catalogue/tests/book.py b/apps/catalogue/tests/book.py deleted file mode 100644 index df6f3b4f..00000000 --- a/apps/catalogue/tests/book.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -"""Tests for manipulating books in the catalogue.""" - -from django.test import TestCase -from django.contrib.auth.models import User -from catalogue.models import Book - - -class ManipulationTests(TestCase): - - def setUp(self): - self.user = User.objects.create(username='tester') - self.book1 = Book.create(self.user, 'book 1', slug='book1') - self.book2 = Book.create(self.user, 'book 2', slug='book2') - - def test_append(self): - self.book1.append(self.book2) - self.assertEqual(Book.objects.all().count(), 1) - self.assertEqual(len(self.book1), 2) - - def test_append_to_self(self): - with self.assertRaises(AssertionError): - self.book1.append(Book.objects.get(pk=self.book1.pk)) - self.assertEqual(Book.objects.all().count(), 2) - self.assertEqual(len(self.book1), 1) - - def test_prepend_history(self): - self.book1.prepend_history(self.book2) - self.assertEqual(Book.objects.all().count(), 1) - self.assertEqual(len(self.book1), 1) - self.assertEqual(self.book1.materialize(), 'book 1') - - def test_prepend_history_to_self(self): - with self.assertRaises(AssertionError): - self.book1.prepend_history(self.book1) - self.assertEqual(Book.objects.all().count(), 2) - self.assertEqual(self.book1.materialize(), 'book 1') - self.assertEqual(self.book2.materialize(), 'book 2') - - def test_split_book(self): - self.book1.chunk_set.create(number=2, title='Second chunk', - slug='book3') - self.book1[1].commit('I survived!') - self.assertEqual(len(self.book1), 2) - self.book1.split() - self.assertEqual(set([b.slug for b in Book.objects.all()]), - set(['book2', '1', 'book3'])) - self.assertEqual( - Book.objects.get(slug='book3').materialize(), - 'I survived!') diff --git a/apps/catalogue/tests/files/chunk1.xml b/apps/catalogue/tests/files/chunk1.xml deleted file mode 100755 index 6a75580a..00000000 --- a/apps/catalogue/tests/files/chunk1.xml +++ /dev/null @@ -1,42 +0,0 @@ -<utwor> - <liryka_l> - -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<rdf:Description rdf:about="http://example.com/documents/book/test-book/"> -<dc:creator xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Mickiewicz, Adam</dc:creator> -<dc:title xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Do M***</dc:title> -<dc:publisher xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Fundacja Nowoczesna Polska</dc:publisher> -<dc:subject.period xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Romantyzm</dc:subject.period> -<dc:subject.type xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Liryka</dc:subject.type> -<dc:subject.genre xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Wiersz</dc:subject.genre> -<!--dc:description xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl). Reprodukcja cyfrowa wykonana przez BibliotekÄ NarodowÄ z egzemplarza pochodzÄ cego ze zbiorów BN.</dc:description--> -<dc:identifier.url xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">http://wolnelektury.pl/katalog/lektura/sonety-odeskie-do-m</dc:identifier.url> -<dc:source.URL xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">http://www.polona.pl/Content/2222</dc:source.URL> -<dc:source xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Mickiewicz, Adam (1798-1855), Poezje, tom 1 (Wiersze mÅodzieÅcze - Ballady i romanse - Wiersze do r. 1824), Krakowska SpóÅdzielnia Wydawnicza, wyd. 2 zwiÄkszone, Kraków, 1922</dc:source> - -<dc:rights xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Domena publiczna - Adam Mickiewicz zm. 1855</dc:rights> -<dc:date.pd xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">1926</dc:date.pd> -<dc:format xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">xml</dc:format> -<dc:type xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">text</dc:type> -<dc:type xml:lang="en" xmlns:dc="http://purl.org/dc/elements/1.1/">text</dc:type> -<dc:date xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">2007-09-06</dc:date> -<dc:language xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">pol</dc:language> - -</rdf:Description> -</rdf:RDF> - -<autor_utworu>Adam Mickiewicz</autor_utworu> -<dzielo_nadrzedne>Sonety odeskie</dzielo_nadrzedne> -<nazwa_utworu>Do M***</nazwa_utworu> - -<nota><akap>Wiérsz napisany w roku 1822</akap></nota> - - -<strofa>Precz z moich oczu!... posÅucham od razu,/ -Precz z mego serca!... i serce posÅucha,/ -Precz z méj pamiÄci!... Nie! tego rozkazu/ -Moja i twoja pamiÄÄ nie posÅucha.</strofa> - -<!-- TRIM_END --> -</liryka_l> -</utwor> diff --git a/apps/catalogue/tests/files/chunk2.xml b/apps/catalogue/tests/files/chunk2.xml deleted file mode 100755 index 63a243e1..00000000 --- a/apps/catalogue/tests/files/chunk2.xml +++ /dev/null @@ -1,11 +0,0 @@ -<utwor><liryka_l> -<!-- TRIM_BEGIN --> - -<strofa>Jak cieÅ tém dÅuższy, gdy padnie z daleka,/ -Tém szerzéj koÅo żaÅobne roztoczy,/ -Tak moja postaÄ, im daléj ucieka,/ -Tém grubszym kirem twÄ pamiÄÄ pomroczy.</strofa> - - -</liryka_l> -</utwor> diff --git a/apps/catalogue/tests/files/expected.xml b/apps/catalogue/tests/files/expected.xml deleted file mode 100755 index ff225a03..00000000 --- a/apps/catalogue/tests/files/expected.xml +++ /dev/null @@ -1,49 +0,0 @@ -<utwor> - <liryka_l> - -<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -<rdf:Description rdf:about="http://example.com/documents/book/test-book/"> -<dc:creator xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Mickiewicz, Adam</dc:creator> -<dc:title xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Do M***</dc:title> -<dc:publisher xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Fundacja Nowoczesna Polska</dc:publisher> -<dc:subject.period xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Romantyzm</dc:subject.period> -<dc:subject.type xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Liryka</dc:subject.type> -<dc:subject.genre xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Wiersz</dc:subject.genre> -<!--dc:description xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl). Reprodukcja cyfrowa wykonana przez BibliotekÄ NarodowÄ z egzemplarza pochodzÄ cego ze zbiorów BN.</dc:description--> -<dc:identifier.url xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">http://wolnelektury.pl/katalog/lektura/sonety-odeskie-do-m</dc:identifier.url> -<dc:source.URL xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">http://www.polona.pl/Content/2222</dc:source.URL> -<dc:source xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Mickiewicz, Adam (1798-1855), Poezje, tom 1 (Wiersze mÅodzieÅcze - Ballady i romanse - Wiersze do r. 1824), Krakowska SpóÅdzielnia Wydawnicza, wyd. 2 zwiÄkszone, Kraków, 1922</dc:source> - -<dc:rights xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">Domena publiczna - Adam Mickiewicz zm. 1855</dc:rights> -<dc:date.pd xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">1926</dc:date.pd> -<dc:format xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">xml</dc:format> -<dc:type xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">text</dc:type> -<dc:type xml:lang="en" xmlns:dc="http://purl.org/dc/elements/1.1/">text</dc:type> -<dc:date xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">2007-09-06</dc:date> -<dc:language xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">pol</dc:language> - -</rdf:Description> -</rdf:RDF> - -<autor_utworu>Adam Mickiewicz</autor_utworu> -<dzielo_nadrzedne>Sonety odeskie</dzielo_nadrzedne> -<nazwa_utworu>Do M***</nazwa_utworu> - -<nota><akap>Wiérsz napisany w roku 1822</akap></nota> - - -<strofa>Precz z moich oczu!... posÅucham od razu,/ -Precz z mego serca!... i serce posÅucha,/ -Precz z méj pamiÄci!... Nie! tego rozkazu/ -Moja i twoja pamiÄÄ nie posÅucha.</strofa> - - - -<strofa>Jak cieÅ tém dÅuższy, gdy padnie z daleka,/ -Tém szerzéj koÅo żaÅobne roztoczy,/ -Tak moja postaÄ, im daléj ucieka,/ -Tém grubszym kirem twÄ pamiÄÄ pomroczy.</strofa> - - -</liryka_l> -</utwor> diff --git a/apps/catalogue/tests/gallery.py b/apps/catalogue/tests/gallery.py deleted file mode 100644 index ad0dfd7d..00000000 --- a/apps/catalogue/tests/gallery.py +++ /dev/null @@ -1,148 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -"""Tests for galleries of scans.""" - -from os.path import join, basename, exists -from os import makedirs, listdir -from django.test import TestCase -from django.contrib.auth.models import User -from catalogue.models import Book -from tempfile import mkdtemp -from django.conf import settings - - -class GalleryAppendTests(TestCase): - def setUp(self): - self.user = User.objects.create(username='tester') - self.book1 = Book.create(self.user, 'book 1', slug='book1') - self.book1.chunk_set.create(number=2, title='Second chunk', - slug='book 1 / 2') - c=self.book1[1] - c.gallery_start=3 - - self.scandir = join(settings.MEDIA_ROOT, settings.IMAGE_DIR) - if not exists(self.scandir): - makedirs(self.scandir) - - def make_gallery(self, book, files): - d = mkdtemp('gallery', dir=self.scandir) - for named, cont in files.items(): - f = open(join(d, named), 'w') - f.write(cont) - f.close() - book.gallery = basename(d) - - - def test_both_indexed(self): - self.book2 = Book.create(self.user, 'book 2', slug='book2') - self.book2.chunk_set.create(number=2, title='Second chunk of second book', - slug='book 2 / 2') - - c = self.book2[1] - c.gallery_start = 3 - c.save() - - print "gallery starts:",self.book2[0].gallery_start, self.book2[1].gallery_start - - self.make_gallery(self.book1, { - '1-0001_1l' : 'aa', - '1-0001_2r' : 'bb', - '1-0002_1l' : 'cc', - '1-0002_2r' : 'dd', - }) - - self.make_gallery(self.book2, { - '1-0001_1l' : 'dd', # the same, should not be moved - '1-0001_2r' : 'ff', - '2-0002_1l' : 'gg', - '2-0002_2r' : 'hh', - }) - - self.book1.append(self.book2) - - files = listdir(join(self.scandir, self.book1.gallery)) - files.sort() - print files - self.assertEqual(files, [ - '1-0001_1l', - '1-0001_2r', - '1-0002_1l', - '1-0002_2r', - # '2-0001_1l', - '2-0001_2r', - '3-0002_1l', - '3-0002_2r', - ]) - - self.assertEqual((4, 6), (self.book1[2].gallery_start, self.book1[3].gallery_start)) - - - def test_none_indexed(self): - self.book2 = Book.create(self.user, 'book 2', slug='book2') - self.make_gallery(self.book1, { - '0001_1l' : 'aa', - '0001_2r' : 'bb', - '0002_1l' : 'cc', - '0002_2r' : 'dd', - }) - - self.make_gallery(self.book2, { - '0001_1l' : 'ee', - '0001_2r' : 'ff', - '0002_1l' : 'gg', - '0002_2r' : 'hh', - }) - - self.book1.append(self.book2) - - files = listdir(join(self.scandir, self.book1.gallery)) - files.sort() - print files - self.assertEqual(files, [ - '0-0001_1l', - '0-0001_2r', - '0-0002_1l', - '0-0002_2r', - '1-0001_1l', - '1-0001_2r', - '1-0002_1l', - '1-0002_2r', - ]) - - - def test_none_indexed(self): - import nose.tools - self.book2 = Book.create(self.user, 'book 2', slug='book2') - self.make_gallery(self.book1, { - '1-0001_1l' : 'aa', - '1-0001_2r' : 'bb', - '1002_1l' : 'cc', - '1002_2r' : 'dd', - }) - - self.make_gallery(self.book2, { - '0001_1l' : 'ee', - '0001_2r' : 'ff', - '0002_1l' : 'gg', - '0002_2r' : 'hh', - }) - - self.book1.append(self.book2) - - files = listdir(join(self.scandir, self.book1.gallery)) - files.sort() - print files - self.assertEqual(files, [ - '0-1-0001_1l', - '0-1-0001_2r', - '0-1002_1l', - '0-1002_2r', - '1-0001_1l', - '1-0001_2r', - '1-0002_1l', - '1-0002_2r', - ]) - diff --git a/apps/catalogue/tests/publish.py b/apps/catalogue/tests/publish.py deleted file mode 100644 index 9f0b8ca4..00000000 --- a/apps/catalogue/tests/publish.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -"""Tests for the publishing process.""" - -from catalogue.test_utils import get_fixture - -from mock import patch -from django.test import TestCase -from django.contrib.auth.models import User -from catalogue.models import Book - - -class PublishTests(TestCase): - def setUp(self): - self.user = User.objects.create(username='tester') - self.text1 = get_fixture('chunk1.xml') - self.book = Book.create(self.user, self.text1, slug='test-book') - - @patch('apiclient.api_call') - def test_unpublishable(self, api_call): - with self.assertRaises(AssertionError): - self.book.publish(self.user) - - @patch('apiclient.api_call') - def test_publish(self, api_call): - self.book[0].head.set_publishable(True) - self.book.publish(self.user) - api_call.assert_called_with(self.user, 'books/', {"book_xml": self.text1}) - - @patch('apiclient.api_call') - def test_publish_multiple(self, api_call): - self.book[0].head.set_publishable(True) - self.book[0].split(slug='part-2') - self.book[1].commit(get_fixture('chunk2.xml')) - self.book[1].head.set_publishable(True) - self.book.publish(self.user) - api_call.assert_called_with(self.user, 'books/', {"book_xml": get_fixture('expected.xml')}) diff --git a/apps/catalogue/tests/xml_updater.py b/apps/catalogue/tests/xml_updater.py deleted file mode 100644 index 9fb5a4a0..00000000 --- a/apps/catalogue/tests/xml_updater.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -"""XmlUpdater tests.""" - -from catalogue.test_utils import get_fixture -from django.test import TestCase -from django.contrib.auth.models import User -from catalogue.models import Book -from catalogue.management import XmlUpdater -from librarian import DCNS - - -class XmlUpdaterTests(TestCase): - class SimpleUpdater(XmlUpdater): - @XmlUpdater.fixes_elements('.//' + DCNS('title')) - def fix_title(element, **kwargs): - element.text = element.text + " fixed" - return True - - def setUp(self): - self.user = User.objects.create(username='tester') - text = get_fixture('chunk1.xml') - Book.create(self.user, text, slug='test-book') - self.title = "Do M***" - - def test_xml_updater(self): - self.SimpleUpdater().run(self.user) - self.assertEqual( - Book.objects.get(slug='test-book').wldocument( - publishable=False).book_info.title, - self.title + " fixed" - ) diff --git a/apps/catalogue/urls.py b/apps/catalogue/urls.py index 8a9945ab..148851b2 100644 --- a/apps/catalogue/urls.py +++ b/apps/catalogue/urls.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 from django.conf.urls import patterns, url -from django.contrib.auth.decorators import permission_required, login_required -from catalogue.views import GalleryView, GalleryPackageView +from django.contrib.auth.decorators import login_required +from catalogue.views import GalleryView urlpatterns = patterns( @@ -11,15 +11,8 @@ urlpatterns = patterns( url(r'^upcoming/$', 'upcoming', name='catalogue_upcoming'), url(r'^finished/$', 'finished', name='catalogue_finished'), - # url(r'^catalogue/$', 'document_list', name='catalogue_document_list'), url(r'^user/$', 'my', name='catalogue_user'), url(r'^user/(?P<username>[^/]+)/$', 'user', name='catalogue_user'), - url(r'^users/$', 'users', name='catalogue_users'), - url(r'^activity/$', 'activity', name='catalogue_activity'), - url(r'^activity/(?P<isodate>\d{4}-\d{2}-\d{2})/$', - 'activity', name='catalogue_activity'), - - # url(r'^upload/$', 'upload', name='catalogue_upload'), url(r'^create/(?P<slug>[^/]*)/', 'create_missing', name='catalogue_create_missing'), @@ -30,43 +23,17 @@ urlpatterns = patterns( url(r'^doc/(?P<pk>\d+)/publish$', 'publish', name="catalogue_publish"), url(r'^doc/(?P<pk>\d+)/unpublish$', 'unpublish', name="catalogue_unpublish"), - # url(r'^(?P<name>[^/]+)/publish/(?P<version>\d+)$', 'publish', name="catalogue_publish"), url(r'^(?P<pk>[^/]+)/schedule/$', 'book_schedule', name="catalogue_book_schedule"), url(r'^(?P<pk>[^/]+)/owner/$', 'book_owner', name="catalogue_book_owner"), url(r'^(?P<pk>[^/]+)/delete/$', 'book_delete', name="catalogue_book_delete"), - # url(r'^book/(?P<slug>[^/]+)/$', 'book', name="catalogue_book"), - url(r'^(?P<pk>[^/]+)/attachments/$', login_required()(GalleryView.as_view()), name="catalogue_book_gallery"), - # url(r'^attachments/$', - # login_required()(GalleryView.as_view()), - # name="catalogue_attachments"), - # url(r'^attachments/(?P<pk>\d+)/$', - # login_required()(GalleryView.as_view()), - # name="catalogue_attachments"), - url(r'^book/(?P<slug>[^/]+)/gallery/package$', - permission_required('catalogue.change_book')(GalleryPackageView.as_view()), - name="catalogue_book_gallery_package"), - # url(r'^book/(?P<slug>[^/]+)/xml$', 'book_xml', name="catalogue_book_xml"), - # url(r'^book/(?P<slug>[^/]+)/txt$', 'book_txt', name="catalogue_book_txt"), url(r'^(?P<pk>\d+)/$', 'book_html', name="catalogue_html"), url(r'^(?P<pk>\d+)/preview/$', 'book_html', {'preview': True}, name="catalogue_preview"), url(r'^(?P<pk>\d+)/rev(?P<rev_pk>\d+)/preview/$', 'book_html', {'preview': True}, name="catalogue_preview_rev"), url(r'^(?P<pk>\d+)/rev(?P<rev_pk>\d+)/pdf/$', 'book_pdf', name="catalogue_pdf"), url(r'^(?P<pk>\d+)/rev(?P<rev_pk>\d+)/epub/$', 'book_epub', name="catalogue_epub"), - - # url(r'^book/(?P<slug>[^/]+)/epub$', 'book_epub', name="catalogue_book_epub"), - # url(r'^book/(?P<slug>[^/]+)/pdf$', 'book_pdf', name="catalogue_book_pdf"), - - # url(r'^chunk_add/(?P<slug>[^/]+)/(?P<chunk>[^/]+)/$', - # 'chunk_add', name="catalogue_chunk_add"), - # url(r'^chunk_edit/(?P<slug>[^/]+)/(?P<chunk>[^/]+)/$', - # 'chunk_edit', name="catalogue_chunk_edit"), - # url(r'^book_append/(?P<slug>[^/]+)/$', - # 'book_append', name="catalogue_book_append"), - # url(r'^chunk_mass_edit', - # 'chunk_mass_edit', name='catalogue_chunk_mass_edit'), ) diff --git a/apps/catalogue/views.py b/apps/catalogue/views.py index d116fcb1..1d1b36ec 100644 --- a/apps/catalogue/views.py +++ b/apps/catalogue/views.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- -from datetime import date, timedelta +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# import logging import os import shutil @@ -9,7 +12,6 @@ from django.contrib import auth from django.contrib.auth.models import User from django.contrib.auth.decorators import login_required from django.core.urlresolvers import reverse -from django.db.models import Count from django import http from django.http import Http404 from django.shortcuts import get_object_or_404, render, redirect @@ -18,14 +20,13 @@ from django.utils.http import urlquote_plus from django.views.decorators.http import require_POST from catalogue import forms -from catalogue import helpers from catalogue.helpers import active_tab from librarian import BuildError from .constants import STAGES from .models import Document, Plan from dvcs.models import Revision from organizations.models import Organization -from fileupload.views import UploadView, PackageView +from fileupload.views import UploadView # # Quick hack around caching problems, TODO: use ETags @@ -60,38 +61,12 @@ def my(request): }) -@active_tab('users') -def users(request): - return render(request, 'catalogue/user_list.html', { - 'users': User.objects.all().annotate(count=Count('chunk')).order_by( - '-count', 'last_name', 'first_name'), - }) - - -@active_tab('activity') -def activity(request, isodate=None): - today = date.today() - try: - day = helpers.parse_isodate(isodate) - except ValueError: - day = today - - if day > today: - raise Http404 - if day != today: - next_day = day + timedelta(1) - prev_day = day - timedelta(1) - - return render(request, 'catalogue/activity.html', locals()) - - @never_cache def logout_then_redirect(request): auth.logout(request) return http.HttpResponseRedirect(urlquote_plus(request.GET.get('next', '/'), safe='/?=')) -# @permission_required('catalogue.add_book') @login_required @active_tab('create') def create_missing(request): @@ -171,96 +146,6 @@ def create_missing(request): }) -# @permission_required('catalogue.add_book') -# @active_tab('upload') -# def upload(request): -# if request.method == "POST": -# form = forms.DocumentsUploadForm(request.POST, request.FILES) -# if form.is_valid(): -# import slughifi -# -# if request.user.is_authenticated(): -# creator = request.user -# else: -# creator = None -# -# zip = form.cleaned_data['zip'] -# skipped_list = [] -# ok_list = [] -# error_list = [] -# slugs = {} -# existing = [book.slug for book in Book.objects.all()] -# for filename in zip.namelist(): -# if filename[-1] == '/': -# continue -# title = os.path.basename(filename)[:-4] -# slug = slughifi(title) -# if not (slug and filename.endswith('.xml')): -# skipped_list.append(filename) -# elif slug in slugs: -# error_list.append((filename, slug, _('Slug already used for %s' % slugs[slug]))) -# elif slug in existing: -# error_list.append((filename, slug, _('Slug already used in repository.'))) -# else: -# try: -# zip.read(filename).decode('utf-8') # test read -# ok_list.append((filename, slug, title)) -# except UnicodeDecodeError: -# error_list.append((filename, title, _('File should be UTF-8 encoded.'))) -# slugs[slug] = filename -# -# if not error_list: -# for filename, slug, title in ok_list: -# book = Book.create( -# text=zip.read(filename).decode('utf-8'), -# creator=creator, -# slug=slug, -# title=title, -# ) -# -# return render(request, "catalogue/document_upload.html", { -# "form": form, -# "ok_list": ok_list, -# "skipped_list": skipped_list, -# "error_list": error_list, -# -# "logout_to": '/', -# }) -# else: -# form = forms.DocumentsUploadForm() -# -# return render(request, "catalogue/document_upload.html", { -# "form": form, -# -# "logout_to": '/', -# }) - - -# @never_cache -# def book_xml(request, slug): -# book = get_object_or_404(Book, slug=slug) -# if not book.accessible(request): -# return HttpResponseForbidden("Not authorized.") -# xml = book.materialize() -# -# response = http.HttpResponse(xml, content_type='application/xml', mimetype='application/wl+xml') -# response['Content-Disposition'] = 'attachment; filename=%s.xml' % slug -# return response - - -# @never_cache -# def book_txt(request, slug): -# book = get_object_or_404(Book, slug=slug) -# if not book.accessible(request): -# return HttpResponseForbidden("Not authorized.") -# -# doc = book.wldocument() -# text = doc.as_text().get_string() -# response = http.HttpResponse(text, content_type='text/plain', mimetype='text/plain') -# response['Content-Disposition'] = 'attachment; filename=%s.txt' % slug -# return response - - @never_cache def book_html(request, pk, rev_pk=None, preview=False): from librarian.document import Document as SST @@ -455,192 +340,6 @@ def book_delete(request, pk): }) -# def book(request, slug): -# book = get_object_or_404(Book, slug=slug) -# if not book.accessible(request): -# return HttpResponseForbidden("Not authorized.") -# -# if request.user.has_perm('catalogue.change_book'): -# if request.method == "POST": -# form = forms.BookForm(request.POST, instance=book) -# if form.is_valid(): -# form.save() -# return http.HttpResponseRedirect(book.get_absolute_url()) -# else: -# form = forms.BookForm(instance=book) -# editable = True -# else: -# form = forms.ReadonlyBookForm(instance=book) -# editable = False -# -# publish_error = book.publishable_error() -# publishable = publish_error is None -# -# return render(request, "catalogue/book_detail.html", { -# "book": book, -# "publishable": publishable, -# "publishable_error": publish_error, -# "form": form, -# "editable": editable, -# }) - - -# @permission_required('catalogue.add_chunk') -# def chunk_add(request, slug, chunk): -# try: -# doc = Chunk.get(slug, chunk) -# except (Chunk.MultipleObjectsReturned, Chunk.DoesNotExist): -# raise Http404 -# if not doc.book.accessible(request): -# return HttpResponseForbidden("Not authorized.") -# -# if request.method == "POST": -# form = forms.ChunkAddForm(request.POST, instance=doc) -# if form.is_valid(): -# if request.user.is_authenticated(): -# creator = request.user -# else: -# creator = None -# doc.split(creator=creator, -# slug=form.cleaned_data['slug'], -# title=form.cleaned_data['title'], -# gallery_start=form.cleaned_data['gallery_start'], -# user=form.cleaned_data['user'], -# stage=form.cleaned_data['stage'] -# ) -# -# return http.HttpResponseRedirect(doc.book.get_absolute_url()) -# else: -# form = forms.ChunkAddForm(initial={ -# "slug": str(doc.number + 1), -# "title": "cz. %d" % (doc.number + 1, ), -# }) -# -# return render(request, "catalogue/chunk_add.html", { -# "chunk": doc, -# "form": form, -# }) - - -# @login_required -# def chunk_edit(request, slug, chunk): -# try: -# doc = Chunk.get(slug, chunk) -# except (Chunk.MultipleObjectsReturned, Chunk.DoesNotExist): -# raise Http404 -# if not doc.book.accessible(request): -# return HttpResponseForbidden("Not authorized.") -# -# if request.method == "POST": -# form = forms.ChunkForm(request.POST, instance=doc) -# if form.is_valid(): -# form.save() -# go_next = request.GET.get('next', None) -# if go_next: -# go_next = urlquote_plus(unquote(iri_to_uri(go_next)), safe='/?=&') -# else: -# go_next = doc.book.get_absolute_url() -# return http.HttpResponseRedirect(go_next) -# else: -# form = forms.ChunkForm(instance=doc) -# -# referer = request.META.get('HTTP_REFERER') -# if referer: -# parts = urlsplit(referer) -# parts = ['', ''] + list(parts[2:]) -# go_next = urlquote_plus(urlunsplit(parts)) -# else: -# go_next = '' -# -# return render(request, "catalogue/chunk_edit.html", { -# "chunk": doc, -# "form": form, -# "go_next": go_next, -# }) - - -# @transaction.atomic -# @login_required -# def chunk_mass_edit(request): -# if request.method == 'POST': -# ids = map(int, filter(lambda i: i.strip()!='', request.POST.get('ids').split(','))) -# chunks = map(lambda i: Chunk.objects.get(id=i), ids) -# -# stage = request.POST.get('stage') -# if stage: -# try: -# stage = Chunk.tag_model.objects.get(slug=stage) -# except Chunk.DoesNotExist, e: -# stage = None -# -# for c in chunks: c.stage = stage -# -# username = request.POST.get('user') -# logger.info("username: %s" % username) -# logger.info(request.POST) -# if username: -# try: -# user = User.objects.get(username=username) -# except User.DoesNotExist, e: -# user = None -# -# for c in chunks: c.user = user -# -# status = request.POST.get('status') -# if status: -# books_affected = set() -# for c in chunks: -# if status == 'publish': -# c.head.publishable = True -# c.head.save() -# elif status == 'unpublish': -# c.head.publishable = False -# c.head.save() -# c.touch() # cache -# books_affected.add(c.book) -# for b in books_affected: -# b.touch() # cache -# -# project_id = request.POST.get('project') -# if project_id: -# try: -# project = Project.objects.get(pk=int(project_id)) -# except (Project.DoesNotExist, ValueError), e: -# project = None -# for c in chunks: -# book = c.book -# book.project = project -# book.save() -# -# for c in chunks: c.save() -# -# return HttpResponse("", content_type="text/plain") -# else: -# raise Http404 - - -# @permission_required('catalogue.change_book') -# def book_append(request, slug): -# book = get_object_or_404(Book, slug=slug) -# if not book.accessible(request): -# return HttpResponseForbidden("Not authorized.") -# -# if request.method == "POST": -# form = forms.BookAppendForm(book, request.POST) -# if form.is_valid(): -# append_to = form.cleaned_data['append_to'] -# append_to.append(book) -# return http.HttpResponseRedirect(append_to.get_absolute_url()) -# else: -# form = forms.BookAppendForm(book) -# return render(request, "catalogue/book_append_to.html", { -# "book": book, -# "form": form, -# -# "logout_to": '/', -# }) - - @require_POST @login_required def publish(request, pk): @@ -702,12 +401,6 @@ class GalleryView(GalleryMixin, UploadView): self.doc = Document.objects.get(pk=pk, deleted=False) -class GalleryPackageView(GalleryMixin, PackageView): - - def get_redirect_url(self, slug): - return reverse('catalogue_book_gallery', kwargs=dict(slug=slug)) - - @login_required def fork(request, pk): doc = get_object_or_404(Document, pk=pk, deleted=False) diff --git a/apps/catalogue/xml_tools.py b/apps/catalogue/xml_tools.py index 242714b6..4365fbdd 100644 --- a/apps/catalogue/xml_tools.py +++ b/apps/catalogue/xml_tools.py @@ -103,7 +103,7 @@ def split_xml(text): name_elem = deepcopy(element) for tag in 'extra', 'motyw', 'pa', 'pe', 'pr', 'pt', 'uwaga': for a in name_elem.findall('.//' + tag): - a.text='' + a.text = '' del a[:] name = etree.tostring(name_elem, method='text', encoding='utf-8').strip() @@ -123,15 +123,17 @@ def split_xml(text): while parent[0] is not element: del parent[0] element, parent = parent, parent.getparent() - chunks[:0] = [[name, + chunks[:0] = [[ + name, unicode(etree.tostring(copied, encoding='utf-8'), 'utf-8') - ]] + ]] parts = src.findall('.//naglowek_rozdzial') - chunks[:0] = [[u'poczÄ tek', + chunks[:0] = [[ + u'poczÄ tek', unicode(etree.tostring(src, encoding='utf-8'), 'utf-8') - ]] + ]] for ch in chunks[1:]: ch[1] = add_trim_begin(ch[1]) diff --git a/apps/cover/__init__.py b/apps/cover/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/apps/cover/forms.py b/apps/cover/forms.py deleted file mode 100755 index 628cb63e..00000000 --- a/apps/cover/forms.py +++ /dev/null @@ -1,102 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -import re -from urllib2 import urlopen -from django import forms -from django.utils.translation import ugettext_lazy as _ -from cover.models import Image - -class ImageAddForm(forms.ModelForm): - class Meta: - model = Image - exclude = [] - - def __init__(self, *args, **kwargs): - super(ImageAddForm, self).__init__(*args, **kwargs) - self.fields['file'].required = self.fields['download_url'].required = self.fields['source_url'].required = False - - def clean_download_url(self): - return self.cleaned_data['download_url'] or None - - def clean_source_url(self): - return self.cleaned_data['source_url'] or None - - def clean(self): - cleaned_data = super(ImageAddForm, self).clean() - if not cleaned_data.get('download_url', None) and not cleaned_data.get('file', None): - raise forms.ValidationError('No image specified') - return cleaned_data - - -class ImageEditForm(forms.ModelForm): - """Form used for editing a Book.""" - class Meta: - model = Image - exclude = ['download_url'] - - -class ReadonlyImageEditForm(ImageEditForm): - """Form used for not editing a Book.""" - - def __init__(self, *args, **kwargs): - ret = super(ReadonlyImageEditForm, self).__init__(*args, **kwargs) - for field in self.fields.values(): - field.widget.attrs.update({"readonly": True}) - return ret - - def save(self, *args, **kwargs): - raise AssertionError, "ReadonlyImageEditForm should not be saved." - - -class FlickrForm(forms.Form): - source_url = forms.URLField(label=_('Flickr URL')) - - def clean_source_url(self): - def normalize_html(html): - return re.sub('[\t\n]', '', html) - - url = self.cleaned_data['source_url'] - m = re.match(r'(https?://)?(www\.|secure\.)?flickr\.com/photos/(?P<author>[^/]+)/(?P<img>\d+)/?', url) - if not m: - raise forms.ValidationError("It doesn't look like Flickr URL.") - author_slug, img_id = m.group('author'), m.group('img') - base_url = "https://www.flickr.com/photos/%s/%s/" % (author_slug, img_id) - - try: - html = normalize_html(urlopen(url).read().decode('utf-8')) - except: - raise forms.ValidationError('Error reading page.') - match = re.search(r'<a href="([^"]*)" rel="license cc:license">Some rights reserved</a>', html) - try: - assert match - license_url = match.group(1) - self.cleaned_data['license_url'] = license_url - re_license = re.compile(r'http://creativecommons.org/licenses/([^/]*)/([^/]*)/.*') - m = re_license.match(license_url) - assert m - self.cleaned_data['license_name'] = 'CC %s %s' % (m.group(1).upper(), m.group(2)) - except AssertionError: - raise forms.ValidationError('Error reading license name.') - - m = re.search(r'"ownername":"([^"]*)', html) - if m: - self.cleaned_data['author'] = "%s@Flickr" % m.group(1) - else: - raise forms.ValidationError('Error reading author name.') - - m = re.search(r'<h1[^>]*>(.*?)</h1>', html) - if not m: - raise forms.ValidationError('Error reading image title.') - self.cleaned_data['title'] = m.group(1) - - url_size = base_url + "sizes/o/" - html = normalize_html(urlopen(url_size).read().decode('utf-8')) - m = re.search(r'<div id="allsizes-photo">\s*<img src="([^"]*)"', html) - if m: - self.cleaned_data['download_url'] = m.group(1) - else: - raise forms.ValidationError('Error reading image URL.') - return base_url diff --git a/apps/cover/locale/pl/LC_MESSAGES/django.mo b/apps/cover/locale/pl/LC_MESSAGES/django.mo deleted file mode 100644 index c4177edc5d463ae477bb45bf63f34474ffa7dbf9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1365 zcmZ9K&u<$=6vwAD(BeYrFD?}obAZwcO}gt;R<w;vQa7n0oWyeNs;YXK>`t7?u4mlY zaot!Ihln04aRG@Ve*p(>sF#Ym=W^kK#DyE&xwhZ8wu#}%v!6Hb=e+U!ac1sY204fI z5!N%T3t0D$-~)LDz6<^e9s_>|-vR#wPk?`c?}7h-CGhB5jGY2cf^*=<;BoL1kn#jb zc~?QoTLvj^13UvZCw?{YKL9E3E0F3x0pA9{0iUDici{Wj-$fDf?|>Bl0Hm27foH*| zAjSOvo(6ve@ng^Nq4{2dRQDA~dB1^__cw?idyUVB;2eVJ+~>iQ;AbG^S3s)23{wA1 z5XUQKB|8b#qcc+fsnFd_1)~&apnN(5^*xG3@&Ojz|5T_q3H7G?rn{qav6Up@x+^=X z(2N?e+O9O%*6c&&CaxJhXKR^`Q^(uQI;&fm@EvEnd~9T!)+pA_6>6G@$-dvUj>R*T zX7rrx=uEMqIZy1sWK@mHqJc8G`j2j8SFzmoT|7nM_S&OH!`VF*d$FE~JIdwSnus@6 zYG1D0TIF|Eo441uHcL&_v(Af+yrUCwqu<Fz%SOD^*lLNIQ_>?z+>~BLyc~oT5rm># z;b9OhR6Y;FAV8pKs)w42AI6nMP!ZuG56jWQ;yA7@b1zy>nmm)<x`;PrqEcQP%Dq(b zB_|UL&tN_-49mt2Y&=xCkv*H`shqd2GvCXum+JTz`uJZ&OUZ7;>noeL+BDBny}q1j z3OkI!92@H!tB1pf^FgU*jaLR|+3#T}uO9g;y-aFzjmNvv<;qvvtu?WD7)NK`QBJIy z*e2R^BEGn-eW{W4oy^3Vb=^GTrdMq9>cTZXR;!mxwHop-c);QQGz_j+%lzWSLS3p} zCG`@SgQYOwj~^FyiU}?wCqz#9a*5rviQMCM+sUCyCp%otKD*b|YV<YR8hf~r+@_-g znWQhi9~)CWW7G`qhYu&uQL={J*2)cMEH|7?S$p(s-zz>So+w`Er0+~2R4<JGtKQ2r wveAN+K3*;FQJB%Puoe$D-qXy;;Xv|#x1*okFFz%t16xE*car&i-ya>YH=$}rAOHXW diff --git a/apps/cover/locale/pl/LC_MESSAGES/django.po b/apps/cover/locale/pl/LC_MESSAGES/django.po deleted file mode 100644 index f1d79a3a..00000000 --- a/apps/cover/locale/pl/LC_MESSAGES/django.po +++ /dev/null @@ -1,95 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-01-26 10:36+0100\n" -"PO-Revision-Date: 2012-06-18 12:38+0100\n" -"Last-Translator: Radek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " -"|| n%100>=20) ? 1 : 2)\n" - -#: forms.py:55 -msgid "Flickr URL" -msgstr "URL z Flickra" - -#: models.py:19 -msgid "title" -msgstr "tytuÅ" - -#: models.py:20 -msgid "author" -msgstr "autor" - -#: models.py:21 -msgid "license name" -msgstr "nazwa licencji" - -#: models.py:22 -msgid "license URL" -msgstr "URL licencji" - -#: models.py:23 -msgid "source URL" -msgstr "URL źródÅa" - -#: models.py:24 -msgid "image download URL" -msgstr "URL pliku do pobrania" - -#: models.py:25 -msgid "file" -msgstr "plik" - -#: models.py:28 -msgid "cover image" -msgstr "obrazek na okÅadkÄ" - -#: models.py:29 -msgid "cover images" -msgstr "obrazki na okÅadki" - -#: templates/cover/add_image.html:33 templates/cover/add_image.html.py:62 -msgid "Add image" -msgstr "Dodaj obrazek" - -#: templates/cover/add_image.html:40 -msgid "Load from Flickr" -msgstr "Pobierz z Flickra" - -#: templates/cover/image_detail.html:7 -msgid "Cover image" -msgstr "Obrazek na okÅadkÄ" - -#: templates/cover/image_detail.html:23 -msgid "source" -msgstr "źródÅo" - -#: templates/cover/image_detail.html:31 -msgid "Change" -msgstr "ZmieÅ" - -#: templates/cover/image_detail.html:37 -msgid "Used in:" -msgstr "Użyte w:" - -#: templates/cover/image_detail.html:45 -msgid "None" -msgstr "Brak" - -#: templates/cover/image_list.html:7 -msgid "Cover images" -msgstr "Obrazki na okÅadki" - -#: templates/cover/image_list.html:10 -msgid "Add new" -msgstr "Dodaj nowy" diff --git a/apps/cover/models.py b/apps/cover/models.py deleted file mode 100644 index d4432c2c..00000000 --- a/apps/cover/models.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -import re -from urlparse import urljoin -from django.conf import settings -from django.core.files.base import ContentFile -from django.db import models -from django.db.models.signals import post_save -from django.dispatch import receiver -from django.utils.translation import ugettext_lazy as _ -from django.contrib.sites.models import Site -from cover.utils import URLOpener - - -class Image(models.Model): - title = models.CharField(max_length=255, verbose_name=_('title')) - author = models.CharField(max_length=255, verbose_name=_('author')) - license_name = models.CharField(max_length=255, verbose_name=_('license name')) - license_url = models.URLField(max_length=255, blank=True, verbose_name=_('license URL')) - source_url = models.URLField(verbose_name=_('source URL'), null = True) - download_url = models.URLField(unique=True, verbose_name=_('image download URL'), null = True) - file = models.ImageField(upload_to='cover/image', editable=True, verbose_name=_('file')) - - class Meta: - verbose_name = _('cover image') - verbose_name_plural = _('cover images') - - def __unicode__(self): - return u"%s - %s" % (self.author, self.title) - - @models.permalink - def get_absolute_url(self): - return ('cover_image', [self.id]) - - def get_full_url(self): - return "http://%s%s" % (Site.objects.get_current().domain, self.get_absolute_url()) - - -@receiver(post_save, sender=Image) -def download_image(sender, instance, **kwargs): - if instance.pk and not instance.file: - t = URLOpener().open(instance.download_url).read() - instance.file.save("%d.jpg" % instance.pk, ContentFile(t)) - - \ No newline at end of file diff --git a/apps/cover/templates/cover/add_image.html b/apps/cover/templates/cover/add_image.html deleted file mode 100755 index 1854555f..00000000 --- a/apps/cover/templates/cover/add_image.html +++ /dev/null @@ -1,67 +0,0 @@ -{% extends "catalogue/base.html" %} -{% load i18n %} - -{% block add_js %} - {{block.super}} - <script> - $(function() { - var radio_buttons = $('input[type=radio][name=upload_type]'), - image_fields = $('.upload_type input[type=text],input[type=file]'); - - var enable_image_field = function(field) { - field.attr('disabled', false); - }, - disable_image_fields = function() { - image_fields.attr('disabled', true); - } - - radio_buttons.change(function() { - var radio_button = $(this), - related_image_field = $('#'+radio_button.attr('data-for')); - disable_image_fields(); - enable_image_field(related_image_field); - }); - - /* initial state */ - disable_image_fields(); - enable_image_field($('#id_download_url')); - }); - </script> -{% endblock %} - -{% block content %} -<h1>{% trans "Add image" %}</h1> - - -<form method="post">{% csrf_token %} -<input type="hidden" name='form_id' value="flickr" /> -<table class='editable'><tbody> - {{ ff.as_table }} - <tr><td></td><td><button type="submit">{% trans "Load from Flickr" %}</button></td></tr> -</tbody></table> -</form> - -<form method="post" enctype="multipart/form-data">{% csrf_token %} -{{ form.non_field_errors }} -<table class='editable'><tbody> - {% for field in form %} - {% if field.name != 'download_url' and field.name != 'file' %} - <tr> - <th>{{field.errors}} {{field.label}}</th> - <td>{{field}}</td> - </tr> - {% endif %} - {% endfor %} - <tr class="upload_type"> - <th>{{ form.download_url.errors }} <input style="width: auto;" checked data-for="id_download_url" type="radio" name="upload_type" value="url"/>{{form.download_url.label}}</th> - <td>{{form.download_url}}</td> - <th>{{ form.file.errors }} <input style="width: auto;" data-for="id_file" type="radio" name="upload_type" value="file"/> Lub {{form.file.label}}</th> - <td>{{form.file}}</td> - - </td> - <tr><td></td><td><button type="submit">{% trans "Add image" %}</button></td></tr> -</tbody></table> -</form> - - -{% endblock %} diff --git a/apps/cover/templates/cover/image_detail.html b/apps/cover/templates/cover/image_detail.html deleted file mode 100755 index 5707b29e..00000000 --- a/apps/cover/templates/cover/image_detail.html +++ /dev/null @@ -1,54 +0,0 @@ -{% extends "catalogue/base.html" %} -{% load i18n %} -{% load thumbnail %} -{% load build_absolute_uri from common_tags %} - -{% block content %} -<h1>{% trans "Cover image" %}</h1> - -<div style="float: right; margin-bottom:1em;"> - -<a href="{{ object.file.url }}"><img style="width:400px" - src="{% thumbnail object.file "400x" as thumb %} - {{ thumb.url }} - {% empty %} - {{ object.file.url }} - {% endthumbnail %}" /> - </a> -<br/><a href="{{ object.source_url }}">{{ object.title }}</a> by {{ object.author }}, - {% if object.license_url %}<a href="{{ object.license_url }}">{% endif %} - {{ object.license_name }}</a> - {% if object.license_url %}</a>{% endif %} - -<br/>{% trans "source" %}: {{ object.download_url }} -</div> - - -{% if editable %}<form method="post">{% csrf_token %}{% endif %} -<table class='editable'><tbody> - {{ form.as_table }} - {% if editable %} - <tr><td></td><td><button type="submit">{% trans "Change" %}</button></td></tr> - {% endif %} -</tbody></table> -{% if editable %}</form>{% endif %} - - -<h2>{% trans "Used in:" %}</h2> -{% if object.book_set %} -<ul> - {% for book in object.book_set.all %} - <li><a href="{{ book.get_absolute_url }}">{{ book }}</a></li> - {% endfor %} -</ul> -{% else %} - <p>{% trans "None" %}</p> -{% endif %} - - -<textarea style="width:100%" rows="5"> -<dc:relation.coverImage.url xmlns:dc="http://purl.org/dc/elements/1.1/">{{ object.file.url|build_absolute_uri:request }}</dc:relation.coverImage.url> -<dc:relation.coverImage.attribution xmlns:dc="http://purl.org/dc/elements/1.1/">{{ object.author }}, {{ object.license_name }}</dc:relation.coverImage.attribution> -<dc:relation.coverImage.source xmlns:dc="http://purl.org/dc/elements/1.1/">{{ object.get_full_url }}</dc:relation.coverImage.source> -</textarea> -{% endblock %} diff --git a/apps/cover/templates/cover/image_list.html b/apps/cover/templates/cover/image_list.html deleted file mode 100755 index 2b799fe5..00000000 --- a/apps/cover/templates/cover/image_list.html +++ /dev/null @@ -1,30 +0,0 @@ -{% extends "catalogue/base.html" %} -{% load i18n %} -{% load thumbnail pagination_tags %} - - -{% block content %} -<h1>{% trans "Cover images" %}</h1> - -{% if can_add %} - <a href="{% url 'cover_add_image' %}">{% trans "Add new" %}</a> -{% endif %} - -<ul> -{% autopaginate object_list 100 %} -{% for image in object_list %} - <a href="{{ image.get_absolute_url }}" style="display:inline-block; width:200px;"> - - <img style="height: 100px" - src="{% thumbnail image.file "x100" as thumb %} - {{ thumb.url }} - {% empty %} - {{ image.file.url }} - {% endthumbnail %}" /> - <br/> - {{ image }}</a> -{% endfor %} -{% paginate %} -</ul> - -{% endblock %} diff --git a/apps/cover/tests.py b/apps/cover/tests.py deleted file mode 100644 index 2f5b304e..00000000 --- a/apps/cover/tests.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -from nose.tools import * -from django.test import TestCase -from cover.forms import FlickrForm - - -class FlickrTests(TestCase): - def test_flickr(self): - form = FlickrForm({"source_url": "https://www.flickr.com/photos/rczajka/6941928577/in/photostream"}) - self.assertTrue(form.is_valid()) - self.assertEqual(form.cleaned_data['source_url'], "https://www.flickr.com/photos/rczajka/6941928577/") - self.assertEqual(form.cleaned_data['author'], "rczajka@Flickr") - self.assertEqual(form.cleaned_data['title'], u"Pirate StaÅczyk") - self.assertEqual(form.cleaned_data['license_name'], "CC BY 2.0") - self.assertEqual(form.cleaned_data['license_url'], "http://creativecommons.org/licenses/by/2.0/deed.en") - self.assertEqual(form.cleaned_data['download_url'], "https://farm8.staticflickr.com/7069/6941928577_415844c58e_o.jpg") diff --git a/apps/cover/urls.py b/apps/cover/urls.py deleted file mode 100644 index f1a48d35..00000000 --- a/apps/cover/urls.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -from django.conf.urls import patterns, url - - -urlpatterns = patterns('cover.views', - url(r'^preview/$', 'preview_from_xml', name='cover_preview'), - url(r'^preview/(?P<book>[^/]+)/$', 'preview', name='cover_preview'), - url(r'^preview/(?P<book>[^/]+)/(?P<chunk>[^/]+)/$', - 'preview', name='cover_preview'), - url(r'^preview/(?P<book>[^/]+)/(?P<chunk>[^/]+)/(?P<rev>\d+)/$', - 'preview', name='cover_preview'), - - url(r'^image/$', 'image_list', name='cover_image_list'), - url(r'^image/(?P<pk>\d+)/?$', 'image', name='cover_image'), - url(r'^add_image/$', 'add_image', name='cover_add_image'), -) diff --git a/apps/cover/utils.py b/apps/cover/utils.py deleted file mode 100755 index e22fa727..00000000 --- a/apps/cover/utils.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -from urllib import FancyURLopener -from django.contrib.sites.models import Site - - -class URLOpener(FancyURLopener): - @property - def version(self): - return 'FNP Redakcja (http://%s)' % Site.objects.get_current() diff --git a/apps/cover/views.py b/apps/cover/views.py deleted file mode 100644 index 752a8244..00000000 --- a/apps/cover/views.py +++ /dev/null @@ -1,139 +0,0 @@ -# -*- coding: utf-8 -*- -# -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -import os.path -from django.conf import settings -from django.contrib.auth.decorators import permission_required -from django.http import HttpResponse, HttpResponseRedirect, Http404 -from django.shortcuts import get_object_or_404, render -from django.views.decorators.csrf import csrf_exempt -from django.views.decorators.http import require_POST -from catalogue.helpers import active_tab -from catalogue.models import Document -from cover.models import Image -from cover import forms - - -PREVIEW_SIZE = (216, 300) - - -def preview(request, book, chunk=None, rev=None): - """Creates a cover image. - - If chunk and rev number are given, use version from given revision. - If rev is not given, use publishable version. - """ - from PIL import Image - from librarian.cover import WLCover - from librarian.dcparser import BookInfo - - chunk = Chunk.get(book, chunk) - if rev is not None: - try: - revision = chunk.at_revision(rev) - except Chunk.change_model.DoesNotExist: - raise Http404 - else: - revision = chunk.publishable() - if revision is None: - raise Http404 - xml = revision.materialize().encode('utf-8') - - try: - info = BookInfo.from_string(xml) - except: - return HttpResponseRedirect(os.path.join(settings.STATIC_URL, "img/sample_cover.png")) - cover = WLCover(info) - response = HttpResponse(mimetype=cover.mime_type()) - image = cover.image().resize(PREVIEW_SIZE, Image.ANTIALIAS) - image.save(response, cover.format) - return response - - -@csrf_exempt -@require_POST -def preview_from_xml(request): - from hashlib import sha1 - from PIL import Image - from os import makedirs - from lxml import etree - from librarian.cover import WLCover - from librarian.dcparser import BookInfo - - xml = request.POST['xml'] - try: - info = BookInfo.from_string(xml.encode('utf-8')) - except: - return HttpResponse(os.path.join(settings.STATIC_URL, "img/sample_cover.png")) - coverid = sha1(etree.tostring(info.to_etree())).hexdigest() - cover = WLCover(info) - - cover_dir = 'cover/preview' - try: - makedirs(os.path.join(settings.MEDIA_ROOT, cover_dir)) - except OSError: - pass - fname = os.path.join(cover_dir, "%s.%s" % (coverid, cover.ext())) - image = cover.image().resize(PREVIEW_SIZE, Image.ANTIALIAS) - image.save(os.path.join(settings.MEDIA_ROOT, fname)) - return HttpResponse(os.path.join(settings.MEDIA_URL, fname)) - - -@active_tab('cover') -def image(request, pk): - image = get_object_or_404(Image, pk=pk) - - if request.user.has_perm('cover.change_image'): - if request.method == "POST": - form = forms.ImageEditForm(request.POST, instance=image) - if form.is_valid(): - form.save() - return HttpResponseRedirect(image.get_absolute_url()) - else: - form = forms.ImageEditForm(instance=image) - editable = True - else: - form = forms.ReadonlyImageEditForm(instance=image) - editable = False - - return render(request, "cover/image_detail.html", { - "object": image, - "form": form, - "editable": editable, - }) - - -@active_tab('cover') -def image_list(request): - objects = Image.objects.all() - enable_add = request.user.has_perm('cover.add_image') - return render(request, "cover/image_list.html", { - 'object_list': Image.objects.all(), - 'can_add': request.user.has_perm('cover.add_image'), - }) - - -@permission_required('cover.add_image') -@active_tab('cover') -def add_image(request): - form = ff = None - if request.method == 'POST': - if request.POST.get('form_id') == 'flickr': - ff = forms.FlickrForm(request.POST) - if ff.is_valid(): - form = forms.ImageAddForm(ff.cleaned_data) - else: - form = forms.ImageAddForm(request.POST, request.FILES) - if form.is_valid(): - obj = form.save() - return HttpResponseRedirect(obj.get_absolute_url()) - if form is None: - form = forms.ImageAddForm() - if ff is None: - ff = forms.FlickrForm() - return render(request, 'cover/add_image.html', { - 'form': form, - 'ff': ff, - }) diff --git a/apps/dvcs/models.py b/apps/dvcs/models.py index 19e7d1e4..6ecb97ce 100644 --- a/apps/dvcs/models.py +++ b/apps/dvcs/models.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from __future__ import unicode_literals, print_function from datetime import datetime @@ -8,9 +13,7 @@ from tempfile import NamedTemporaryFile from django.conf import settings from django.core.files.base import ContentFile -from django.core.files.storage import FileSystemStorage -from django.db import models, transaction -from django.db.models.base import ModelBase +from django.db import models from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ @@ -31,32 +34,22 @@ class Revision(models.Model): Gzipped text of the document is stored in a file. """ - author = models.ForeignKey(settings.AUTH_USER_MODEL, - null=True, blank=True, verbose_name=_('author')) - author_name = models.CharField(_('author name'), max_length=128, - null=True, blank=True, - help_text=_("Used if author is not set.") - ) - author_email = models.CharField(_('author email'), max_length=128, - null=True, blank=True, - help_text=_("Used if author is not set.") - ) + author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, verbose_name=_('author')) + author_name = models.CharField( + _('author name'), max_length=128, null=True, blank=True, help_text=_("Used if author is not set.")) + author_email = models.CharField( + _('author email'), max_length=128, null=True, blank=True, help_text=_("Used if author is not set.")) # Any other author data? # How do we identify an author? - parent = models.ForeignKey('self', - null=True, blank=True, default=None, - verbose_name=_('parent'), - related_name="children") + parent = models.ForeignKey( + 'self', null=True, blank=True, default=None, verbose_name=_('parent'), related_name="children") - merge_parent = models.ForeignKey('self', - null=True, blank=True, default=None, - verbose_name=_('merge parent'), - related_name="merge_children") + merge_parent = models.ForeignKey( + 'self', null=True, blank=True, default=None, verbose_name=_('merge parent'), related_name="merge_children") description = models.TextField(_('description'), blank=True, default='') - created_at = models.DateTimeField(editable=False, db_index=True, - default=datetime.now) + created_at = models.DateTimeField(editable=False, db_index=True, default=datetime.now) class Meta: ordering = ('created_at',) @@ -68,7 +61,7 @@ class Revision(models.Model): def get_text_path(self): if self.pk: - return re.sub(r'([0-9a-f]{2})([^\.])', r'\1/\2', '%x.gz' % self.pk) + return re.sub(r'([0-9a-f]{2})([^.])', r'\1/\2', '%x.gz' % self.pk) else: return None @@ -88,9 +81,8 @@ class Revision(models.Model): ) @classmethod - def create(cls, text, parent=None, merge_parent=None, - author=None, author_name=None, author_email=None, - description=''): + def create(cls, text, parent=None, merge_parent=None, author=None, author_name=None, author_email=None, + description=''): if text: text = text.replace( @@ -168,15 +160,14 @@ class Revision(models.Model): revs.update(self.merge_parent.get_ancestors()) return revs + @python_2_unicode_compatible class Ref(models.Model): """A reference pointing to a specific revision.""" - revision = models.ForeignKey(Revision, - null=True, blank=True, default=None, - verbose_name=_('revision'), - help_text=_("The document's revision."), - editable=False) + revision = models.ForeignKey( + Revision, null=True, blank=True, default=None, verbose_name=_('revision'), + help_text=_("The document's revision."), editable=False) def __str__(self): return "ref:{0}->rev:{1}".format(self.id, self.revision_id) @@ -194,12 +185,9 @@ class Ref(models.Model): for f in files: os.unlink(f) - return result.decode('utf-8') - def merge_with(self, revision, - author=None, author_name=None, author_email=None, - description="Automatic merge."): + def merge_with(self, revision, author=None, author_name=None, author_email=None, description="Automatic merge."): """Merges a given revision into the ref.""" if self.revision is None: fast_forward = True @@ -238,17 +226,13 @@ class Ref(models.Model): def materialize(self): return self.revision.materialize() if self.revision is not None else '' - def commit(self, text, parent=False, - author=None, author_name=None, author_email=None, - description=''): + def commit(self, text, parent=False, author=None, author_name=None, author_email=None, description=''): """Creates a new revision and sets it as the ref. This will automatically merge the commit into the main branch, if parent is not document's head. :param unicode text: new version of the document - :param base: parent revision (head, if not specified) - :type base: Revision or None :param User author: the commiter :param unicode author_name: commiter name (if ``author`` not specified) :param unicode author_email: commiter e-mail (if ``author`` not specified) @@ -267,8 +251,7 @@ class Ref(models.Model): description=description, parent=parent ) - self.merge_with(rev, author=author, author_name=author_name, - author_email=author_email) + self.merge_with(rev, author=author, author_name=author_name, author_email=author_email) post_commit.send(sender=type(self), instance=self) diff --git a/apps/dvcs/signals.py b/apps/dvcs/signals.py index d71d655b..3aa87de7 100755 --- a/apps/dvcs/signals.py +++ b/apps/dvcs/signals.py @@ -1,6 +1,11 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from __future__ import unicode_literals from django.dispatch import Signal post_commit = Signal(providing_args=['instance']) -post_merge = Signal(providing_args=['fast_forward', 'instance']) \ No newline at end of file +post_merge = Signal(providing_args=['fast_forward', 'instance']) diff --git a/apps/dvcs/storage.py b/apps/dvcs/storage.py index 4bf292bc..080e7077 100755 --- a/apps/dvcs/storage.py +++ b/apps/dvcs/storage.py @@ -1,7 +1,11 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from __future__ import unicode_literals -import os -from django.core.files.base import ContentFile, File +from django.core.files.base import ContentFile from django.core.files.storage import FileSystemStorage try: @@ -35,4 +39,4 @@ class GzipFileSystemStorage(FileSystemStorage): def get_available_name(self, name): if self.exists(name): self.delete(name) - return name \ No newline at end of file + return name diff --git a/apps/dvcs/tests/__init__.py b/apps/dvcs/tests/__init__.py index 868f00a3..0d0a2882 100755 --- a/apps/dvcs/tests/__init__.py +++ b/apps/dvcs/tests/__init__.py @@ -1,178 +1,5 @@ -from nose.tools import * -from django.test import TestCase -from dvcs.models import Document - - -class ADocument(Document): - class Meta: - app_label = 'dvcs' - - -class DocumentModelTests(TestCase): - - def assertTextEqual(self, given, expected): - return self.assertEqual(given, expected, - "Expected '''%s'''\n differs from text: '''%s'''" % (expected, given) - ) - - def test_empty_file(self): - doc = ADocument.objects.create() - self.assertTextEqual(doc.materialize(), u"") - - def test_single_commit(self): - doc = ADocument.objects.create() - doc.commit(text=u"Ala ma kota", description="Commit #1") - self.assertTextEqual(doc.materialize(), u"Ala ma kota") - - def test_chained_commits(self): - doc = ADocument.objects.create() - text1 = u""" - Line #1 - Line #2 is cool - """ - text2 = u""" - Line #1 - Line #2 is hot - """ - text3 = u""" - Line #1 - ... is hot - Line #3 ate Line #2 - """ - - c1 = doc.commit(description="Commit #1", text=text1) - c2 = doc.commit(description="Commit #2", text=text2) - c3 = doc.commit(description="Commit #3", text=text3) - - self.assertTextEqual(doc.materialize(), text3) - self.assertTextEqual(doc.materialize(change=c3), text3) - self.assertTextEqual(doc.materialize(change=c2), text2) - self.assertTextEqual(doc.materialize(change=c1), text1) - - def test_parallel_commit_noconflict(self): - doc = ADocument.objects.create() - text1 = u""" - Line #1 - Line #2 - """ - text2 = u""" - Line #1 is hot - Line #2 - """ - text3 = u""" - Line #1 - Line #2 - Line #3 - """ - text_merged = u""" - Line #1 is hot - Line #2 - Line #3 - """ - - base = doc.commit(description="Commit #1", text=text1) - c1 = doc.commit(description="Commit #2", text=text2) - commits = doc.change_set.count() - c2 = doc.commit(description="Commit #3", text=text3, parent=base) - self.assertEqual(doc.change_set.count(), commits + 2, - u"Parallel commits should create an additional merge commit") - self.assertTextEqual(doc.materialize(), text_merged) - - def test_parallel_commit_conflict(self): - doc = ADocument.objects.create() - text1 = u""" - Line #1 - Line #2 - Line #3 - """ - text2 = u""" - Line #1 - Line #2 is hot - Line #3 - """ - text3 = u""" - Line #1 - Line #2 is cool - Line #3 - """ - text_merged = u""" - Line #1 -<<<<<<< - Line #2 is hot -======= - Line #2 is cool ->>>>>>> - Line #3 - """ - base = doc.commit(description="Commit #1", text=text1) - c1 = doc.commit(description="Commit #2", text=text2) - commits = doc.change_set.count() - c2 = doc.commit(description="Commit #3", text=text3, parent=base) - self.assertEqual(doc.change_set.count(), commits + 2, - u"Parallel commits should create an additional merge commit") - self.assertTextEqual(doc.materialize(), text_merged) - - - def test_multiple_parallel_commits(self): - text_a1 = u""" - Line #1 - - Line #2 - - Line #3 - """ - text_a2 = u""" - Line #1 * - - Line #2 - - Line #3 - """ - text_b1 = u""" - Line #1 - - Line #2 ** - - Line #3 - """ - text_c1 = u""" - Line #1 - - Line #2 - - Line #3 *** - """ - text_merged = u""" - Line #1 * - - Line #2 ** - - Line #3 *** - """ - - - doc = ADocument.objects.create() - c1 = doc.commit(description="Commit A1", text=text_a1) - c2 = doc.commit(description="Commit A2", text=text_a2, parent=c1) - c3 = doc.commit(description="Commit B1", text=text_b1, parent=c1) - c4 = doc.commit(description="Commit C1", text=text_c1, parent=c1) - self.assertTextEqual(doc.materialize(), text_merged) - - - def test_prepend_history(self): - doc1 = ADocument.objects.create() - doc2 = ADocument.objects.create() - doc1.commit(text='Commit 1') - doc2.commit(text='Commit 2') - doc2.prepend_history(doc1) - self.assertEqual(ADocument.objects.all().count(), 1) - self.assertTextEqual(doc2.at_revision(1).materialize(), 'Commit 1') - self.assertTextEqual(doc2.materialize(), 'Commit 2') - - def test_prepend_to_self(self): - doc = ADocument.objects.create() - doc.commit(text='Commit 1') - with self.assertRaises(AssertionError): - doc.prepend_history(doc) - self.assertTextEqual(doc.materialize(), 'Commit 1') - +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# diff --git a/apps/dvcs/version.py b/apps/dvcs/version.py index bb786ec5..729bd3d9 100644 --- a/apps/dvcs/version.py +++ b/apps/dvcs/version.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from __future__ import unicode_literals -VERSION='0.1' +VERSION = '0.1' diff --git a/apps/email_mangler/templatetags/email.py b/apps/email_mangler/templatetags/email.py index 376117a8..1d0080b6 100755 --- a/apps/email_mangler/templatetags/email.py +++ b/apps/email_mangler/templatetags/email.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django.utils.html import escape from django.utils.safestring import mark_safe from django.utils.translation import ugettext as _ @@ -17,7 +22,8 @@ def email_link(email): at = escape(_('at')) dot = escape(_('dot')) mangled = "%s %s %s" % (name, at, (' %s ' % dot).join(domain.split('.'))) - return mark_safe("<a class='mangled' data-addr1='%(name)s' " + return mark_safe( + "<a class='mangled' data-addr1='%(name)s' " "data-addr2='%(domain)s'>%(mangled)s</a>" % { 'name': name.encode('rot13'), 'domain': domain.encode('rot13'), diff --git a/apps/fileupload/forms.py b/apps/fileupload/forms.py index f5e10699..d4fbd49d 100644 --- a/apps/fileupload/forms.py +++ b/apps/fileupload/forms.py @@ -1,4 +1,10 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django import forms + class UploadForm(forms.Form): files = forms.FileField() diff --git a/apps/fileupload/models.py b/apps/fileupload/models.py deleted file mode 100644 index 8b137891..00000000 --- a/apps/fileupload/models.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/apps/fileupload/templatetags/upload_tags.py b/apps/fileupload/templatetags/upload_tags.py index aefce2e3..e49566fb 100644 --- a/apps/fileupload/templatetags/upload_tags.py +++ b/apps/fileupload/templatetags/upload_tags.py @@ -1,7 +1,13 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django import template register = template.Library() + @register.simple_tag def upload_js(): return """ @@ -13,10 +19,13 @@ def upload_js(): <td class="name"><span>{%=file.name%}</span></td> <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td> {% if (file.error) { %} - <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td> + <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> + {%=locale.fileupload.errors[file.error] || file.error%}</td> {% } else if (o.files.valid && !i) { %} <td> - <div class="progress progress-success progress-striped active"><div class="bar" style="width:0%;"></div></div> + <div class="progress progress-success progress-striped active"> + <div class="bar" style="width:0%;"></div> + </div> </td> <td class="start">{% if (!o.options.autoUpload) { %} <button class="btn btn-success"> @@ -44,13 +53,16 @@ def upload_js(): <td></td> <td class="name"><span>{%=file.name%}</span></td> <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td> - <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td> + <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> + {%=locale.fileupload.errors[file.error] || file.error%}</td> {% } else { %} <td class="preview">{% if (file.thumbnail_url) { %} - <a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a> + <a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" + download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a> {% } %}</td> <td class="name"> - <a href="{%=file.url%}" title="{%=file.name%}" rel="{%=file.thumbnail_url&&'gallery'%}" download="{%=file.name%}">{%=file.name%}</a> + <a href="{%=file.url%}" title="{%=file.name%}" rel="{%=file.thumbnail_url&&'gallery'%}" + download="{%=file.name%}">{%=file.name%}</a> </td> <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td> <td colspan="2"></td> diff --git a/apps/fileupload/urls.py b/apps/fileupload/urls.py index cd4f46c3..68bdc482 100644 --- a/apps/fileupload/urls.py +++ b/apps/fileupload/urls.py @@ -1,7 +1,12 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django.conf.urls import patterns, url from fileupload.views import UploadView -urlpatterns = patterns('', +urlpatterns = patterns( + '', url(r'^(?P<path>(?:.*/)?)$', UploadView.as_view(), name='fileupload'), ) - diff --git a/apps/fileupload/views.py b/apps/fileupload/views.py index de2532f4..89ccf081 100644 --- a/apps/fileupload/views.py +++ b/apps/fileupload/views.py @@ -1,12 +1,16 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# import json import os -from zipfile import ZipFile from urllib import quote from django.conf import settings -from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404 +from django.http import HttpResponse, Http404 from django.utils.decorators import method_decorator from django.views.decorators.vary import vary_on_headers -from django.views.generic import FormView, View, RedirectView +from django.views.generic import FormView from .forms import UploadForm @@ -31,6 +35,7 @@ class JSONResponse(HttpResponse): content = json.dumps(obj) super(JSONResponse, self).__init__(content, mimetype, *args, **kwargs) + class UploadViewMixin(object): def get_safe_path(self, filename=""): """Finds absolute filesystem path of the browsed dir of file. @@ -49,6 +54,7 @@ class UploadViewMixin(object): raise Http404 return path + class UploadView(UploadViewMixin, FormView): template_name = "fileupload/picture_form.html" form_class = UploadForm @@ -78,7 +84,7 @@ class UploadView(UploadViewMixin, FormView): directory = os.path.dirname(directory) now_path = (os.path.dirname(now_path)) while directory: - crumbs.insert(0, (os.path.basename(directory), now_path+'/')) + crumbs.insert(0, (os.path.basename(directory), now_path + '/')) directory = os.path.dirname(directory) now_path = os.path.dirname(now_path) crumbs.insert(0, ('media', now_path)) @@ -117,7 +123,6 @@ class UploadView(UploadViewMixin, FormView): quote(f.encode('utf-8'))), 'delete_type': "DELETE" }) - thumbnail_url = thumbnail(self.get_directory() + f), files.append(file_info) return JSONResponse(files) else: @@ -137,9 +142,9 @@ class UploadView(UploadViewMixin, FormView): 'name': f.name, 'url': self.get_url(f.name), 'thumbnail_url': thumbnail(self.get_directory() + f.name), - 'delete_url': "%s?file=%s" % ( - self.request.get_full_path(), - quote(f.name.encode('utf-8'))), + 'delete_url': "%s?file=%s" % ( + self.request.get_full_path(), + quote(f.name.encode('utf-8'))), 'delete_type': "DELETE" }) response = JSONResponse(data) @@ -151,15 +156,3 @@ class UploadView(UploadViewMixin, FormView): response = JSONResponse(True) response['Content-Disposition'] = 'inline; filename=files.json' return response - - -class PackageView(UploadViewMixin, RedirectView): - def dispatch(self, request, *args, **kwargs): - self.object = self.get_object(request, *args, **kwargs) - path = self.get_safe_path() - with ZipFile(os.path.join(path, 'package.zip'), 'w') as zip_file: - for f in os.listdir(path): - if f == 'package.zip': - continue - zip_file.write(os.path.join(path, f), arcname = f) - return super(PackageView, self).dispatch(request, *args, **kwargs) diff --git a/apps/organizations/admin.py b/apps/organizations/admin.py index 31f36ea3..60aa7f1c 100644 --- a/apps/organizations/admin.py +++ b/apps/organizations/admin.py @@ -1,6 +1,10 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django.contrib import admin from organizations import models admin.site.register(models.Organization) - diff --git a/apps/organizations/forms.py b/apps/organizations/forms.py index 63f9c028..63984486 100644 --- a/apps/organizations/forms.py +++ b/apps/organizations/forms.py @@ -1,6 +1,12 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django import forms from .models import Organization, UserCard, countries + class OrganizationForm(forms.ModelForm): cts = countries @@ -8,6 +14,7 @@ class OrganizationForm(forms.ModelForm): model = Organization exclude = ['_html'] + class UserCardForm(forms.ModelForm): cts = countries @@ -24,11 +31,10 @@ class UserCardForm(forms.ModelForm): 'first_name': kwargs['instance'].user.first_name, 'last_name': kwargs['instance'].user.last_name, } - return super(UserCardForm, self).__init__(*args, **kwargs) + super(UserCardForm, self).__init__(*args, **kwargs) def save(self, *args, **kwargs): self.instance.user.first_name = self.cleaned_data.get('first_name', '') self.instance.user.last_name = self.cleaned_data.get('last_name', '') self.instance.user.save() return super(UserCardForm, self).save(*args, **kwargs) - diff --git a/apps/organizations/templatetags/urlinfo.py b/apps/organizations/templatetags/urlinfo.py index 33d61c6b..0b59b990 100644 --- a/apps/organizations/templatetags/urlinfo.py +++ b/apps/organizations/templatetags/urlinfo.py @@ -1,8 +1,14 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django import template from embeder import embed register = template.Library() + @register.assignment_tag def urlinfo(url): try: diff --git a/apps/organizations/urls.py b/apps/organizations/urls.py index 7c2605fc..33945f16 100644 --- a/apps/organizations/urls.py +++ b/apps/organizations/urls.py @@ -3,7 +3,8 @@ from django.conf.urls import patterns, url from organizations import views -urlpatterns = patterns('', +urlpatterns = patterns( + '', url(r'^$', views.organizations, name="organizations"), url(r'^new/$', views.org_new, name="organizations_new"), url(r'^(?P<pk>\d+)/$', views.main, name="organizations_main"), diff --git a/apps/organizations/views.py b/apps/organizations/views.py index a7d69802..24f2436f 100644 --- a/apps/organizations/views.py +++ b/apps/organizations/views.py @@ -1,12 +1,16 @@ -# Create your views here. +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from django.shortcuts import render, redirect -from django.http import HttpResponse, Http404 -#from django.views.decorators import require_post +from django.http import Http404 from .forms import OrganizationForm, UserCardForm from .models import Organization, Membership, UserCard + @login_required def org_new(request): if request.method == 'POST': @@ -38,6 +42,7 @@ def main(request, pk, tab='documents'): 'am_member': am_member, }) + def user_card(request, pk): try: user = User.objects.get(pk=pk) @@ -92,8 +97,8 @@ def join(request, pk): return render(request, 'organizations/join.html', {'org': org}) + @login_required -#@POST_required def membership(request, pk): try: org = Organization.objects.get(pk=pk) diff --git a/apps/wiki/forms.py b/apps/wiki/forms.py index bee0e192..7ef02e15 100644 --- a/apps/wiki/forms.py +++ b/apps/wiki/forms.py @@ -6,7 +6,6 @@ from django import forms from django.utils.translation import ugettext_lazy as _ -from catalogue.models import Document from catalogue.constants import STAGES @@ -43,7 +42,7 @@ class DocumentTextSaveForm(forms.Form): ) stage = forms.ChoiceField( - choices = [(s, s) for s in STAGES], + choices=[(s, s) for s in STAGES], required=False, label=_(u"Stage"), help_text=_(u"If completed a work stage, change to another one."), @@ -51,11 +50,10 @@ class DocumentTextSaveForm(forms.Form): def __init__(self, *args, **kwargs): user = kwargs.pop('user') - r = super(DocumentTextSaveForm, self).__init__(*args, **kwargs) + super(DocumentTextSaveForm, self).__init__(*args, **kwargs) if user and user.is_authenticated(): self.fields['author_name'].required = False self.fields['author_email'].required = False - return r class DocumentTextRevertForm(forms.Form): diff --git a/apps/wiki/helpers.py b/apps/wiki/helpers.py index 4ff7bc6e..b60265f5 100644 --- a/apps/wiki/helpers.py +++ b/apps/wiki/helpers.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from datetime import datetime from functools import wraps import json diff --git a/apps/wiki/models.py b/apps/wiki/models.py deleted file mode 100644 index e69de29b..00000000 diff --git a/apps/wiki/nice_diff.py b/apps/wiki/nice_diff.py index b228fad9..19ad602c 100644 --- a/apps/wiki/nice_diff.py +++ b/apps/wiki/nice_diff.py @@ -19,11 +19,11 @@ def diff_replace(match): def filter_line(line): - return DIFF_RE.sub(diff_replace, html_escape(line)).replace('\x01', '</span>') + return DIFF_RE.sub(diff_replace, html_escape(line)).replace('\x01', '</span>') def format_changeset(a, b, change): - return (a[0], filter_line(a[1]), b[0], filter_line(b[1]), change) + return a[0], filter_line(a[1]), b[0], filter_line(b[1]), change def html_diff_table(la, lb, context=None): diff --git a/apps/wiki/settings.py b/apps/wiki/settings.py index 50f49d8b..3752034d 100644 --- a/apps/wiki/settings.py +++ b/apps/wiki/settings.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django.conf import settings GALLERY_URL = settings.MEDIA_URL + 'images/' diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/common.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/common.js deleted file mode 100644 index 785c2a20..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/common.js +++ /dev/null @@ -1,201 +0,0 @@ -/* record log messages for testing */ -// var logAllIds = function() { -// var allTags = document.head.getElementsByTagName('style'); -// var ids = []; -// for (var tg = 0; tg < allTags.length; tg++) { -// var tag = allTags[tg]; -// if (tag.id) { -// console.log(tag.id); -// } -// } -// }; - -var logMessages = [], - realConsoleLog = console.log; -console.log = function(msg) { - logMessages.push(msg); - realConsoleLog.call(console, msg); -}; - -var testLessEqualsInDocument = function() { - testLessInDocument(testSheet); -}; - -var testLessErrorsInDocument = function(isConsole) { - testLessInDocument(isConsole ? testErrorSheetConsole : testErrorSheet); -}; - -var testLessInDocument = function(testFunc) { - var links = document.getElementsByTagName('link'), - typePattern = /^text\/(x-)?less$/; - - for (var i = 0; i < links.length; i++) { - if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) && - (links[i].type.match(typePattern)))) { - testFunc(links[i]); - } - } -}; - -var testSheet = function(sheet) { - it(sheet.id + " should match the expected output", function() { - var lessOutputId = sheet.id.replace("original-", ""), - expectedOutputId = "expected-" + lessOutputId, - lessOutputObj, - lessOutput, - expectedOutputHref = document.getElementById(expectedOutputId).href, - expectedOutput = loadFile(expectedOutputHref); - - // Browser spec generates less on the fly, so we need to loose control - waitsFor(function() { - lessOutputObj = document.getElementById(lessOutputId); - // the type condition is necessary because of inline browser tests - return lessOutputObj !== null && lessOutputObj.type === "text/css"; - }, "generation of " + lessOutputId + "", 700); - - runs(function() { - lessOutput = lessOutputObj.innerText; - }); - - waitsFor(function() { - return expectedOutput.loaded; - }, "failed to load expected outout", 10000); - - runs(function() { - // use sheet to do testing - expect(expectedOutput.text).toEqual(lessOutput); - }); - }); -}; - -//TODO: do it cleaner - the same way as in css - -function extractId(href) { - return href.replace(/^[a-z-]+:\/+?[^\/]+/, '') // Remove protocol & domain - .replace(/^\//, '') // Remove root / - .replace(/\.[a-zA-Z]+$/, '') // Remove simple extension - .replace(/[^\.\w-]+/g, '-') // Replace illegal characters - .replace(/\./g, ':'); // Replace dots with colons(for valid id) -} - -var testErrorSheet = function(sheet) { - it(sheet.id + " should match an error", function() { - var lessHref = sheet.href, - id = "less-error-message:" + extractId(lessHref), - // id = sheet.id.replace(/^original-less:/, "less-error-message:"), - errorHref = lessHref.replace(/.less$/, ".txt"), - errorFile = loadFile(errorHref), - actualErrorElement, - actualErrorMsg; - - // Less.js sets 10ms timer in order to add error message on top of page. - waitsFor(function() { - actualErrorElement = document.getElementById(id); - return actualErrorElement !== null; - }, "error message was not generated", 70); - - runs(function() { - actualErrorMsg = actualErrorElement.innerText - .replace(/\n\d+/g, function(lineNo) { - return lineNo + " "; - }) - .replace(/\n\s*in /g, " in ") - .replace("\n\n", "\n"); - }); - - waitsFor(function() { - return errorFile.loaded; - }, "failed to load expected outout", 10000); - - runs(function() { - var errorTxt = errorFile.text - .replace("{path}", "") - .replace("{pathrel}", "") - .replace("{pathhref}", "http://localhost:8081/test/less/errors/") - .replace("{404status}", " (404)"); - expect(errorTxt).toEqual(actualErrorMsg); - if (errorTxt == actualErrorMsg) { - actualErrorElement.style.display = "none"; - } - }); - }); -}; - -var testErrorSheetConsole = function(sheet) { - it(sheet.id + " should match an error", function() { - var lessHref = sheet.href, - id = sheet.id.replace(/^original-less:/, "less-error-message:"), - errorHref = lessHref.replace(/.less$/, ".txt"), - errorFile = loadFile(errorHref), - actualErrorElement = document.getElementById(id), - actualErrorMsg = logMessages[logMessages.length - 1]; - - describe("the error", function() { - expect(actualErrorElement).toBe(null); - - }); - - /*actualErrorMsg = actualErrorElement.innerText - .replace(/\n\d+/g, function(lineNo) { return lineNo + " "; }) - .replace(/\n\s*in /g, " in ") - .replace("\n\n", "\n");*/ - - waitsFor(function() { - return errorFile.loaded; - }, "failed to load expected outout", 10000); - - runs(function() { - var errorTxt = errorFile.text - .replace("{path}", "") - .replace("{pathrel}", "") - .replace("{pathhref}", "http://localhost:8081/browser/less/") - .replace("{404status}", " (404)") - .trim(); - expect(errorTxt).toEqual(actualErrorMsg); - }); - }); -}; - -var loadFile = function(href) { - var request = new XMLHttpRequest(), - response = { - loaded: false, - text: "" - }; - request.open('GET', href, true); - request.onload = function(e) { - response.text = request.response.replace(/\r/g, ""); - response.loaded = true; - }; - request.send(); - return response; -}; - -(function() { - var jasmineEnv = jasmine.getEnv(); - jasmineEnv.updateInterval = 1000; - - var htmlReporter = new jasmine.HtmlReporter(); - - jasmineEnv.addReporter(htmlReporter); - - jasmineEnv.specFilter = function(spec) { - return htmlReporter.specFilter(spec); - }; - - var currentWindowOnload = window.onload; - - window.onload = function() { - if (currentWindowOnload) { - currentWindowOnload(); - } - execJasmine(); - }; - - function execJasmine() { - setTimeout(function() { - jasmineEnv.execute(); - }, 3000); - } - -})(); \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/global-vars/simple.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/global-vars/simple.css deleted file mode 100644 index 05b9fb02..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/global-vars/simple.css +++ /dev/null @@ -1,3 +0,0 @@ -.test { - color: #ff0000; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/modify-vars/simple.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/modify-vars/simple.css deleted file mode 100644 index 4cb81bac..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/modify-vars/simple.css +++ /dev/null @@ -1,7 +0,0 @@ -.testisimported { - color: gainsboro; -} -.test { - color1: #008000; - color2: #800080; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/relative-urls/urls.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/relative-urls/urls.css deleted file mode 100644 index cd83a824..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/relative-urls/urls.css +++ /dev/null @@ -1,34 +0,0 @@ -@import "http://localhost:8081/test/browser/less/imports/modify-this.css"; -@import "http://localhost:8081/test/browser/less/imports/modify-again.css"; -.modify { - my-url: url("http://localhost:8081/test/browser/less/imports/a.png"); -} -.modify { - my-url: url("http://localhost:8081/test/browser/less/imports/b.png"); -} -@font-face { - src: local(Futura-Medium), url(http://localhost:8081/test/browser/less/relative-urls/fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -#misc { - background-image: url(http://localhost:8081/test/browser/less/relative-urls/images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} -#svg-data-uri { - background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>'); -} -.comma-delimited { - background: url(http://localhost:8081/test/browser/less/relative-urls/bg.jpg) no-repeat, url(http://localhost:8081/test/browser/less/relative-urls/bg.png) repeat-x top left, url(http://localhost:8081/test/browser/less/relative-urls/bg); -} -.values { - url: url('http://localhost:8081/test/browser/less/relative-urls/Trebuchet'); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/rootpath-relative/urls.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/rootpath-relative/urls.css deleted file mode 100644 index d9752d4f..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/rootpath-relative/urls.css +++ /dev/null @@ -1,34 +0,0 @@ -@import "https://www.github.com/cloudhead/imports/modify-this.css"; -@import "https://www.github.com/cloudhead/imports/modify-again.css"; -.modify { - my-url: url("https://www.github.com/cloudhead/imports/a.png"); -} -.modify { - my-url: url("https://www.github.com/cloudhead/imports/b.png"); -} -@font-face { - src: local(Futura-Medium), url(https://www.github.com/cloudhead/less.js/fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -#misc { - background-image: url(https://www.github.com/cloudhead/less.js/images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} -#svg-data-uri { - background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>'); -} -.comma-delimited { - background: url(https://www.github.com/cloudhead/less.js/bg.jpg) no-repeat, url(https://www.github.com/cloudhead/less.js/bg.png) repeat-x top left, url(https://www.github.com/cloudhead/less.js/bg); -} -.values { - url: url('https://www.github.com/cloudhead/less.js/Trebuchet'); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/rootpath/urls.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/rootpath/urls.css deleted file mode 100644 index 0ca84f0d..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/rootpath/urls.css +++ /dev/null @@ -1,31 +0,0 @@ -/*@import "https://www.github.com/modify-this.css";*/ -/*@import "https://www.github.com/modify-again.css";*/ -.modify { - my-url: url("https://www.github.com/a.png"); -} -.modify { - my-url: url("https://www.github.com/b.png"); -} -@font-face { - src: local(Futura-Medium), url(https://www.github.com/fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -#misc { - background-image: url(https://www.github.com/images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64,kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ukg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} -#svg-data-uri { - background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>'); -} -.comma-delimited { - background: url(https://www.github.com/bg.jpg) no-repeat, url(https://www.github.com/bg.png) repeat-x top left, url(https://www.github.com/bg); -} -.values { - url: url('https://www.github.com/Trebuchet'); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/urls.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/urls.css deleted file mode 100644 index 489d979b..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/css/urls.css +++ /dev/null @@ -1,49 +0,0 @@ -/*@import "http://localhost:8081/test/browser/less/modify-this.css";*/ -/*@import "http://localhost:8081/test/browser/less/modify-again.css";*/ -.modify { - my-url: url("http://localhost:8081/test/browser/less/a.png"); -} -.modify { - my-url: url("http://localhost:8081/test/browser/less/b.png"); -} -@font-face { - src: local(Futura-Medium), url(http://localhost:8081/test/browser/less/fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -#misc { - background-image: url(http://localhost:8081/test/browser/less/images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64,kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ukg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} -#svg-data-uri { - background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>'); -} -.comma-delimited { - background: url(http://localhost:8081/test/browser/less/bg.jpg) no-repeat, url(http://localhost:8081/test/browser/less/bg.png) repeat-x top left, url(http://localhost:8081/test/browser/less/bg); -} -.values { - url: url('http://localhost:8081/test/browser/less/Trebuchet'); -} -#data-uri { - uri: url('http://localhost:8081/test/data/image.jpg'); -} -#data-uri-guess { - uri: url('http://localhost:8081/test/data/image.jpg'); -} -#data-uri-ascii { - uri-1: url('http://localhost:8081/test/data/page.html'); - uri-2: url('http://localhost:8081/test/data/page.html'); -} -#data-uri-toobig { - uri: url('http://localhost:8081/test/data/data-uri-fail.png'); -} -#svg-functions { - background-image: url('data:image/svg+xml,<?xml version="1.0" ?><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none"><linearGradient id="gradient" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" stop-color="#000000"/><stop offset="100%" stop-color="#ffffff"/></linearGradient><rect x="0" y="0" width="1" height="1" fill="url(#gradient)" /></svg>'); - background-image: url('data:image/svg+xml,<?xml version="1.0" ?><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none"><linearGradient id="gradient" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" stop-color="#000000"/><stop offset="3%" stop-color="#ffa500"/><stop offset="100%" stop-color="#ffffff"/></linearGradient><rect x="0" y="0" width="1" height="1" fill="url(#gradient)" /></svg>'); - background-image: url('data:image/svg+xml,<?xml version="1.0" ?><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none"><linearGradient id="gradient" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="1%" stop-color="#c4c4c4"/><stop offset="3%" stop-color="#ffa500"/><stop offset="5%" stop-color="#008000"/><stop offset="95%" stop-color="#ffffff"/></linearGradient><rect x="0" y="0" width="1" height="1" fill="url(#gradient)" /></svg>'); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/es5.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/es5.js deleted file mode 100644 index c4fcc802..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/es5.js +++ /dev/null @@ -1,27 +0,0 @@ -/* - PhantomJS does not implement bind. this is from - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind - */ -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== "function") { - // closest thing possible to the ECMAScript 5 internal IsCallable function - throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); - } - - var aArgs = Array.prototype.slice.call(arguments, 1), - fToBind = this, - fNOP = function () {}, - fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis - ? this - : oThis, - aArgs.concat(Array.prototype.slice.call(arguments))); - }; - - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - - return fBound; - }; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/jasmine-html.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/jasmine-html.js deleted file mode 100644 index 543d5696..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/jasmine-html.js +++ /dev/null @@ -1,681 +0,0 @@ -jasmine.HtmlReporterHelpers = {}; - -jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) { - var el = document.createElement(type); - - for (var i = 2; i < arguments.length; i++) { - var child = arguments[i]; - - if (typeof child === 'string') { - el.appendChild(document.createTextNode(child)); - } else { - if (child) { - el.appendChild(child); - } - } - } - - for (var attr in attrs) { - if (attr == "className") { - el[attr] = attrs[attr]; - } else { - el.setAttribute(attr, attrs[attr]); - } - } - - return el; -}; - -jasmine.HtmlReporterHelpers.getSpecStatus = function(child) { - var results = child.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.skipped) { - status = 'skipped'; - } - - return status; -}; - -jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) { - var parentDiv = this.dom.summary; - var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite'; - var parent = child[parentSuite]; - - if (parent) { - if (typeof this.views.suites[parent.id] == 'undefined') { - this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views); - } - parentDiv = this.views.suites[parent.id].element; - } - - parentDiv.appendChild(childElement); -}; - - -jasmine.HtmlReporterHelpers.addHelpers = function(ctor) { - for(var fn in jasmine.HtmlReporterHelpers) { - ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn]; - } -}; - -jasmine.HtmlReporter = function(_doc) { - var self = this; - var doc = _doc || window.document; - - var reporterView; - - var dom = {}; - - // Jasmine Reporter Public Interface - self.logRunningSpecs = false; - - self.reportRunnerStarting = function(runner) { - var specs = runner.specs() || []; - - if (specs.length == 0) { - return; - } - - createReporterDom(runner.env.versionString()); - doc.body.appendChild(dom.reporter); - setExceptionHandling(); - - reporterView = new jasmine.HtmlReporter.ReporterView(dom); - reporterView.addSpecs(specs, self.specFilter); - }; - - self.reportRunnerResults = function(runner) { - reporterView && reporterView.complete(); - }; - - self.reportSuiteResults = function(suite) { - reporterView.suiteComplete(suite); - }; - - self.reportSpecStarting = function(spec) { - if (self.logRunningSpecs) { - self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); - } - }; - - self.reportSpecResults = function(spec) { - reporterView.specComplete(spec); - }; - - self.log = function() { - var console = jasmine.getGlobal().console; - if (console && console.log) { - if (console.log.apply) { - console.log.apply(console, arguments); - } else { - console.log(arguments); // ie fix: console.log.apply doesn't exist on ie - } - } - }; - - self.specFilter = function(spec) { - if (!focusedSpecName()) { - return true; - } - - return spec.getFullName().indexOf(focusedSpecName()) === 0; - }; - - return self; - - function focusedSpecName() { - var specName; - - (function memoizeFocusedSpec() { - if (specName) { - return; - } - - var paramMap = []; - var params = jasmine.HtmlReporter.parameters(doc); - - for (var i = 0; i < params.length; i++) { - var p = params[i].split('='); - paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); - } - - specName = paramMap.spec; - })(); - - return specName; - } - - function createReporterDom(version) { - dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' }, - dom.banner = self.createDom('div', { className: 'banner' }, - self.createDom('span', { className: 'title' }, "Jasmine "), - self.createDom('span', { className: 'version' }, version)), - - dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}), - dom.alert = self.createDom('div', {className: 'alert'}, - self.createDom('span', { className: 'exceptions' }, - self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'), - self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))), - dom.results = self.createDom('div', {className: 'results'}, - dom.summary = self.createDom('div', { className: 'summary' }), - dom.details = self.createDom('div', { id: 'details' })) - ); - } - - function noTryCatch() { - return window.location.search.match(/catch=false/); - } - - function searchWithCatch() { - var params = jasmine.HtmlReporter.parameters(window.document); - var removed = false; - var i = 0; - - while (!removed && i < params.length) { - if (params[i].match(/catch=/)) { - params.splice(i, 1); - removed = true; - } - i++; - } - if (jasmine.CATCH_EXCEPTIONS) { - params.push("catch=false"); - } - - return params.join("&"); - } - - function setExceptionHandling() { - var chxCatch = document.getElementById('no_try_catch'); - - if (noTryCatch()) { - chxCatch.setAttribute('checked', true); - jasmine.CATCH_EXCEPTIONS = false; - } - chxCatch.onclick = function() { - window.location.search = searchWithCatch(); - }; - } -}; -jasmine.HtmlReporter.parameters = function(doc) { - var paramStr = doc.location.search.substring(1); - var params = []; - - if (paramStr.length > 0) { - params = paramStr.split('&'); - } - return params; -} -jasmine.HtmlReporter.sectionLink = function(sectionName) { - var link = '?'; - var params = []; - - if (sectionName) { - params.push('spec=' + encodeURIComponent(sectionName)); - } - if (!jasmine.CATCH_EXCEPTIONS) { - params.push("catch=false"); - } - if (params.length > 0) { - link += params.join("&"); - } - - return link; -}; -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter); -jasmine.HtmlReporter.ReporterView = function(dom) { - this.startedAt = new Date(); - this.runningSpecCount = 0; - this.completeSpecCount = 0; - this.passedCount = 0; - this.failedCount = 0; - this.skippedCount = 0; - - this.createResultsMenu = function() { - this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'}, - this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'), - ' | ', - this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing')); - - this.summaryMenuItem.onclick = function() { - dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, ''); - }; - - this.detailsMenuItem.onclick = function() { - showDetails(); - }; - }; - - this.addSpecs = function(specs, specFilter) { - this.totalSpecCount = specs.length; - - this.views = { - specs: {}, - suites: {} - }; - - for (var i = 0; i < specs.length; i++) { - var spec = specs[i]; - this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views); - if (specFilter(spec)) { - this.runningSpecCount++; - } - } - }; - - this.specComplete = function(spec) { - this.completeSpecCount++; - - if (isUndefined(this.views.specs[spec.id])) { - this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom); - } - - var specView = this.views.specs[spec.id]; - - switch (specView.status()) { - case 'passed': - this.passedCount++; - break; - - case 'failed': - this.failedCount++; - break; - - case 'skipped': - this.skippedCount++; - break; - } - - specView.refresh(); - this.refresh(); - }; - - this.suiteComplete = function(suite) { - var suiteView = this.views.suites[suite.id]; - if (isUndefined(suiteView)) { - return; - } - suiteView.refresh(); - }; - - this.refresh = function() { - - if (isUndefined(this.resultsMenu)) { - this.createResultsMenu(); - } - - // currently running UI - if (isUndefined(this.runningAlert)) { - this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" }); - dom.alert.appendChild(this.runningAlert); - } - this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount); - - // skipped specs UI - if (isUndefined(this.skippedAlert)) { - this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" }); - } - - this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all"; - - if (this.skippedCount === 1 && isDefined(dom.alert)) { - dom.alert.appendChild(this.skippedAlert); - } - - // passing specs UI - if (isUndefined(this.passedAlert)) { - this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" }); - } - this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount); - - // failing specs UI - if (isUndefined(this.failedAlert)) { - this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"}); - } - this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount); - - if (this.failedCount === 1 && isDefined(dom.alert)) { - dom.alert.appendChild(this.failedAlert); - dom.alert.appendChild(this.resultsMenu); - } - - // summary info - this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount); - this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing"; - }; - - this.complete = function() { - dom.alert.removeChild(this.runningAlert); - - this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all"; - - if (this.failedCount === 0) { - dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount))); - } else { - showDetails(); - } - - dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s")); - }; - - return this; - - function showDetails() { - if (dom.reporter.className.search(/showDetails/) === -1) { - dom.reporter.className += " showDetails"; - } - } - - function isUndefined(obj) { - return typeof obj === 'undefined'; - } - - function isDefined(obj) { - return !isUndefined(obj); - } - - function specPluralizedFor(count) { - var str = count + " spec"; - if (count > 1) { - str += "s" - } - return str; - } - -}; - -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView); - - -jasmine.HtmlReporter.SpecView = function(spec, dom, views) { - this.spec = spec; - this.dom = dom; - this.views = views; - - this.symbol = this.createDom('li', { className: 'pending' }); - this.dom.symbolSummary.appendChild(this.symbol); - - this.summary = this.createDom('div', { className: 'specSummary' }, - this.createDom('a', { - className: 'description', - href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()), - title: this.spec.getFullName() - }, this.spec.description) - ); - - this.detail = this.createDom('div', { className: 'specDetail' }, - this.createDom('a', { - className: 'description', - href: '?spec=' + encodeURIComponent(this.spec.getFullName()), - title: this.spec.getFullName() - }, this.spec.getFullName()) - ); -}; - -jasmine.HtmlReporter.SpecView.prototype.status = function() { - return this.getSpecStatus(this.spec); -}; - -jasmine.HtmlReporter.SpecView.prototype.refresh = function() { - this.symbol.className = this.status(); - - switch (this.status()) { - case 'skipped': - break; - - case 'passed': - this.appendSummaryToSuiteDiv(); - break; - - case 'failed': - this.appendSummaryToSuiteDiv(); - this.appendFailureDetail(); - break; - } -}; - -jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() { - this.summary.className += ' ' + this.status(); - this.appendToSummary(this.spec, this.summary); -}; - -jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() { - this.detail.className += ' ' + this.status(); - - var resultItems = this.spec.results().getItems(); - var messagesDiv = this.createDom('div', { className: 'messages' }); - - for (var i = 0; i < resultItems.length; i++) { - var result = resultItems[i]; - - if (result.type == 'log') { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); - } else if (result.type == 'expect' && result.passed && !result.passed()) { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); - - if (result.trace.stack) { - messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); - } - } - } - - if (messagesDiv.childNodes.length > 0) { - this.detail.appendChild(messagesDiv); - this.dom.details.appendChild(this.detail); - } -}; - -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) { - this.suite = suite; - this.dom = dom; - this.views = views; - - this.element = this.createDom('div', { className: 'suite' }, - this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description) - ); - - this.appendToSummary(this.suite, this.element); -}; - -jasmine.HtmlReporter.SuiteView.prototype.status = function() { - return this.getSpecStatus(this.suite); -}; - -jasmine.HtmlReporter.SuiteView.prototype.refresh = function() { - this.element.className += " " + this.status(); -}; - -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView); - -/* @deprecated Use jasmine.HtmlReporter instead - */ -jasmine.TrivialReporter = function(doc) { - this.document = doc || document; - this.suiteDivs = {}; - this.logRunningSpecs = false; -}; - -jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) { - var el = document.createElement(type); - - for (var i = 2; i < arguments.length; i++) { - var child = arguments[i]; - - if (typeof child === 'string') { - el.appendChild(document.createTextNode(child)); - } else { - if (child) { el.appendChild(child); } - } - } - - for (var attr in attrs) { - if (attr == "className") { - el[attr] = attrs[attr]; - } else { - el.setAttribute(attr, attrs[attr]); - } - } - - return el; -}; - -jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) { - var showPassed, showSkipped; - - this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' }, - this.createDom('div', { className: 'banner' }, - this.createDom('div', { className: 'logo' }, - this.createDom('span', { className: 'title' }, "Jasmine"), - this.createDom('span', { className: 'version' }, runner.env.versionString())), - this.createDom('div', { className: 'options' }, - "Show ", - showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "), - showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped") - ) - ), - - this.runnerDiv = this.createDom('div', { className: 'runner running' }, - this.createDom('a', { className: 'run_spec', href: '?' }, "run all"), - this.runnerMessageSpan = this.createDom('span', {}, "Running..."), - this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, "")) - ); - - this.document.body.appendChild(this.outerDiv); - - var suites = runner.suites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - var suiteDiv = this.createDom('div', { className: 'suite' }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"), - this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description)); - this.suiteDivs[suite.id] = suiteDiv; - var parentDiv = this.outerDiv; - if (suite.parentSuite) { - parentDiv = this.suiteDivs[suite.parentSuite.id]; - } - parentDiv.appendChild(suiteDiv); - } - - this.startedAt = new Date(); - - var self = this; - showPassed.onclick = function(evt) { - if (showPassed.checked) { - self.outerDiv.className += ' show-passed'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); - } - }; - - showSkipped.onclick = function(evt) { - if (showSkipped.checked) { - self.outerDiv.className += ' show-skipped'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); - } - }; -}; - -jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) { - var results = runner.results(); - var className = (results.failedCount > 0) ? "runner failed" : "runner passed"; - this.runnerDiv.setAttribute("class", className); - //do it twice for IE - this.runnerDiv.setAttribute("className", className); - var specs = runner.specs(); - var specCount = 0; - for (var i = 0; i < specs.length; i++) { - if (this.specFilter(specs[i])) { - specCount++; - } - } - var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s"); - message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"; - this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild); - - this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString())); -}; - -jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { - var results = suite.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.totalCount === 0) { // todo: change this to check results.skipped - status = 'skipped'; - } - this.suiteDivs[suite.id].className += " " + status; -}; - -jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) { - if (this.logRunningSpecs) { - this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); - } -}; - -jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) { - var results = spec.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.skipped) { - status = 'skipped'; - } - var specDiv = this.createDom('div', { className: 'spec ' + status }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"), - this.createDom('a', { - className: 'description', - href: '?spec=' + encodeURIComponent(spec.getFullName()), - title: spec.getFullName() - }, spec.description)); - - - var resultItems = results.getItems(); - var messagesDiv = this.createDom('div', { className: 'messages' }); - for (var i = 0; i < resultItems.length; i++) { - var result = resultItems[i]; - - if (result.type == 'log') { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); - } else if (result.type == 'expect' && result.passed && !result.passed()) { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); - - if (result.trace.stack) { - messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); - } - } - } - - if (messagesDiv.childNodes.length > 0) { - specDiv.appendChild(messagesDiv); - } - - this.suiteDivs[spec.suite.id].appendChild(specDiv); -}; - -jasmine.TrivialReporter.prototype.log = function() { - var console = jasmine.getGlobal().console; - if (console && console.log) { - if (console.log.apply) { - console.log.apply(console, arguments); - } else { - console.log(arguments); // ie fix: console.log.apply doesn't exist on ie - } - } -}; - -jasmine.TrivialReporter.prototype.getLocation = function() { - return this.document.location; -}; - -jasmine.TrivialReporter.prototype.specFilter = function(spec) { - var paramMap = {}; - var params = this.getLocation().search.substring(1).split('&'); - for (var i = 0; i < params.length; i++) { - var p = params[i].split('='); - paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); - } - - if (!paramMap.spec) { - return true; - } - return spec.getFullName().indexOf(paramMap.spec) === 0; -}; diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/jasmine.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/jasmine.css deleted file mode 100644 index 8c008dc7..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/jasmine.css +++ /dev/null @@ -1,82 +0,0 @@ -body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; } - -#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; } -#HTMLReporter a { text-decoration: none; } -#HTMLReporter a:hover { text-decoration: underline; } -#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; } -#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; } -#HTMLReporter #jasmine_content { position: fixed; right: 100%; } -#HTMLReporter .version { color: #aaaaaa; } -#HTMLReporter .banner { margin-top: 14px; } -#HTMLReporter .duration { color: #aaaaaa; float: right; } -#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; } -#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; } -#HTMLReporter .symbolSummary li.passed { font-size: 14px; } -#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; } -#HTMLReporter .symbolSummary li.failed { line-height: 9px; } -#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; } -#HTMLReporter .symbolSummary li.skipped { font-size: 14px; } -#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; } -#HTMLReporter .symbolSummary li.pending { line-height: 11px; } -#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; } -#HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; } -#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } -#HTMLReporter .runningAlert { background-color: #666666; } -#HTMLReporter .skippedAlert { background-color: #aaaaaa; } -#HTMLReporter .skippedAlert:first-child { background-color: #333333; } -#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; } -#HTMLReporter .passingAlert { background-color: #a6b779; } -#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; } -#HTMLReporter .failingAlert { background-color: #cf867e; } -#HTMLReporter .failingAlert:first-child { background-color: #b03911; } -#HTMLReporter .results { margin-top: 14px; } -#HTMLReporter #details { display: none; } -#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; } -#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; } -#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; } -#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; } -#HTMLReporter.showDetails .summary { display: none; } -#HTMLReporter.showDetails #details { display: block; } -#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; } -#HTMLReporter .summary { margin-top: 14px; } -#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; } -#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; } -#HTMLReporter .summary .specSummary.failed a { color: #b03911; } -#HTMLReporter .description + .suite { margin-top: 0; } -#HTMLReporter .suite { margin-top: 14px; } -#HTMLReporter .suite a { color: #333333; } -#HTMLReporter #details .specDetail { margin-bottom: 28px; } -#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; } -#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; } -#HTMLReporter .resultMessage span.result { display: block; } -#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; } - -#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ } -#TrivialReporter a:visited, #TrivialReporter a { color: #303; } -#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; } -#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; } -#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; } -#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; } -#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; } -#TrivialReporter .runner.running { background-color: yellow; } -#TrivialReporter .options { text-align: right; font-size: .8em; } -#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; } -#TrivialReporter .suite .suite { margin: 5px; } -#TrivialReporter .suite.passed { background-color: #dfd; } -#TrivialReporter .suite.failed { background-color: #fdd; } -#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; } -#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; } -#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; } -#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; } -#TrivialReporter .spec.skipped { background-color: #bbb; } -#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; } -#TrivialReporter .passed { background-color: #cfc; display: none; } -#TrivialReporter .failed { background-color: #fbb; } -#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; } -#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; } -#TrivialReporter .resultMessage .mismatch { color: black; } -#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; } -#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; } -#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; } -#TrivialReporter #jasmine_content { position: fixed; right: 100%; } -#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/jasmine.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/jasmine.js deleted file mode 100644 index 6b3459b9..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/jasmine.js +++ /dev/null @@ -1,2600 +0,0 @@ -var isCommonJS = typeof window == "undefined" && typeof exports == "object"; - -/** - * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. - * - * @namespace - */ -var jasmine = {}; -if (isCommonJS) exports.jasmine = jasmine; -/** - * @private - */ -jasmine.unimplementedMethod_ = function() { - throw new Error("unimplemented method"); -}; - -/** - * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just - * a plain old variable and may be redefined by somebody else. - * - * @private - */ -jasmine.undefined = jasmine.___undefined___; - -/** - * Show diagnostic messages in the console if set to true - * - */ -jasmine.VERBOSE = false; - -/** - * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. - * - */ -jasmine.DEFAULT_UPDATE_INTERVAL = 250; - -/** - * Maximum levels of nesting that will be included when an object is pretty-printed - */ -jasmine.MAX_PRETTY_PRINT_DEPTH = 40; - -/** - * Default timeout interval in milliseconds for waitsFor() blocks. - */ -jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; - -/** - * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite. - * Set to false to let the exception bubble up in the browser. - * - */ -jasmine.CATCH_EXCEPTIONS = true; - -jasmine.getGlobal = function() { - function getGlobal() { - return this; - } - - return getGlobal(); -}; - -/** - * Allows for bound functions to be compared. Internal use only. - * - * @ignore - * @private - * @param base {Object} bound 'this' for the function - * @param name {Function} function to find - */ -jasmine.bindOriginal_ = function(base, name) { - var original = base[name]; - if (original.apply) { - return function() { - return original.apply(base, arguments); - }; - } else { - // IE support - return jasmine.getGlobal()[name]; - } -}; - -jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); -jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); -jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); -jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); - -jasmine.MessageResult = function(values) { - this.type = 'log'; - this.values = values; - this.trace = new Error(); // todo: test better -}; - -jasmine.MessageResult.prototype.toString = function() { - var text = ""; - for (var i = 0; i < this.values.length; i++) { - if (i > 0) text += " "; - if (jasmine.isString_(this.values[i])) { - text += this.values[i]; - } else { - text += jasmine.pp(this.values[i]); - } - } - return text; -}; - -jasmine.ExpectationResult = function(params) { - this.type = 'expect'; - this.matcherName = params.matcherName; - this.passed_ = params.passed; - this.expected = params.expected; - this.actual = params.actual; - this.message = this.passed_ ? 'Passed.' : params.message; - - var trace = (params.trace || new Error(this.message)); - this.trace = this.passed_ ? '' : trace; -}; - -jasmine.ExpectationResult.prototype.toString = function () { - return this.message; -}; - -jasmine.ExpectationResult.prototype.passed = function () { - return this.passed_; -}; - -/** - * Getter for the Jasmine environment. Ensures one gets created - */ -jasmine.getEnv = function() { - var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); - return env; -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isArray_ = function(value) { - return jasmine.isA_("Array", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isString_ = function(value) { - return jasmine.isA_("String", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isNumber_ = function(value) { - return jasmine.isA_("Number", value); -}; - -/** - * @ignore - * @private - * @param {String} typeName - * @param value - * @returns {Boolean} - */ -jasmine.isA_ = function(typeName, value) { - return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; -}; - -/** - * Pretty printer for expecations. Takes any object and turns it into a human-readable string. - * - * @param value {Object} an object to be outputted - * @returns {String} - */ -jasmine.pp = function(value) { - var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); - stringPrettyPrinter.format(value); - return stringPrettyPrinter.string; -}; - -/** - * Returns true if the object is a DOM Node. - * - * @param {Object} obj object to check - * @returns {Boolean} - */ -jasmine.isDomNode = function(obj) { - return obj.nodeType > 0; -}; - -/** - * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. - * - * @example - * // don't care about which function is passed in, as long as it's a function - * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); - * - * @param {Class} clazz - * @returns matchable object of the type clazz - */ -jasmine.any = function(clazz) { - return new jasmine.Matchers.Any(clazz); -}; - -/** - * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the - * attributes on the object. - * - * @example - * // don't care about any other attributes than foo. - * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"}); - * - * @param sample {Object} sample - * @returns matchable object for the sample - */ -jasmine.objectContaining = function (sample) { - return new jasmine.Matchers.ObjectContaining(sample); -}; - -/** - * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. - * - * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine - * expectation syntax. Spies can be checked if they were called or not and what the calling params were. - * - * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). - * - * Spies are torn down at the end of every spec. - * - * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. - * - * @example - * // a stub - * var myStub = jasmine.createSpy('myStub'); // can be used anywhere - * - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // actual foo.not will not be called, execution stops - * spyOn(foo, 'not'); - - // foo.not spied upon, execution will continue to implementation - * spyOn(foo, 'not').andCallThrough(); - * - * // fake example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // foo.not(val) will return val - * spyOn(foo, 'not').andCallFake(function(value) {return value;}); - * - * // mock example - * foo.not(7 == 7); - * expect(foo.not).toHaveBeenCalled(); - * expect(foo.not).toHaveBeenCalledWith(true); - * - * @constructor - * @see spyOn, jasmine.createSpy, jasmine.createSpyObj - * @param {String} name - */ -jasmine.Spy = function(name) { - /** - * The name of the spy, if provided. - */ - this.identity = name || 'unknown'; - /** - * Is this Object a spy? - */ - this.isSpy = true; - /** - * The actual function this spy stubs. - */ - this.plan = function() { - }; - /** - * Tracking of the most recent call to the spy. - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy.mostRecentCall.args = [1, 2]; - */ - this.mostRecentCall = {}; - - /** - * Holds arguments for each call to the spy, indexed by call count - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy(7, 8); - * mySpy.mostRecentCall.args = [7, 8]; - * mySpy.argsForCall[0] = [1, 2]; - * mySpy.argsForCall[1] = [7, 8]; - */ - this.argsForCall = []; - this.calls = []; -}; - -/** - * Tells a spy to call through to the actual implemenatation. - * - * @example - * var foo = { - * bar: function() { // do some stuff } - * } - * - * // defining a spy on an existing property: foo.bar - * spyOn(foo, 'bar').andCallThrough(); - */ -jasmine.Spy.prototype.andCallThrough = function() { - this.plan = this.originalValue; - return this; -}; - -/** - * For setting the return value of a spy. - * - * @example - * // defining a spy from scratch: foo() returns 'baz' - * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); - * - * // defining a spy on an existing property: foo.bar() returns 'baz' - * spyOn(foo, 'bar').andReturn('baz'); - * - * @param {Object} value - */ -jasmine.Spy.prototype.andReturn = function(value) { - this.plan = function() { - return value; - }; - return this; -}; - -/** - * For throwing an exception when a spy is called. - * - * @example - * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' - * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); - * - * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' - * spyOn(foo, 'bar').andThrow('baz'); - * - * @param {String} exceptionMsg - */ -jasmine.Spy.prototype.andThrow = function(exceptionMsg) { - this.plan = function() { - throw exceptionMsg; - }; - return this; -}; - -/** - * Calls an alternate implementation when a spy is called. - * - * @example - * var baz = function() { - * // do some stuff, return something - * } - * // defining a spy from scratch: foo() calls the function baz - * var foo = jasmine.createSpy('spy on foo').andCall(baz); - * - * // defining a spy on an existing property: foo.bar() calls an anonymnous function - * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); - * - * @param {Function} fakeFunc - */ -jasmine.Spy.prototype.andCallFake = function(fakeFunc) { - this.plan = fakeFunc; - return this; -}; - -/** - * Resets all of a spy's the tracking variables so that it can be used again. - * - * @example - * spyOn(foo, 'bar'); - * - * foo.bar(); - * - * expect(foo.bar.callCount).toEqual(1); - * - * foo.bar.reset(); - * - * expect(foo.bar.callCount).toEqual(0); - */ -jasmine.Spy.prototype.reset = function() { - this.wasCalled = false; - this.callCount = 0; - this.argsForCall = []; - this.calls = []; - this.mostRecentCall = {}; -}; - -jasmine.createSpy = function(name) { - - var spyObj = function() { - spyObj.wasCalled = true; - spyObj.callCount++; - var args = jasmine.util.argsToArray(arguments); - spyObj.mostRecentCall.object = this; - spyObj.mostRecentCall.args = args; - spyObj.argsForCall.push(args); - spyObj.calls.push({object: this, args: args}); - return spyObj.plan.apply(this, arguments); - }; - - var spy = new jasmine.Spy(name); - - for (var prop in spy) { - spyObj[prop] = spy[prop]; - } - - spyObj.reset(); - - return spyObj; -}; - -/** - * Determines whether an object is a spy. - * - * @param {jasmine.Spy|Object} putativeSpy - * @returns {Boolean} - */ -jasmine.isSpy = function(putativeSpy) { - return putativeSpy && putativeSpy.isSpy; -}; - -/** - * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something - * large in one call. - * - * @param {String} baseName name of spy class - * @param {Array} methodNames array of names of methods to make spies - */ -jasmine.createSpyObj = function(baseName, methodNames) { - if (!jasmine.isArray_(methodNames) || methodNames.length === 0) { - throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); - } - var obj = {}; - for (var i = 0; i < methodNames.length; i++) { - obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); - } - return obj; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the current spec's output. - * - * Be careful not to leave calls to <code>jasmine.log</code> in production code. - */ -jasmine.log = function() { - var spec = jasmine.getEnv().currentSpec; - spec.log.apply(spec, arguments); -}; - -/** - * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. - * - * @example - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops - * - * @see jasmine.createSpy - * @param obj - * @param methodName - * @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods - */ -var spyOn = function(obj, methodName) { - return jasmine.getEnv().currentSpec.spyOn(obj, methodName); -}; -if (isCommonJS) exports.spyOn = spyOn; - -/** - * Creates a Jasmine spec that will be added to the current suite. - * - * // TODO: pending tests - * - * @example - * it('should be true', function() { - * expect(true).toEqual(true); - * }); - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var it = function(desc, func) { - return jasmine.getEnv().it(desc, func); -}; -if (isCommonJS) exports.it = it; - -/** - * Creates a <em>disabled</em> Jasmine spec. - * - * A convenience method that allows existing specs to be disabled temporarily during development. - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var xit = function(desc, func) { - return jasmine.getEnv().xit(desc, func); -}; -if (isCommonJS) exports.xit = xit; - -/** - * Starts a chain for a Jasmine expectation. - * - * It is passed an Object that is the actual value and should chain to one of the many - * jasmine.Matchers functions. - * - * @param {Object} actual Actual value to test against and expected value - * @return {jasmine.Matchers} - */ -var expect = function(actual) { - return jasmine.getEnv().currentSpec.expect(actual); -}; -if (isCommonJS) exports.expect = expect; - -/** - * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. - * - * @param {Function} func Function that defines part of a jasmine spec. - */ -var runs = function(func) { - jasmine.getEnv().currentSpec.runs(func); -}; -if (isCommonJS) exports.runs = runs; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -var waits = function(timeout) { - jasmine.getEnv().currentSpec.waits(timeout); -}; -if (isCommonJS) exports.waits = waits; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); -}; -if (isCommonJS) exports.waitsFor = waitsFor; - -/** - * A function that is called before each spec in a suite. - * - * Used for spec setup, including validating assumptions. - * - * @param {Function} beforeEachFunction - */ -var beforeEach = function(beforeEachFunction) { - jasmine.getEnv().beforeEach(beforeEachFunction); -}; -if (isCommonJS) exports.beforeEach = beforeEach; - -/** - * A function that is called after each spec in a suite. - * - * Used for restoring any state that is hijacked during spec execution. - * - * @param {Function} afterEachFunction - */ -var afterEach = function(afterEachFunction) { - jasmine.getEnv().afterEach(afterEachFunction); -}; -if (isCommonJS) exports.afterEach = afterEach; - -/** - * Defines a suite of specifications. - * - * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared - * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization - * of setup in some tests. - * - * @example - * // TODO: a simple suite - * - * // TODO: a simple suite with a nested describe block - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var describe = function(description, specDefinitions) { - return jasmine.getEnv().describe(description, specDefinitions); -}; -if (isCommonJS) exports.describe = describe; - -/** - * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var xdescribe = function(description, specDefinitions) { - return jasmine.getEnv().xdescribe(description, specDefinitions); -}; -if (isCommonJS) exports.xdescribe = xdescribe; - - -// Provide the XMLHttpRequest class for IE 5.x-6.x: -jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { - function tryIt(f) { - try { - return f(); - } catch(e) { - } - return null; - } - - var xhr = tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.6.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.3.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP"); - }) || - tryIt(function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }); - - if (!xhr) throw new Error("This browser does not support XMLHttpRequest."); - - return xhr; -} : XMLHttpRequest; -/** - * @namespace - */ -jasmine.util = {}; - -/** - * Declare that a child class inherit it's prototype from the parent class. - * - * @private - * @param {Function} childClass - * @param {Function} parentClass - */ -jasmine.util.inherit = function(childClass, parentClass) { - /** - * @private - */ - var subclass = function() { - }; - subclass.prototype = parentClass.prototype; - childClass.prototype = new subclass(); -}; - -jasmine.util.formatException = function(e) { - var lineNumber; - if (e.line) { - lineNumber = e.line; - } - else if (e.lineNumber) { - lineNumber = e.lineNumber; - } - - var file; - - if (e.sourceURL) { - file = e.sourceURL; - } - else if (e.fileName) { - file = e.fileName; - } - - var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); - - if (file && lineNumber) { - message += ' in ' + file + ' (line ' + lineNumber + ')'; - } - - return message; -}; - -jasmine.util.htmlEscape = function(str) { - if (!str) return str; - return str.replace(/&/g, '&') - .replace(/</g, '<') - .replace(/>/g, '>'); -}; - -jasmine.util.argsToArray = function(args) { - var arrayOfArgs = []; - for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); - return arrayOfArgs; -}; - -jasmine.util.extend = function(destination, source) { - for (var property in source) destination[property] = source[property]; - return destination; -}; - -/** - * Environment for Jasmine - * - * @constructor - */ -jasmine.Env = function() { - this.currentSpec = null; - this.currentSuite = null; - this.currentRunner_ = new jasmine.Runner(this); - - this.reporter = new jasmine.MultiReporter(); - - this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; - this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; - this.lastUpdate = 0; - this.specFilter = function() { - return true; - }; - - this.nextSpecId_ = 0; - this.nextSuiteId_ = 0; - this.equalityTesters_ = []; - - // wrap matchers - this.matchersClass = function() { - jasmine.Matchers.apply(this, arguments); - }; - jasmine.util.inherit(this.matchersClass, jasmine.Matchers); - - jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); -}; - - -jasmine.Env.prototype.setTimeout = jasmine.setTimeout; -jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; -jasmine.Env.prototype.setInterval = jasmine.setInterval; -jasmine.Env.prototype.clearInterval = jasmine.clearInterval; - -/** - * @returns an object containing jasmine version build info, if set. - */ -jasmine.Env.prototype.version = function () { - if (jasmine.version_) { - return jasmine.version_; - } else { - throw new Error('Version not set'); - } -}; - -/** - * @returns string containing jasmine version build info, if set. - */ -jasmine.Env.prototype.versionString = function() { - if (!jasmine.version_) { - return "version unknown"; - } - - var version = this.version(); - var versionString = version.major + "." + version.minor + "." + version.build; - if (version.release_candidate) { - versionString += ".rc" + version.release_candidate; - } - versionString += " revision " + version.revision; - return versionString; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSpecId = function () { - return this.nextSpecId_++; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSuiteId = function () { - return this.nextSuiteId_++; -}; - -/** - * Register a reporter to receive status updates from Jasmine. - * @param {jasmine.Reporter} reporter An object which will receive status updates. - */ -jasmine.Env.prototype.addReporter = function(reporter) { - this.reporter.addReporter(reporter); -}; - -jasmine.Env.prototype.execute = function() { - this.currentRunner_.execute(); -}; - -jasmine.Env.prototype.describe = function(description, specDefinitions) { - var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); - - var parentSuite = this.currentSuite; - if (parentSuite) { - parentSuite.add(suite); - } else { - this.currentRunner_.add(suite); - } - - this.currentSuite = suite; - - var declarationError = null; - try { - specDefinitions.call(suite); - } catch(e) { - declarationError = e; - } - - if (declarationError) { - this.it("encountered a declaration exception", function() { - throw declarationError; - }); - } - - this.currentSuite = parentSuite; - - return suite; -}; - -jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { - if (this.currentSuite) { - this.currentSuite.beforeEach(beforeEachFunction); - } else { - this.currentRunner_.beforeEach(beforeEachFunction); - } -}; - -jasmine.Env.prototype.currentRunner = function () { - return this.currentRunner_; -}; - -jasmine.Env.prototype.afterEach = function(afterEachFunction) { - if (this.currentSuite) { - this.currentSuite.afterEach(afterEachFunction); - } else { - this.currentRunner_.afterEach(afterEachFunction); - } - -}; - -jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { - return { - execute: function() { - } - }; -}; - -jasmine.Env.prototype.it = function(description, func) { - var spec = new jasmine.Spec(this, this.currentSuite, description); - this.currentSuite.add(spec); - this.currentSpec = spec; - - if (func) { - spec.runs(func); - } - - return spec; -}; - -jasmine.Env.prototype.xit = function(desc, func) { - return { - id: this.nextSpecId(), - runs: function() { - } - }; -}; - -jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) { - if (a.source != b.source) - mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/"); - - if (a.ignoreCase != b.ignoreCase) - mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier"); - - if (a.global != b.global) - mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier"); - - if (a.multiline != b.multiline) - mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier"); - - if (a.sticky != b.sticky) - mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier"); - - return (mismatchValues.length === 0); -}; - -jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { - if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { - return true; - } - - a.__Jasmine_been_here_before__ = b; - b.__Jasmine_been_here_before__ = a; - - var hasKey = function(obj, keyName) { - return obj !== null && obj[keyName] !== jasmine.undefined; - }; - - for (var property in b) { - if (!hasKey(a, property) && hasKey(b, property)) { - mismatchKeys.push("expected has key '" + property + "', but missing from actual."); - } - } - for (property in a) { - if (!hasKey(b, property) && hasKey(a, property)) { - mismatchKeys.push("expected missing key '" + property + "', but present in actual."); - } - } - for (property in b) { - if (property == '__Jasmine_been_here_before__') continue; - if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { - mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); - } - } - - if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { - mismatchValues.push("arrays were not the same length"); - } - - delete a.__Jasmine_been_here_before__; - delete b.__Jasmine_been_here_before__; - return (mismatchKeys.length === 0 && mismatchValues.length === 0); -}; - -jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { - mismatchKeys = mismatchKeys || []; - mismatchValues = mismatchValues || []; - - for (var i = 0; i < this.equalityTesters_.length; i++) { - var equalityTester = this.equalityTesters_[i]; - var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); - if (result !== jasmine.undefined) return result; - } - - if (a === b) return true; - - if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { - return (a == jasmine.undefined && b == jasmine.undefined); - } - - if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { - return a === b; - } - - if (a instanceof Date && b instanceof Date) { - return a.getTime() == b.getTime(); - } - - if (a.jasmineMatches) { - return a.jasmineMatches(b); - } - - if (b.jasmineMatches) { - return b.jasmineMatches(a); - } - - if (a instanceof jasmine.Matchers.ObjectContaining) { - return a.matches(b); - } - - if (b instanceof jasmine.Matchers.ObjectContaining) { - return b.matches(a); - } - - if (jasmine.isString_(a) && jasmine.isString_(b)) { - return (a == b); - } - - if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { - return (a == b); - } - - if (a instanceof RegExp && b instanceof RegExp) { - return this.compareRegExps_(a, b, mismatchKeys, mismatchValues); - } - - if (typeof a === "object" && typeof b === "object") { - return this.compareObjects_(a, b, mismatchKeys, mismatchValues); - } - - //Straight check - return (a === b); -}; - -jasmine.Env.prototype.contains_ = function(haystack, needle) { - if (jasmine.isArray_(haystack)) { - for (var i = 0; i < haystack.length; i++) { - if (this.equals_(haystack[i], needle)) return true; - } - return false; - } - return haystack.indexOf(needle) >= 0; -}; - -jasmine.Env.prototype.addEqualityTester = function(equalityTester) { - this.equalityTesters_.push(equalityTester); -}; -/** No-op base class for Jasmine reporters. - * - * @constructor - */ -jasmine.Reporter = function() { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerResults = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecStarting = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecResults = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.log = function(str) { -}; - -/** - * Blocks are functions with executable code that make up a spec. - * - * @constructor - * @param {jasmine.Env} env - * @param {Function} func - * @param {jasmine.Spec} spec - */ -jasmine.Block = function(env, func, spec) { - this.env = env; - this.func = func; - this.spec = spec; -}; - -jasmine.Block.prototype.execute = function(onComplete) { - if (!jasmine.CATCH_EXCEPTIONS) { - this.func.apply(this.spec); - } - else { - try { - this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); - } - } - onComplete(); -}; -/** JavaScript API reporter. - * - * @constructor - */ -jasmine.JsApiReporter = function() { - this.started = false; - this.finished = false; - this.suites_ = []; - this.results_ = {}; -}; - -jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { - this.started = true; - var suites = runner.topLevelSuites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - this.suites_.push(this.summarize_(suite)); - } -}; - -jasmine.JsApiReporter.prototype.suites = function() { - return this.suites_; -}; - -jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { - var isSuite = suiteOrSpec instanceof jasmine.Suite; - var summary = { - id: suiteOrSpec.id, - name: suiteOrSpec.description, - type: isSuite ? 'suite' : 'spec', - children: [] - }; - - if (isSuite) { - var children = suiteOrSpec.children(); - for (var i = 0; i < children.length; i++) { - summary.children.push(this.summarize_(children[i])); - } - } - return summary; -}; - -jasmine.JsApiReporter.prototype.results = function() { - return this.results_; -}; - -jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { - return this.results_[specId]; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { - this.finished = true; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { - this.results_[spec.id] = { - messages: spec.results().getItems(), - result: spec.results().failedCount > 0 ? "failed" : "passed" - }; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.log = function(str) { -}; - -jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ - var results = {}; - for (var i = 0; i < specIds.length; i++) { - var specId = specIds[i]; - results[specId] = this.summarizeResult_(this.results_[specId]); - } - return results; -}; - -jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ - var summaryMessages = []; - var messagesLength = result.messages.length; - for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { - var resultMessage = result.messages[messageIndex]; - summaryMessages.push({ - text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, - passed: resultMessage.passed ? resultMessage.passed() : true, - type: resultMessage.type, - message: resultMessage.message, - trace: { - stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined - } - }); - } - - return { - result : result.result, - messages : summaryMessages - }; -}; - -/** - * @constructor - * @param {jasmine.Env} env - * @param actual - * @param {jasmine.Spec} spec - */ -jasmine.Matchers = function(env, actual, spec, opt_isNot) { - this.env = env; - this.actual = actual; - this.spec = spec; - this.isNot = opt_isNot || false; - this.reportWasCalled_ = false; -}; - -// todo: @deprecated as of Jasmine 0.11, remove soon [xw] -jasmine.Matchers.pp = function(str) { - throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); -}; - -// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] -jasmine.Matchers.prototype.report = function(result, failing_message, details) { - throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); -}; - -jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { - for (var methodName in prototype) { - if (methodName == 'report') continue; - var orig = prototype[methodName]; - matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); - } -}; - -jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { - return function() { - var matcherArgs = jasmine.util.argsToArray(arguments); - var result = matcherFunction.apply(this, arguments); - - if (this.isNot) { - result = !result; - } - - if (this.reportWasCalled_) return result; - - var message; - if (!result) { - if (this.message) { - message = this.message.apply(this, arguments); - if (jasmine.isArray_(message)) { - message = message[this.isNot ? 1 : 0]; - } - } else { - var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); - message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; - if (matcherArgs.length > 0) { - for (var i = 0; i < matcherArgs.length; i++) { - if (i > 0) message += ","; - message += " " + jasmine.pp(matcherArgs[i]); - } - } - message += "."; - } - } - var expectationResult = new jasmine.ExpectationResult({ - matcherName: matcherName, - passed: result, - expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], - actual: this.actual, - message: message - }); - this.spec.addMatcherResult(expectationResult); - return jasmine.undefined; - }; -}; - - - - -/** - * toBe: compares the actual to the expected using === - * @param expected - */ -jasmine.Matchers.prototype.toBe = function(expected) { - return this.actual === expected; -}; - -/** - * toNotBe: compares the actual to the expected using !== - * @param expected - * @deprecated as of 1.0. Use not.toBe() instead. - */ -jasmine.Matchers.prototype.toNotBe = function(expected) { - return this.actual !== expected; -}; - -/** - * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. - * - * @param expected - */ -jasmine.Matchers.prototype.toEqual = function(expected) { - return this.env.equals_(this.actual, expected); -}; - -/** - * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual - * @param expected - * @deprecated as of 1.0. Use not.toEqual() instead. - */ -jasmine.Matchers.prototype.toNotEqual = function(expected) { - return !this.env.equals_(this.actual, expected); -}; - -/** - * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes - * a pattern or a String. - * - * @param expected - */ -jasmine.Matchers.prototype.toMatch = function(expected) { - return new RegExp(expected).test(this.actual); -}; - -/** - * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch - * @param expected - * @deprecated as of 1.0. Use not.toMatch() instead. - */ -jasmine.Matchers.prototype.toNotMatch = function(expected) { - return !(new RegExp(expected).test(this.actual)); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeDefined = function() { - return (this.actual !== jasmine.undefined); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeUndefined = function() { - return (this.actual === jasmine.undefined); -}; - -/** - * Matcher that compares the actual to null. - */ -jasmine.Matchers.prototype.toBeNull = function() { - return (this.actual === null); -}; - -/** - * Matcher that compares the actual to NaN. - */ -jasmine.Matchers.prototype.toBeNaN = function() { - this.message = function() { - return [ "Expected " + jasmine.pp(this.actual) + " to be NaN." ]; - }; - - return (this.actual !== this.actual); -}; - -/** - * Matcher that boolean not-nots the actual. - */ -jasmine.Matchers.prototype.toBeTruthy = function() { - return !!this.actual; -}; - - -/** - * Matcher that boolean nots the actual. - */ -jasmine.Matchers.prototype.toBeFalsy = function() { - return !this.actual; -}; - - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called. - */ -jasmine.Matchers.prototype.toHaveBeenCalled = function() { - if (arguments.length > 0) { - throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to have been called.", - "Expected spy " + this.actual.identity + " not to have been called." - ]; - }; - - return this.actual.wasCalled; -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ -jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was not called. - * - * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead - */ -jasmine.Matchers.prototype.wasNotCalled = function() { - if (arguments.length > 0) { - throw new Error('wasNotCalled does not take arguments'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to not have been called.", - "Expected spy " + this.actual.identity + " to have been called." - ]; - }; - - return !this.actual.wasCalled; -}; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. - * - * @example - * - */ -jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - this.message = function() { - var invertedMessage = "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was."; - var positiveMessage = ""; - if (this.actual.callCount === 0) { - positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called."; - } else { - positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '') - } - return [positiveMessage, invertedMessage]; - }; - - return this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; - -/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasNotCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", - "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" - ]; - }; - - return !this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** - * Matcher that checks that the expected item is an element in the actual Array. - * - * @param {Object} expected - */ -jasmine.Matchers.prototype.toContain = function(expected) { - return this.env.contains_(this.actual, expected); -}; - -/** - * Matcher that checks that the expected item is NOT an element in the actual Array. - * - * @param {Object} expected - * @deprecated as of 1.0. Use not.toContain() instead. - */ -jasmine.Matchers.prototype.toNotContain = function(expected) { - return !this.env.contains_(this.actual, expected); -}; - -jasmine.Matchers.prototype.toBeLessThan = function(expected) { - return this.actual < expected; -}; - -jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { - return this.actual > expected; -}; - -/** - * Matcher that checks that the expected item is equal to the actual item - * up to a given level of decimal precision (default 2). - * - * @param {Number} expected - * @param {Number} precision, as number of decimal places - */ -jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { - if (!(precision === 0)) { - precision = precision || 2; - } - return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2); -}; - -/** - * Matcher that checks that the expected exception was thrown by the actual. - * - * @param {String} [expected] - */ -jasmine.Matchers.prototype.toThrow = function(expected) { - var result = false; - var exception; - if (typeof this.actual != 'function') { - throw new Error('Actual is not a function'); - } - try { - this.actual(); - } catch (e) { - exception = e; - } - if (exception) { - result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); - } - - var not = this.isNot ? "not " : ""; - - this.message = function() { - if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { - return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); - } else { - return "Expected function to throw an exception."; - } - }; - - return result; -}; - -jasmine.Matchers.Any = function(expectedClass) { - this.expectedClass = expectedClass; -}; - -jasmine.Matchers.Any.prototype.jasmineMatches = function(other) { - if (this.expectedClass == String) { - return typeof other == 'string' || other instanceof String; - } - - if (this.expectedClass == Number) { - return typeof other == 'number' || other instanceof Number; - } - - if (this.expectedClass == Function) { - return typeof other == 'function' || other instanceof Function; - } - - if (this.expectedClass == Object) { - return typeof other == 'object'; - } - - return other instanceof this.expectedClass; -}; - -jasmine.Matchers.Any.prototype.jasmineToString = function() { - return '<jasmine.any(' + this.expectedClass + ')>'; -}; - -jasmine.Matchers.ObjectContaining = function (sample) { - this.sample = sample; -}; - -jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) { - mismatchKeys = mismatchKeys || []; - mismatchValues = mismatchValues || []; - - var env = jasmine.getEnv(); - - var hasKey = function(obj, keyName) { - return obj != null && obj[keyName] !== jasmine.undefined; - }; - - for (var property in this.sample) { - if (!hasKey(other, property) && hasKey(this.sample, property)) { - mismatchKeys.push("expected has key '" + property + "', but missing from actual."); - } - else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) { - mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual."); - } - } - - return (mismatchKeys.length === 0 && mismatchValues.length === 0); -}; - -jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () { - return "<jasmine.objectContaining(" + jasmine.pp(this.sample) + ")>"; -}; -// Mock setTimeout, clearTimeout -// Contributed by Pivotal Computer Systems, www.pivotalsf.com - -jasmine.FakeTimer = function() { - this.reset(); - - var self = this; - self.setTimeout = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); - return self.timeoutsMade; - }; - - self.setInterval = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); - return self.timeoutsMade; - }; - - self.clearTimeout = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - - self.clearInterval = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - -}; - -jasmine.FakeTimer.prototype.reset = function() { - this.timeoutsMade = 0; - this.scheduledFunctions = {}; - this.nowMillis = 0; -}; - -jasmine.FakeTimer.prototype.tick = function(millis) { - var oldMillis = this.nowMillis; - var newMillis = oldMillis + millis; - this.runFunctionsWithinRange(oldMillis, newMillis); - this.nowMillis = newMillis; -}; - -jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { - var scheduledFunc; - var funcsToRun = []; - for (var timeoutKey in this.scheduledFunctions) { - scheduledFunc = this.scheduledFunctions[timeoutKey]; - if (scheduledFunc != jasmine.undefined && - scheduledFunc.runAtMillis >= oldMillis && - scheduledFunc.runAtMillis <= nowMillis) { - funcsToRun.push(scheduledFunc); - this.scheduledFunctions[timeoutKey] = jasmine.undefined; - } - } - - if (funcsToRun.length > 0) { - funcsToRun.sort(function(a, b) { - return a.runAtMillis - b.runAtMillis; - }); - for (var i = 0; i < funcsToRun.length; ++i) { - try { - var funcToRun = funcsToRun[i]; - this.nowMillis = funcToRun.runAtMillis; - funcToRun.funcToCall(); - if (funcToRun.recurring) { - this.scheduleFunction(funcToRun.timeoutKey, - funcToRun.funcToCall, - funcToRun.millis, - true); - } - } catch(e) { - } - } - this.runFunctionsWithinRange(oldMillis, nowMillis); - } -}; - -jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { - this.scheduledFunctions[timeoutKey] = { - runAtMillis: this.nowMillis + millis, - funcToCall: funcToCall, - recurring: recurring, - timeoutKey: timeoutKey, - millis: millis - }; -}; - -/** - * @namespace - */ -jasmine.Clock = { - defaultFakeTimer: new jasmine.FakeTimer(), - - reset: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.reset(); - }, - - tick: function(millis) { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.tick(millis); - }, - - runFunctionsWithinRange: function(oldMillis, nowMillis) { - jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); - }, - - scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { - jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); - }, - - useMock: function() { - if (!jasmine.Clock.isInstalled()) { - var spec = jasmine.getEnv().currentSpec; - spec.after(jasmine.Clock.uninstallMock); - - jasmine.Clock.installMock(); - } - }, - - installMock: function() { - jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; - }, - - uninstallMock: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.installed = jasmine.Clock.real; - }, - - real: { - setTimeout: jasmine.getGlobal().setTimeout, - clearTimeout: jasmine.getGlobal().clearTimeout, - setInterval: jasmine.getGlobal().setInterval, - clearInterval: jasmine.getGlobal().clearInterval - }, - - assertInstalled: function() { - if (!jasmine.Clock.isInstalled()) { - throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); - } - }, - - isInstalled: function() { - return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; - }, - - installed: null -}; -jasmine.Clock.installed = jasmine.Clock.real; - -//else for IE support -jasmine.getGlobal().setTimeout = function(funcToCall, millis) { - if (jasmine.Clock.installed.setTimeout.apply) { - return jasmine.Clock.installed.setTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.setTimeout(funcToCall, millis); - } -}; - -jasmine.getGlobal().setInterval = function(funcToCall, millis) { - if (jasmine.Clock.installed.setInterval.apply) { - return jasmine.Clock.installed.setInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.setInterval(funcToCall, millis); - } -}; - -jasmine.getGlobal().clearTimeout = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearTimeout(timeoutKey); - } -}; - -jasmine.getGlobal().clearInterval = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearInterval(timeoutKey); - } -}; - -/** - * @constructor - */ -jasmine.MultiReporter = function() { - this.subReporters_ = []; -}; -jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); - -jasmine.MultiReporter.prototype.addReporter = function(reporter) { - this.subReporters_.push(reporter); -}; - -(function() { - var functionNames = [ - "reportRunnerStarting", - "reportRunnerResults", - "reportSuiteResults", - "reportSpecStarting", - "reportSpecResults", - "log" - ]; - for (var i = 0; i < functionNames.length; i++) { - var functionName = functionNames[i]; - jasmine.MultiReporter.prototype[functionName] = (function(functionName) { - return function() { - for (var j = 0; j < this.subReporters_.length; j++) { - var subReporter = this.subReporters_[j]; - if (subReporter[functionName]) { - subReporter[functionName].apply(subReporter, arguments); - } - } - }; - })(functionName); - } -})(); -/** - * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults - * - * @constructor - */ -jasmine.NestedResults = function() { - /** - * The total count of results - */ - this.totalCount = 0; - /** - * Number of passed results - */ - this.passedCount = 0; - /** - * Number of failed results - */ - this.failedCount = 0; - /** - * Was this suite/spec skipped? - */ - this.skipped = false; - /** - * @ignore - */ - this.items_ = []; -}; - -/** - * Roll up the result counts. - * - * @param result - */ -jasmine.NestedResults.prototype.rollupCounts = function(result) { - this.totalCount += result.totalCount; - this.passedCount += result.passedCount; - this.failedCount += result.failedCount; -}; - -/** - * Adds a log message. - * @param values Array of message parts which will be concatenated later. - */ -jasmine.NestedResults.prototype.log = function(values) { - this.items_.push(new jasmine.MessageResult(values)); -}; - -/** - * Getter for the results: message & results. - */ -jasmine.NestedResults.prototype.getItems = function() { - return this.items_; -}; - -/** - * Adds a result, tracking counts (total, passed, & failed) - * @param {jasmine.ExpectationResult|jasmine.NestedResults} result - */ -jasmine.NestedResults.prototype.addResult = function(result) { - if (result.type != 'log') { - if (result.items_) { - this.rollupCounts(result); - } else { - this.totalCount++; - if (result.passed()) { - this.passedCount++; - } else { - this.failedCount++; - } - } - } - this.items_.push(result); -}; - -/** - * @returns {Boolean} True if <b>everything</b> below passed - */ -jasmine.NestedResults.prototype.passed = function() { - return this.passedCount === this.totalCount; -}; -/** - * Base class for pretty printing for expectation results. - */ -jasmine.PrettyPrinter = function() { - this.ppNestLevel_ = 0; -}; - -/** - * Formats a value in a nice, human-readable string. - * - * @param value - */ -jasmine.PrettyPrinter.prototype.format = function(value) { - this.ppNestLevel_++; - try { - if (value === jasmine.undefined) { - this.emitScalar('undefined'); - } else if (value === null) { - this.emitScalar('null'); - } else if (value === jasmine.getGlobal()) { - this.emitScalar('<global>'); - } else if (value.jasmineToString) { - this.emitScalar(value.jasmineToString()); - } else if (typeof value === 'string') { - this.emitString(value); - } else if (jasmine.isSpy(value)) { - this.emitScalar("spy on " + value.identity); - } else if (value instanceof RegExp) { - this.emitScalar(value.toString()); - } else if (typeof value === 'function') { - this.emitScalar('Function'); - } else if (typeof value.nodeType === 'number') { - this.emitScalar('HTMLNode'); - } else if (value instanceof Date) { - this.emitScalar('Date(' + value + ')'); - } else if (value.__Jasmine_been_here_before__) { - this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>'); - } else if (jasmine.isArray_(value) || typeof value == 'object') { - value.__Jasmine_been_here_before__ = true; - if (jasmine.isArray_(value)) { - this.emitArray(value); - } else { - this.emitObject(value); - } - delete value.__Jasmine_been_here_before__; - } else { - this.emitScalar(value.toString()); - } - } finally { - this.ppNestLevel_--; - } -}; - -jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { - for (var property in obj) { - if (!obj.hasOwnProperty(property)) continue; - if (property == '__Jasmine_been_here_before__') continue; - fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && - obj.__lookupGetter__(property) !== null) : false); - } -}; - -jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; - -jasmine.StringPrettyPrinter = function() { - jasmine.PrettyPrinter.call(this); - - this.string = ''; -}; -jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); - -jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { - this.append(value); -}; - -jasmine.StringPrettyPrinter.prototype.emitString = function(value) { - this.append("'" + value + "'"); -}; - -jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { - if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) { - this.append("Array"); - return; - } - - this.append('[ '); - for (var i = 0; i < array.length; i++) { - if (i > 0) { - this.append(', '); - } - this.format(array[i]); - } - this.append(' ]'); -}; - -jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { - if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) { - this.append("Object"); - return; - } - - var self = this; - this.append('{ '); - var first = true; - - this.iterateObject(obj, function(property, isGetter) { - if (first) { - first = false; - } else { - self.append(', '); - } - - self.append(property); - self.append(' : '); - if (isGetter) { - self.append('<getter>'); - } else { - self.format(obj[property]); - } - }); - - this.append(' }'); -}; - -jasmine.StringPrettyPrinter.prototype.append = function(value) { - this.string += value; -}; -jasmine.Queue = function(env) { - this.env = env; - - // parallel to blocks. each true value in this array means the block will - // get executed even if we abort - this.ensured = []; - this.blocks = []; - this.running = false; - this.index = 0; - this.offset = 0; - this.abort = false; -}; - -jasmine.Queue.prototype.addBefore = function(block, ensure) { - if (ensure === jasmine.undefined) { - ensure = false; - } - - this.blocks.unshift(block); - this.ensured.unshift(ensure); -}; - -jasmine.Queue.prototype.add = function(block, ensure) { - if (ensure === jasmine.undefined) { - ensure = false; - } - - this.blocks.push(block); - this.ensured.push(ensure); -}; - -jasmine.Queue.prototype.insertNext = function(block, ensure) { - if (ensure === jasmine.undefined) { - ensure = false; - } - - this.ensured.splice((this.index + this.offset + 1), 0, ensure); - this.blocks.splice((this.index + this.offset + 1), 0, block); - this.offset++; -}; - -jasmine.Queue.prototype.start = function(onComplete) { - this.running = true; - this.onComplete = onComplete; - this.next_(); -}; - -jasmine.Queue.prototype.isRunning = function() { - return this.running; -}; - -jasmine.Queue.LOOP_DONT_RECURSE = true; - -jasmine.Queue.prototype.next_ = function() { - var self = this; - var goAgain = true; - - while (goAgain) { - goAgain = false; - - if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) { - var calledSynchronously = true; - var completedSynchronously = false; - - var onComplete = function () { - if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { - completedSynchronously = true; - return; - } - - if (self.blocks[self.index].abort) { - self.abort = true; - } - - self.offset = 0; - self.index++; - - var now = new Date().getTime(); - if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { - self.env.lastUpdate = now; - self.env.setTimeout(function() { - self.next_(); - }, 0); - } else { - if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { - goAgain = true; - } else { - self.next_(); - } - } - }; - self.blocks[self.index].execute(onComplete); - - calledSynchronously = false; - if (completedSynchronously) { - onComplete(); - } - - } else { - self.running = false; - if (self.onComplete) { - self.onComplete(); - } - } - } -}; - -jasmine.Queue.prototype.results = function() { - var results = new jasmine.NestedResults(); - for (var i = 0; i < this.blocks.length; i++) { - if (this.blocks[i].results) { - results.addResult(this.blocks[i].results()); - } - } - return results; -}; - - -/** - * Runner - * - * @constructor - * @param {jasmine.Env} env - */ -jasmine.Runner = function(env) { - var self = this; - self.env = env; - self.queue = new jasmine.Queue(env); - self.before_ = []; - self.after_ = []; - self.suites_ = []; -}; - -jasmine.Runner.prototype.execute = function() { - var self = this; - if (self.env.reporter.reportRunnerStarting) { - self.env.reporter.reportRunnerStarting(this); - } - self.queue.start(function () { - self.finishCallback(); - }); -}; - -jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.splice(0,0,beforeEachFunction); -}; - -jasmine.Runner.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.splice(0,0,afterEachFunction); -}; - - -jasmine.Runner.prototype.finishCallback = function() { - this.env.reporter.reportRunnerResults(this); -}; - -jasmine.Runner.prototype.addSuite = function(suite) { - this.suites_.push(suite); -}; - -jasmine.Runner.prototype.add = function(block) { - if (block instanceof jasmine.Suite) { - this.addSuite(block); - } - this.queue.add(block); -}; - -jasmine.Runner.prototype.specs = function () { - var suites = this.suites(); - var specs = []; - for (var i = 0; i < suites.length; i++) { - specs = specs.concat(suites[i].specs()); - } - return specs; -}; - -jasmine.Runner.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Runner.prototype.topLevelSuites = function() { - var topLevelSuites = []; - for (var i = 0; i < this.suites_.length; i++) { - if (!this.suites_[i].parentSuite) { - topLevelSuites.push(this.suites_[i]); - } - } - return topLevelSuites; -}; - -jasmine.Runner.prototype.results = function() { - return this.queue.results(); -}; -/** - * Internal representation of a Jasmine specification, or test. - * - * @constructor - * @param {jasmine.Env} env - * @param {jasmine.Suite} suite - * @param {String} description - */ -jasmine.Spec = function(env, suite, description) { - if (!env) { - throw new Error('jasmine.Env() required'); - } - if (!suite) { - throw new Error('jasmine.Suite() required'); - } - var spec = this; - spec.id = env.nextSpecId ? env.nextSpecId() : null; - spec.env = env; - spec.suite = suite; - spec.description = description; - spec.queue = new jasmine.Queue(env); - - spec.afterCallbacks = []; - spec.spies_ = []; - - spec.results_ = new jasmine.NestedResults(); - spec.results_.description = description; - spec.matchersClass = null; -}; - -jasmine.Spec.prototype.getFullName = function() { - return this.suite.getFullName() + ' ' + this.description + '.'; -}; - - -jasmine.Spec.prototype.results = function() { - return this.results_; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the spec's output. - * - * Be careful not to leave calls to <code>jasmine.log</code> in production code. - */ -jasmine.Spec.prototype.log = function() { - return this.results_.log(arguments); -}; - -jasmine.Spec.prototype.runs = function (func) { - var block = new jasmine.Block(this.env, func, this); - this.addToQueue(block); - return this; -}; - -jasmine.Spec.prototype.addToQueue = function (block) { - if (this.queue.isRunning()) { - this.queue.insertNext(block); - } else { - this.queue.add(block); - } -}; - -/** - * @param {jasmine.ExpectationResult} result - */ -jasmine.Spec.prototype.addMatcherResult = function(result) { - this.results_.addResult(result); -}; - -jasmine.Spec.prototype.expect = function(actual) { - var positive = new (this.getMatchersClass_())(this.env, actual, this); - positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); - return positive; -}; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -jasmine.Spec.prototype.waits = function(timeout) { - var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); - this.addToQueue(waitsFunc); - return this; -}; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - var latchFunction_ = null; - var optional_timeoutMessage_ = null; - var optional_timeout_ = null; - - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - switch (typeof arg) { - case 'function': - latchFunction_ = arg; - break; - case 'string': - optional_timeoutMessage_ = arg; - break; - case 'number': - optional_timeout_ = arg; - break; - } - } - - var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); - this.addToQueue(waitsForFunc); - return this; -}; - -jasmine.Spec.prototype.fail = function (e) { - var expectationResult = new jasmine.ExpectationResult({ - passed: false, - message: e ? jasmine.util.formatException(e) : 'Exception', - trace: { stack: e.stack } - }); - this.results_.addResult(expectationResult); -}; - -jasmine.Spec.prototype.getMatchersClass_ = function() { - return this.matchersClass || this.env.matchersClass; -}; - -jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { - var parent = this.getMatchersClass_(); - var newMatchersClass = function() { - parent.apply(this, arguments); - }; - jasmine.util.inherit(newMatchersClass, parent); - jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); - this.matchersClass = newMatchersClass; -}; - -jasmine.Spec.prototype.finishCallback = function() { - this.env.reporter.reportSpecResults(this); -}; - -jasmine.Spec.prototype.finish = function(onComplete) { - this.removeAllSpies(); - this.finishCallback(); - if (onComplete) { - onComplete(); - } -}; - -jasmine.Spec.prototype.after = function(doAfter) { - if (this.queue.isRunning()) { - this.queue.add(new jasmine.Block(this.env, doAfter, this), true); - } else { - this.afterCallbacks.unshift(doAfter); - } -}; - -jasmine.Spec.prototype.execute = function(onComplete) { - var spec = this; - if (!spec.env.specFilter(spec)) { - spec.results_.skipped = true; - spec.finish(onComplete); - return; - } - - this.env.reporter.reportSpecStarting(this); - - spec.env.currentSpec = spec; - - spec.addBeforesAndAftersToQueue(); - - spec.queue.start(function () { - spec.finish(onComplete); - }); -}; - -jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { - var runner = this.env.currentRunner(); - var i; - - for (var suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); - } - } - for (i = 0; i < runner.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); - } - for (i = 0; i < this.afterCallbacks.length; i++) { - this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true); - } - for (suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true); - } - } - for (i = 0; i < runner.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true); - } -}; - -jasmine.Spec.prototype.explodes = function() { - throw 'explodes function should not have been called'; -}; - -jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { - if (obj == jasmine.undefined) { - throw "spyOn could not find an object to spy upon for " + methodName + "()"; - } - - if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { - throw methodName + '() method does not exist'; - } - - if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { - throw new Error(methodName + ' has already been spied upon'); - } - - var spyObj = jasmine.createSpy(methodName); - - this.spies_.push(spyObj); - spyObj.baseObj = obj; - spyObj.methodName = methodName; - spyObj.originalValue = obj[methodName]; - - obj[methodName] = spyObj; - - return spyObj; -}; - -jasmine.Spec.prototype.removeAllSpies = function() { - for (var i = 0; i < this.spies_.length; i++) { - var spy = this.spies_[i]; - spy.baseObj[spy.methodName] = spy.originalValue; - } - this.spies_ = []; -}; - -/** - * Internal representation of a Jasmine suite. - * - * @constructor - * @param {jasmine.Env} env - * @param {String} description - * @param {Function} specDefinitions - * @param {jasmine.Suite} parentSuite - */ -jasmine.Suite = function(env, description, specDefinitions, parentSuite) { - var self = this; - self.id = env.nextSuiteId ? env.nextSuiteId() : null; - self.description = description; - self.queue = new jasmine.Queue(env); - self.parentSuite = parentSuite; - self.env = env; - self.before_ = []; - self.after_ = []; - self.children_ = []; - self.suites_ = []; - self.specs_ = []; -}; - -jasmine.Suite.prototype.getFullName = function() { - var fullName = this.description; - for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { - fullName = parentSuite.description + ' ' + fullName; - } - return fullName; -}; - -jasmine.Suite.prototype.finish = function(onComplete) { - this.env.reporter.reportSuiteResults(this); - this.finished = true; - if (typeof(onComplete) == 'function') { - onComplete(); - } -}; - -jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.unshift(beforeEachFunction); -}; - -jasmine.Suite.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.unshift(afterEachFunction); -}; - -jasmine.Suite.prototype.results = function() { - return this.queue.results(); -}; - -jasmine.Suite.prototype.add = function(suiteOrSpec) { - this.children_.push(suiteOrSpec); - if (suiteOrSpec instanceof jasmine.Suite) { - this.suites_.push(suiteOrSpec); - this.env.currentRunner().addSuite(suiteOrSpec); - } else { - this.specs_.push(suiteOrSpec); - } - this.queue.add(suiteOrSpec); -}; - -jasmine.Suite.prototype.specs = function() { - return this.specs_; -}; - -jasmine.Suite.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Suite.prototype.children = function() { - return this.children_; -}; - -jasmine.Suite.prototype.execute = function(onComplete) { - var self = this; - this.queue.start(function () { - self.finish(onComplete); - }); -}; -jasmine.WaitsBlock = function(env, timeout, spec) { - this.timeout = timeout; - jasmine.Block.call(this, env, null, spec); -}; - -jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); - -jasmine.WaitsBlock.prototype.execute = function (onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); - } - this.env.setTimeout(function () { - onComplete(); - }, this.timeout); -}; -/** - * A block which waits for some condition to become true, with timeout. - * - * @constructor - * @extends jasmine.Block - * @param {jasmine.Env} env The Jasmine environment. - * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. - * @param {Function} latchFunction A function which returns true when the desired condition has been met. - * @param {String} message The message to display if the desired condition hasn't been met within the given time period. - * @param {jasmine.Spec} spec The Jasmine spec. - */ -jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { - this.timeout = timeout || env.defaultTimeoutInterval; - this.latchFunction = latchFunction; - this.message = message; - this.totalTimeSpentWaitingForLatch = 0; - jasmine.Block.call(this, env, null, spec); -}; -jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); - -jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; - -jasmine.WaitsForBlock.prototype.execute = function(onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); - } - var latchFunctionResult; - try { - latchFunctionResult = this.latchFunction.apply(this.spec); - } catch (e) { - this.spec.fail(e); - onComplete(); - return; - } - - if (latchFunctionResult) { - onComplete(); - } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { - var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); - this.spec.fail({ - name: 'timeout', - message: message - }); - - this.abort = true; - onComplete(); - } else { - this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; - var self = this; - this.env.setTimeout(function() { - self.execute(onComplete); - }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); - } -}; - -jasmine.version_= { - "major": 1, - "minor": 3, - "build": 1, - "revision": 1354556913 -}; diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less.js deleted file mode 100644 index 15023be5..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less.js +++ /dev/null @@ -1,6937 +0,0 @@ -/*! - * LESS - Leaner CSS v1.5.0 - * http://lesscss.org - * - * Copyright (c) 2009-2013, Alexis Sellier <self@cloudhead.net> - * Licensed under the Apache v2 License. - * - * @licence - */ - - - -(function (window, undefined) {// -// Stub out `require` in the browser -// -function require(arg) { - return window.less[arg.split('/')[1]]; -}; - - -if (typeof(window.less) === 'undefined' || typeof(window.less.nodeType) !== 'undefined') { window.less = {}; } -less = window.less; -tree = window.less.tree = {}; -less.mode = 'browser'; - -var less, tree; - -// Node.js does not have a header file added which defines less -if (less === undefined) { - less = exports; - tree = require('./tree'); - less.mode = 'node'; -} -// -// less.js - parser -// -// A relatively straight-forward predictive parser. -// There is no tokenization/lexing stage, the input is parsed -// in one sweep. -// -// To make the parser fast enough to run in the browser, several -// optimization had to be made: -// -// - Matching and slicing on a huge input is often cause of slowdowns. -// The solution is to chunkify the input into smaller strings. -// The chunks are stored in the `chunks` var, -// `j` holds the current chunk index, and `current` holds -// the index of the current chunk in relation to `input`. -// This gives us an almost 4x speed-up. -// -// - In many cases, we don't need to match individual tokens; -// for example, if a value doesn't hold any variables, operations -// or dynamic references, the parser can effectively 'skip' it, -// treating it as a literal. -// An example would be '1px solid #000' - which evaluates to itself, -// we don't need to know what the individual components are. -// The drawback, of course is that you don't get the benefits of -// syntax-checking on the CSS. This gives us a 50% speed-up in the parser, -// and a smaller speed-up in the code-gen. -// -// -// Token matching is done with the `$` function, which either takes -// a terminal string or regexp, or a non-terminal function to call. -// It also takes care of moving all the indices forwards. -// -// -less.Parser = function Parser(env) { - var input, // LeSS input string - i, // current index in `input` - j, // current chunk - temp, // temporarily holds a chunk's state, for backtracking - memo, // temporarily holds `i`, when backtracking - furthest, // furthest index the parser has gone to - chunks, // chunkified input - current, // index of current chunk, in `input` - parser, - rootFilename = env && env.filename; - - // Top parser on an import tree must be sure there is one "env" - // which will then be passed around by reference. - if (!(env instanceof tree.parseEnv)) { - env = new tree.parseEnv(env); - } - - var imports = this.imports = { - paths: env.paths || [], // Search paths, when importing - queue: [], // Files which haven't been imported yet - files: env.files, // Holds the imported parse trees - contents: env.contents, // Holds the imported file contents - mime: env.mime, // MIME type of .less files - error: null, // Error in parsing/evaluating an import - push: function (path, currentFileInfo, importOptions, callback) { - var parserImports = this; - this.queue.push(path); - - var fileParsedFunc = function (e, root, fullPath) { - parserImports.queue.splice(parserImports.queue.indexOf(path), 1); // Remove the path from the queue - - var importedPreviously = fullPath in parserImports.files || fullPath === rootFilename; - - parserImports.files[fullPath] = root; // Store the root - - if (e && !parserImports.error) { parserImports.error = e; } - - callback(e, root, importedPreviously, fullPath); - }; - - if (less.Parser.importer) { - less.Parser.importer(path, currentFileInfo, fileParsedFunc, env); - } else { - less.Parser.fileLoader(path, currentFileInfo, function(e, contents, fullPath, newFileInfo) { - if (e) {fileParsedFunc(e); return;} - - var newEnv = new tree.parseEnv(env); - - newEnv.currentFileInfo = newFileInfo; - newEnv.processImports = false; - newEnv.contents[fullPath] = contents; - - if (currentFileInfo.reference || importOptions.reference) { - newFileInfo.reference = true; - } - - if (importOptions.inline) { - fileParsedFunc(null, contents, fullPath); - } else { - new(less.Parser)(newEnv).parse(contents, function (e, root) { - fileParsedFunc(e, root, fullPath); - }); - } - }, env); - } - } - }; - - function save() { temp = chunks[j], memo = i, current = i; } - function restore() { chunks[j] = temp, i = memo, current = i; } - - function sync() { - if (i > current) { - chunks[j] = chunks[j].slice(i - current); - current = i; - } - } - function isWhitespace(c) { - // Could change to \s? - var code = c.charCodeAt(0); - return code === 32 || code === 10 || code === 9; - } - // - // Parse from a token, regexp or string, and move forward if match - // - function $(tok) { - var match, length; - - // - // Non-terminal - // - if (tok instanceof Function) { - return tok.call(parser.parsers); - // - // Terminal - // - // Either match a single character in the input, - // or match a regexp in the current chunk (chunk[j]). - // - } else if (typeof(tok) === 'string') { - match = input.charAt(i) === tok ? tok : null; - length = 1; - sync (); - } else { - sync (); - - if (match = tok.exec(chunks[j])) { - length = match[0].length; - } else { - return null; - } - } - - // The match is confirmed, add the match length to `i`, - // and consume any extra white-space characters (' ' || '\n') - // which come after that. The reason for this is that LeSS's - // grammar is mostly white-space insensitive. - // - if (match) { - skipWhitespace(length); - - if(typeof(match) === 'string') { - return match; - } else { - return match.length === 1 ? match[0] : match; - } - } - } - - function skipWhitespace(length) { - var oldi = i, oldj = j, - endIndex = i + chunks[j].length, - mem = i += length; - - while (i < endIndex) { - if (! isWhitespace(input.charAt(i))) { break; } - i++; - } - chunks[j] = chunks[j].slice(length + (i - mem)); - current = i; - - if (chunks[j].length === 0 && j < chunks.length - 1) { j++; } - - return oldi !== i || oldj !== j; - } - - function expect(arg, msg) { - var result = $(arg); - if (! result) { - error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'" - : "unexpected token")); - } else { - return result; - } - } - - function error(msg, type) { - var e = new Error(msg); - e.index = i; - e.type = type || 'Syntax'; - throw e; - } - - // Same as $(), but don't change the state of the parser, - // just return the match. - function peek(tok) { - if (typeof(tok) === 'string') { - return input.charAt(i) === tok; - } else { - return tok.test(chunks[j]); - } - } - - function getInput(e, env) { - if (e.filename && env.currentFileInfo.filename && (e.filename !== env.currentFileInfo.filename)) { - return parser.imports.contents[e.filename]; - } else { - return input; - } - } - - function getLocation(index, inputStream) { - var n = index + 1, - line = null, - column = -1; - - while (--n >= 0 && inputStream.charAt(n) !== '\n') { - column++; - } - - if (typeof index === 'number') { - line = (inputStream.slice(0, index).match(/\n/g) || "").length; - } - - return { - line: line, - column: column - }; - } - - function getDebugInfo(index, inputStream, env) { - var filename = env.currentFileInfo.filename; - if(less.mode !== 'browser' && less.mode !== 'rhino') { - filename = require('path').resolve(filename); - } - - return { - lineNumber: getLocation(index, inputStream).line + 1, - fileName: filename - }; - } - - function LessError(e, env) { - var input = getInput(e, env), - loc = getLocation(e.index, input), - line = loc.line, - col = loc.column, - callLine = e.call && getLocation(e.call, input).line, - lines = input.split('\n'); - - this.type = e.type || 'Syntax'; - this.message = e.message; - this.filename = e.filename || env.currentFileInfo.filename; - this.index = e.index; - this.line = typeof(line) === 'number' ? line + 1 : null; - this.callLine = callLine + 1; - this.callExtract = lines[callLine]; - this.stack = e.stack; - this.column = col; - this.extract = [ - lines[line - 1], - lines[line], - lines[line + 1] - ]; - } - - LessError.prototype = new Error(); - LessError.prototype.constructor = LessError; - - this.env = env = env || {}; - - // The optimization level dictates the thoroughness of the parser, - // the lower the number, the less nodes it will create in the tree. - // This could matter for debugging, or if you want to access - // the individual nodes in the tree. - this.optimization = ('optimization' in this.env) ? this.env.optimization : 1; - - // - // The Parser - // - return parser = { - - imports: imports, - // - // Parse an input string into an abstract syntax tree, - // call `callback` when done. - // - parse: function (str, callback) { - var root, line, lines, error = null; - - i = j = current = furthest = 0; - input = str.replace(/\r\n/g, '\n'); - - // Remove potential UTF Byte Order Mark - input = input.replace(/^\uFEFF/, ''); - - parser.imports.contents[env.currentFileInfo.filename] = input; - - // Split the input into chunks. - chunks = (function (chunks) { - var j = 0, - skip = /(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g, - comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g, - string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g, - level = 0, - match, - chunk = chunks[0], - inParam; - - for (var i = 0, c, cc; i < input.length;) { - skip.lastIndex = i; - if (match = skip.exec(input)) { - if (match.index === i) { - i += match[0].length; - chunk.push(match[0]); - } - } - c = input.charAt(i); - comment.lastIndex = string.lastIndex = i; - - if (match = string.exec(input)) { - if (match.index === i) { - i += match[0].length; - chunk.push(match[0]); - continue; - } - } - - if (!inParam && c === '/') { - cc = input.charAt(i + 1); - if (cc === '/' || cc === '*') { - if (match = comment.exec(input)) { - if (match.index === i) { - i += match[0].length; - chunk.push(match[0]); - continue; - } - } - } - } - - switch (c) { - case '{': - if (!inParam) { - level++; - chunk.push(c); - break; - } - /* falls through */ - case '}': - if (!inParam) { - level--; - chunk.push(c); - chunks[++j] = chunk = []; - break; - } - /* falls through */ - case '(': - if (!inParam) { - inParam = true; - chunk.push(c); - break; - } - /* falls through */ - case ')': - if (inParam) { - inParam = false; - chunk.push(c); - break; - } - /* falls through */ - default: - chunk.push(c); - } - - i++; - } - if (level !== 0) { - error = new(LessError)({ - index: i-1, - type: 'Parse', - message: (level > 0) ? "missing closing `}`" : "missing opening `{`", - filename: env.currentFileInfo.filename - }, env); - } - - return chunks.map(function (c) { return c.join(''); }); - })([[]]); - - if (error) { - return callback(new(LessError)(error, env)); - } - - // Start with the primary rule. - // The whole syntax tree is held under a Ruleset node, - // with the `root` property set to true, so no `{}` are - // output. The callback is called when the input is parsed. - try { - root = new(tree.Ruleset)([], $(this.parsers.primary)); - root.root = true; - root.firstRoot = true; - } catch (e) { - return callback(new(LessError)(e, env)); - } - - root.toCSS = (function (evaluate) { - return function (options, variables) { - options = options || {}; - var evaldRoot, - css, - evalEnv = new tree.evalEnv(options); - - // - // Allows setting variables with a hash, so: - // - // `{ color: new(tree.Color)('#f01') }` will become: - // - // new(tree.Rule)('@color', - // new(tree.Value)([ - // new(tree.Expression)([ - // new(tree.Color)('#f01') - // ]) - // ]) - // ) - // - if (typeof(variables) === 'object' && !Array.isArray(variables)) { - variables = Object.keys(variables).map(function (k) { - var value = variables[k]; - - if (! (value instanceof tree.Value)) { - if (! (value instanceof tree.Expression)) { - value = new(tree.Expression)([value]); - } - value = new(tree.Value)([value]); - } - return new(tree.Rule)('@' + k, value, false, null, 0); - }); - evalEnv.frames = [new(tree.Ruleset)(null, variables)]; - } - - try { - evaldRoot = evaluate.call(this, evalEnv); - - new(tree.joinSelectorVisitor)() - .run(evaldRoot); - - new(tree.processExtendsVisitor)() - .run(evaldRoot); - - new(tree.toCSSVisitor)({compress: Boolean(options.compress)}) - .run(evaldRoot); - - if (options.sourceMap) { - evaldRoot = new tree.sourceMapOutput( - { - writeSourceMap: options.writeSourceMap, - rootNode: evaldRoot, - contentsMap: parser.imports.contents, - sourceMapFilename: options.sourceMapFilename, - outputFilename: options.sourceMapOutputFilename, - sourceMapBasepath: options.sourceMapBasepath, - sourceMapRootpath: options.sourceMapRootpath, - outputSourceFiles: options.outputSourceFiles, - sourceMapGenerator: options.sourceMapGenerator - }); - } - - css = evaldRoot.toCSS({ - compress: Boolean(options.compress), - dumpLineNumbers: env.dumpLineNumbers, - strictUnits: Boolean(options.strictUnits)}); - } catch (e) { - throw new(LessError)(e, env); - } - - if (options.cleancss && less.mode === 'node') { - var CleanCSS = require('clean-css'); - //TODO would be nice for no advanced to be an option - return new CleanCSS({keepSpecialComments: '*', processImport: false, noRebase: true, noAdvanced: true}).minify(css); - } else if (options.compress) { - return css.replace(/(^(\s)+)|((\s)+$)/g, ""); - } else { - return css; - } - }; - })(root.eval); - - // If `i` is smaller than the `input.length - 1`, - // it means the parser wasn't able to parse the whole - // string, so we've got a parsing error. - // - // We try to extract a \n delimited string, - // showing the line where the parse error occured. - // We split it up into two parts (the part which parsed, - // and the part which didn't), so we can color them differently. - if (i < input.length - 1) { - i = furthest; - var loc = getLocation(i, input); - lines = input.split('\n'); - line = loc.line + 1; - - error = { - type: "Parse", - message: "Unrecognised input", - index: i, - filename: env.currentFileInfo.filename, - line: line, - column: loc.column, - extract: [ - lines[line - 2], - lines[line - 1], - lines[line] - ] - }; - } - - var finish = function (e) { - e = error || e || parser.imports.error; - - if (e) { - if (!(e instanceof LessError)) { - e = new(LessError)(e, env); - } - - return callback(e); - } - else { - return callback(null, root); - } - }; - - if (env.processImports !== false) { - new tree.importVisitor(this.imports, finish) - .run(root); - } else { - return finish(); - } - }, - - // - // Here in, the parsing rules/functions - // - // The basic structure of the syntax tree generated is as follows: - // - // Ruleset -> Rule -> Value -> Expression -> Entity - // - // Here's some LESS code: - // - // .class { - // color: #fff; - // border: 1px solid #000; - // width: @w + 4px; - // > .child {...} - // } - // - // And here's what the parse tree might look like: - // - // Ruleset (Selector '.class', [ - // Rule ("color", Value ([Expression [Color #fff]])) - // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) - // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]])) - // Ruleset (Selector [Element '>', '.child'], [...]) - // ]) - // - // In general, most rules will try to parse a token with the `$()` function, and if the return - // value is truly, will return a new node, of the relevant type. Sometimes, we need to check - // first, before parsing, that's when we use `peek()`. - // - parsers: { - // - // The `primary` rule is the *entry* and *exit* point of the parser. - // The rules here can appear at any level of the parse tree. - // - // The recursive nature of the grammar is an interplay between the `block` - // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, - // as represented by this simplified grammar: - // - // primary â (ruleset | rule)+ - // ruleset â selector+ block - // block â '{' primary '}' - // - // Only at one point is the primary rule not called from the - // block rule: at the root level. - // - primary: function () { - var node, root = []; - - while ((node = $(this.extendRule) || $(this.mixin.definition) || $(this.rule) || $(this.ruleset) || - $(this.mixin.call) || $(this.comment) || $(this.directive)) - || $(/^[\s\n]+/) || $(/^;+/)) { - node && root.push(node); - } - return root; - }, - - // We create a Comment node for CSS comments `/* */`, - // but keep the LeSS comments `//` silent, by just skipping - // over them. - comment: function () { - var comment; - - if (input.charAt(i) !== '/') { return; } - - if (input.charAt(i + 1) === '/') { - return new(tree.Comment)($(/^\/\/.*/), true, i, env.currentFileInfo); - } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) { - return new(tree.Comment)(comment, false, i, env.currentFileInfo); - } - }, - - comments: function () { - var comment, comments = []; - - while(comment = $(this.comment)) { - comments.push(comment); - } - - return comments; - }, - - // - // Entities are tokens which can be found inside an Expression - // - entities: { - // - // A string, which supports escaping " and ' - // - // "milky way" 'he\'s the one!' - // - quoted: function () { - var str, j = i, e, index = i; - - if (input.charAt(j) === '~') { j++, e = true; } // Escaped strings - if (input.charAt(j) !== '"' && input.charAt(j) !== "'") { return; } - - e && $('~'); - - if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) { - return new(tree.Quoted)(str[0], str[1] || str[2], e, index, env.currentFileInfo); - } - }, - - // - // A catch-all word, such as: - // - // black border-collapse - // - keyword: function () { - var k; - - if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) { - var color = tree.Color.fromKeyword(k); - if (color) { - return color; - } - return new(tree.Keyword)(k); - } - }, - - // - // A function call - // - // rgb(255, 0, 255) - // - // We also try to catch IE's `alpha()`, but let the `alpha` parser - // deal with the details. - // - // The arguments are parsed with the `entities.arguments` parser. - // - call: function () { - var name, nameLC, args, alpha_ret, index = i; - - if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) { return; } - - name = name[1]; - nameLC = name.toLowerCase(); - - if (nameLC === 'url') { return null; } - else { i += name.length; } - - if (nameLC === 'alpha') { - alpha_ret = $(this.alpha); - if(typeof alpha_ret !== 'undefined') { - return alpha_ret; - } - } - - $('('); // Parse the '(' and consume whitespace. - - args = $(this.entities.arguments); - - if (! $(')')) { - return; - } - - if (name) { return new(tree.Call)(name, args, index, env.currentFileInfo); } - }, - arguments: function () { - var args = [], arg; - - while (arg = $(this.entities.assignment) || $(this.expression)) { - args.push(arg); - if (! $(',')) { - break; - } - } - return args; - }, - literal: function () { - return $(this.entities.dimension) || - $(this.entities.color) || - $(this.entities.quoted) || - $(this.entities.unicodeDescriptor); - }, - - // Assignments are argument entities for calls. - // They are present in ie filter properties as shown below. - // - // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) - // - - assignment: function () { - var key, value; - if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) { - return new(tree.Assignment)(key, value); - } - }, - - // - // Parse url() tokens - // - // We use a specific rule for urls, because they don't really behave like - // standard function calls. The difference is that the argument doesn't have - // to be enclosed within a string, so it can't be parsed as an Expression. - // - url: function () { - var value; - - if (input.charAt(i) !== 'u' || !$(/^url\(/)) { - return; - } - - value = $(this.entities.quoted) || $(this.entities.variable) || - $(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ""; - - expect(')'); - - /*jshint eqnull:true */ - return new(tree.URL)((value.value != null || value instanceof tree.Variable) - ? value : new(tree.Anonymous)(value), env.currentFileInfo); - }, - - // - // A Variable entity, such as `@fink`, in - // - // width: @fink + 2px - // - // We use a different parser for variable definitions, - // see `parsers.variable`. - // - variable: function () { - var name, index = i; - - if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) { - return new(tree.Variable)(name, index, env.currentFileInfo); - } - }, - - // A variable entity useing the protective {} e.g. @{var} - variableCurly: function () { - var curly, index = i; - - if (input.charAt(i) === '@' && (curly = $(/^@\{([\w-]+)\}/))) { - return new(tree.Variable)("@" + curly[1], index, env.currentFileInfo); - } - }, - - // - // A Hexadecimal color - // - // #4F3C2F - // - // `rgb` and `hsl` colors are parsed through the `entities.call` parser. - // - color: function () { - var rgb; - - if (input.charAt(i) === '#' && (rgb = $(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) { - return new(tree.Color)(rgb[1]); - } - }, - - // - // A Dimension, that is, a number and a unit - // - // 0.5em 95% - // - dimension: function () { - var value, c = input.charCodeAt(i); - //Is the first char of the dimension 0-9, '.', '+' or '-' - if ((c > 57 || c < 43) || c === 47 || c == 44) { - return; - } - - if (value = $(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/)) { - return new(tree.Dimension)(value[1], value[2]); - } - }, - - // - // A unicode descriptor, as is used in unicode-range - // - // U+0?? or U+00A1-00A9 - // - unicodeDescriptor: function () { - var ud; - - if (ud = $(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/)) { - return new(tree.UnicodeDescriptor)(ud[0]); - } - }, - - // - // JavaScript code to be evaluated - // - // `window.location.href` - // - javascript: function () { - var str, j = i, e; - - if (input.charAt(j) === '~') { j++; e = true; } // Escaped strings - if (input.charAt(j) !== '`') { return; } - if (env.javascriptEnabled !== undefined && !env.javascriptEnabled) { - error("You are using JavaScript, which has been disabled."); - } - - if (e) { $('~'); } - - if (str = $(/^`([^`]*)`/)) { - return new(tree.JavaScript)(str[1], i, e); - } - } - }, - - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink: - // - variable: function () { - var name; - - if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1]; } - }, - - // - // extend syntax - used to extend selectors - // - extend: function(isRule) { - var elements, e, index = i, option, extendList = []; - - if (!$(isRule ? /^&:extend\(/ : /^:extend\(/)) { return; } - - do { - option = null; - elements = []; - while (true) { - option = $(/^(all)(?=\s*(\)|,))/); - if (option) { break; } - e = $(this.element); - if (!e) { break; } - elements.push(e); - } - - option = option && option[1]; - - extendList.push(new(tree.Extend)(new(tree.Selector)(elements), option, index)); - - } while($(",")); - - expect(/^\)/); - - if (isRule) { - expect(/^;/); - } - - return extendList; - }, - - // - // extendRule - used in a rule to extend all the parent selectors - // - extendRule: function() { - return this.extend(true); - }, - - // - // Mixins - // - mixin: { - // - // A Mixin call, with an optional argument list - // - // #mixins > .square(#fff); - // .rounded(4px, black); - // .button; - // - // The `while` loop is there because mixins can be - // namespaced, but we only support the child and descendant - // selector for now. - // - call: function () { - var elements = [], e, c, args, index = i, s = input.charAt(i), important = false; - - if (s !== '.' && s !== '#') { return; } - - save(); // stop us absorbing part of an invalid selector - - while (e = $(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) { - elements.push(new(tree.Element)(c, e, i, env.currentFileInfo)); - c = $('>'); - } - if ($('(')) { - args = this.mixin.args.call(this, true).args; - expect(')'); - } - - args = args || []; - - if ($(this.important)) { - important = true; - } - - if (elements.length > 0 && ($(';') || peek('}'))) { - return new(tree.mixin.Call)(elements, args, index, env.currentFileInfo, important); - } - - restore(); - }, - args: function (isCall) { - var expressions = [], argsSemiColon = [], isSemiColonSeperated, argsComma = [], expressionContainsNamed, name, nameLoop, value, arg, - returner = {args:null, variadic: false}; - while (true) { - if (isCall) { - arg = $(this.expression); - } else { - $(this.comments); - if (input.charAt(i) === '.' && $(/^\.{3}/)) { - returner.variadic = true; - if ($(";") && !isSemiColonSeperated) { - isSemiColonSeperated = true; - } - (isSemiColonSeperated ? argsSemiColon : argsComma) - .push({ variadic: true }); - break; - } - arg = $(this.entities.variable) || $(this.entities.literal) - || $(this.entities.keyword); - } - - if (!arg) { - break; - } - - nameLoop = null; - if (arg.throwAwayComments) { - arg.throwAwayComments(); - } - value = arg; - var val = null; - - if (isCall) { - // Variable - if (arg.value.length == 1) { - val = arg.value[0]; - } - } else { - val = arg; - } - - if (val && val instanceof tree.Variable) { - if ($(':')) { - if (expressions.length > 0) { - if (isSemiColonSeperated) { - error("Cannot mix ; and , as delimiter types"); - } - expressionContainsNamed = true; - } - value = expect(this.expression); - nameLoop = (name = val.name); - } else if (!isCall && $(/^\.{3}/)) { - returner.variadic = true; - if ($(";") && !isSemiColonSeperated) { - isSemiColonSeperated = true; - } - (isSemiColonSeperated ? argsSemiColon : argsComma) - .push({ name: arg.name, variadic: true }); - break; - } else if (!isCall) { - name = nameLoop = val.name; - value = null; - } - } - - if (value) { - expressions.push(value); - } - - argsComma.push({ name:nameLoop, value:value }); - - if ($(',')) { - continue; - } - - if ($(';') || isSemiColonSeperated) { - - if (expressionContainsNamed) { - error("Cannot mix ; and , as delimiter types"); - } - - isSemiColonSeperated = true; - - if (expressions.length > 1) { - value = new(tree.Value)(expressions); - } - argsSemiColon.push({ name:name, value:value }); - - name = null; - expressions = []; - expressionContainsNamed = false; - } - } - - returner.args = isSemiColonSeperated ? argsSemiColon : argsComma; - return returner; - }, - // - // A Mixin definition, with a list of parameters - // - // .rounded (@radius: 2px, @color) { - // ... - // } - // - // Until we have a finer grained state-machine, we have to - // do a look-ahead, to make sure we don't have a mixin call. - // See the `rule` function for more information. - // - // We start by matching `.rounded (`, and then proceed on to - // the argument list, which has optional default values. - // We store the parameters in `params`, with a `value` key, - // if there is a value, such as in the case of `@radius`. - // - // Once we've got our params list, and a closing `)`, we parse - // the `{...}` block. - // - definition: function () { - var name, params = [], match, ruleset, cond, variadic = false; - if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') || - peek(/^[^{]*\}/)) { - return; - } - - save(); - - if (match = $(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)) { - name = match[1]; - - var argInfo = this.mixin.args.call(this, false); - params = argInfo.args; - variadic = argInfo.variadic; - - // .mixincall("@{a}"); - // looks a bit like a mixin definition.. so we have to be nice and restore - if (!$(')')) { - furthest = i; - restore(); - } - - $(this.comments); - - if ($(/^when/)) { // Guard - cond = expect(this.conditions, 'expected condition'); - } - - ruleset = $(this.block); - - if (ruleset) { - return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic); - } else { - restore(); - } - } - } - }, - - // - // Entities are the smallest recognized token, - // and can be found inside a rule's value. - // - entity: function () { - return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) || - $(this.entities.call) || $(this.entities.keyword) ||$(this.entities.javascript) || - $(this.comment); - }, - - // - // A Rule terminator. Note that we use `peek()` to check for '}', - // because the `block` rule will be expecting it, but we still need to make sure - // it's there, if ';' was ommitted. - // - end: function () { - return $(';') || peek('}'); - }, - - // - // IE's alpha function - // - // alpha(opacity=88) - // - alpha: function () { - var value; - - if (! $(/^\(opacity=/i)) { return; } - if (value = $(/^\d+/) || $(this.entities.variable)) { - expect(')'); - return new(tree.Alpha)(value); - } - }, - - // - // A Selector Element - // - // div - // + h1 - // #socks - // input[type="text"] - // - // Elements are the building blocks for Selectors, - // they are made out of a `Combinator` (see combinator rule), - // and an element name, such as a tag a class, or `*`. - // - element: function () { - var e, c, v; - - c = $(this.combinator); - - e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || - $('*') || $('&') || $(this.attribute) || $(/^\([^()@]+\)/) || $(/^[\.#](?=@)/) || $(this.entities.variableCurly); - - if (! e) { - if ($('(')) { - if ((v = ($(this.selector))) && - $(')')) { - e = new(tree.Paren)(v); - } - } - } - - if (e) { return new(tree.Element)(c, e, i, env.currentFileInfo); } - }, - - // - // Combinators combine elements together, in a Selector. - // - // Because our parser isn't white-space sensitive, special care - // has to be taken, when parsing the descendant combinator, ` `, - // as it's an empty space. We have to check the previous character - // in the input, to see if it's a ` ` character. More info on how - // we deal with this in *combinator.js*. - // - combinator: function () { - var c = input.charAt(i); - - if (c === '>' || c === '+' || c === '~' || c === '|') { - i++; - while (input.charAt(i).match(/\s/)) { i++; } - return new(tree.Combinator)(c); - } else if (input.charAt(i - 1).match(/\s/)) { - return new(tree.Combinator)(" "); - } else { - return new(tree.Combinator)(null); - } - }, - // - // A CSS selector (see selector below) - // with less extensions e.g. the ability to extend and guard - // - lessSelector: function () { - return this.selector(true); - }, - // - // A CSS Selector - // - // .class > div + h1 - // li a:hover - // - // Selectors are made out of one or more Elements, see above. - // - selector: function (isLess) { - var e, elements = [], c, extend, extendList = [], when, condition; - - while ((isLess && (extend = $(this.extend))) || (isLess && (when = $(/^when/))) || (e = $(this.element))) { - if (when) { - condition = expect(this.conditions, 'expected condition'); - } else if (condition) { - error("CSS guard can only be used at the end of selector"); - } else if (extend) { - extendList.push.apply(extendList, extend); - } else { - if (extendList.length) { - error("Extend can only be used at the end of selector"); - } - c = input.charAt(i); - elements.push(e); - e = null; - } - if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { - break; - } - } - - if (elements.length > 0) { return new(tree.Selector)(elements, extendList, condition, i, env.currentFileInfo); } - if (extendList.length) { error("Extend must be used to extend a selector, it cannot be used on its own"); } - }, - attribute: function () { - var key, val, op; - - if (! $('[')) { return; } - - if (!(key = $(this.entities.variableCurly))) { - key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); - } - - if ((op = $(/^[|~*$^]?=/))) { - val = $(this.entities.quoted) || $(/^[0-9]+%/) || $(/^[\w-]+/) || $(this.entities.variableCurly); - } - - expect(']'); - - return new(tree.Attribute)(key, op, val); - }, - - // - // The `block` rule is used by `ruleset` and `mixin.definition`. - // It's a wrapper around the `primary` rule, with added `{}`. - // - block: function () { - var content; - if ($('{') && (content = $(this.primary)) && $('}')) { - return content; - } - }, - - // - // div, .class, body > p {...} - // - ruleset: function () { - var selectors = [], s, rules, debugInfo; - - save(); - - if (env.dumpLineNumbers) { - debugInfo = getDebugInfo(i, input, env); - } - - while (s = $(this.lessSelector)) { - selectors.push(s); - $(this.comments); - if (! $(',')) { break; } - if (s.condition) { - error("Guards are only currently allowed on a single selector."); - } - $(this.comments); - } - - if (selectors.length > 0 && (rules = $(this.block))) { - var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports); - if (env.dumpLineNumbers) { - ruleset.debugInfo = debugInfo; - } - return ruleset; - } else { - // Backtrack - furthest = i; - restore(); - } - }, - rule: function (tryAnonymous) { - var name, value, c = input.charAt(i), important, merge = false; - save(); - - if (c === '.' || c === '#' || c === '&') { return; } - - if (name = $(this.variable) || $(this.ruleProperty)) { - // prefer to try to parse first if its a variable or we are compressing - // but always fallback on the other one - value = !tryAnonymous && (env.compress || (name.charAt(0) === '@')) ? - ($(this.value) || $(this.anonymousValue)) : - ($(this.anonymousValue) || $(this.value)); - - - important = $(this.important); - if (name[name.length-1] === "+") { - merge = true; - name = name.substr(0, name.length - 1); - } - - if (value && $(this.end)) { - return new (tree.Rule)(name, value, important, merge, memo, env.currentFileInfo); - } else { - furthest = i; - restore(); - if (value && !tryAnonymous) { - return this.rule(true); - } - } - } - }, - anonymousValue: function () { - var match; - if (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j])) { - i += match[0].length - 1; - return new(tree.Anonymous)(match[1]); - } - }, - - // - // An @import directive - // - // @import "lib"; - // - // Depending on our environemnt, importing is done differently: - // In the browser, it's an XHR request, in Node, it would be a - // file-system operation. The function used for importing is - // stored in `import`, which we pass to the Import constructor. - // - "import": function () { - var path, features, index = i; - - save(); - - var dir = $(/^@import?\s+/); - - var options = (dir ? $(this.importOptions) : null) || {}; - - if (dir && (path = $(this.entities.quoted) || $(this.entities.url))) { - features = $(this.mediaFeatures); - if ($(';')) { - features = features && new(tree.Value)(features); - return new(tree.Import)(path, features, options, index, env.currentFileInfo); - } - } - - restore(); - }, - - importOptions: function() { - var o, options = {}, optionName, value; - - // list of options, surrounded by parens - if (! $('(')) { return null; } - do { - if (o = $(this.importOption)) { - optionName = o; - value = true; - switch(optionName) { - case "css": - optionName = "less"; - value = false; - break; - case "once": - optionName = "multiple"; - value = false; - break; - } - options[optionName] = value; - if (! $(',')) { break; } - } - } while (o); - expect(')'); - return options; - }, - - importOption: function() { - var opt = $(/^(less|css|multiple|once|inline|reference)/); - if (opt) { - return opt[1]; - } - }, - - mediaFeature: function () { - var e, p, nodes = []; - - do { - if (e = ($(this.entities.keyword) || $(this.entities.variable))) { - nodes.push(e); - } else if ($('(')) { - p = $(this.property); - e = $(this.value); - if ($(')')) { - if (p && e) { - nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, null, i, env.currentFileInfo, true))); - } else if (e) { - nodes.push(new(tree.Paren)(e)); - } else { - return null; - } - } else { return null; } - } - } while (e); - - if (nodes.length > 0) { - return new(tree.Expression)(nodes); - } - }, - - mediaFeatures: function () { - var e, features = []; - - do { - if (e = $(this.mediaFeature)) { - features.push(e); - if (! $(',')) { break; } - } else if (e = $(this.entities.variable)) { - features.push(e); - if (! $(',')) { break; } - } - } while (e); - - return features.length > 0 ? features : null; - }, - - media: function () { - var features, rules, media, debugInfo; - - if (env.dumpLineNumbers) { - debugInfo = getDebugInfo(i, input, env); - } - - if ($(/^@media/)) { - features = $(this.mediaFeatures); - - if (rules = $(this.block)) { - media = new(tree.Media)(rules, features, i, env.currentFileInfo); - if (env.dumpLineNumbers) { - media.debugInfo = debugInfo; - } - return media; - } - } - }, - - // - // A CSS Directive - // - // @charset "utf-8"; - // - directive: function () { - var name, value, rules, nonVendorSpecificName, - hasBlock, hasIdentifier, hasExpression, identifier; - - if (input.charAt(i) !== '@') { return; } - - if (value = $(this['import']) || $(this.media)) { - return value; - } - - save(); - - name = $(/^@[a-z-]+/); - - if (!name) { return; } - - nonVendorSpecificName = name; - if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { - nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1); - } - - switch(nonVendorSpecificName) { - case "@font-face": - hasBlock = true; - break; - case "@viewport": - case "@top-left": - case "@top-left-corner": - case "@top-center": - case "@top-right": - case "@top-right-corner": - case "@bottom-left": - case "@bottom-left-corner": - case "@bottom-center": - case "@bottom-right": - case "@bottom-right-corner": - case "@left-top": - case "@left-middle": - case "@left-bottom": - case "@right-top": - case "@right-middle": - case "@right-bottom": - hasBlock = true; - break; - case "@host": - case "@page": - case "@document": - case "@supports": - case "@keyframes": - hasBlock = true; - hasIdentifier = true; - break; - case "@namespace": - hasExpression = true; - break; - } - - if (hasIdentifier) { - identifier = ($(/^[^{]+/) || '').trim(); - if (identifier) { - name += " " + identifier; - } - } - - if (hasBlock) - { - if (rules = $(this.block)) { - return new(tree.Directive)(name, rules, i, env.currentFileInfo); - } - } else { - if ((value = hasExpression ? $(this.expression) : $(this.entity)) && $(';')) { - var directive = new(tree.Directive)(name, value, i, env.currentFileInfo); - if (env.dumpLineNumbers) { - directive.debugInfo = getDebugInfo(i, input, env); - } - return directive; - } - } - - restore(); - }, - - // - // A Value is a comma-delimited list of Expressions - // - // font-family: Baskerville, Georgia, serif; - // - // In a Rule, a Value represents everything after the `:`, - // and before the `;`. - // - value: function () { - var e, expressions = []; - - while (e = $(this.expression)) { - expressions.push(e); - if (! $(',')) { break; } - } - - if (expressions.length > 0) { - return new(tree.Value)(expressions); - } - }, - important: function () { - if (input.charAt(i) === '!') { - return $(/^! *important/); - } - }, - sub: function () { - var a, e; - - if ($('(')) { - if (a = $(this.addition)) { - e = new(tree.Expression)([a]); - expect(')'); - e.parens = true; - return e; - } - } - }, - multiplication: function () { - var m, a, op, operation, isSpaced; - if (m = $(this.operand)) { - isSpaced = isWhitespace(input.charAt(i - 1)); - while (!peek(/^\/[*\/]/) && (op = ($('/') || $('*')))) { - if (a = $(this.operand)) { - m.parensInOp = true; - a.parensInOp = true; - operation = new(tree.Operation)(op, [operation || m, a], isSpaced); - isSpaced = isWhitespace(input.charAt(i - 1)); - } else { - break; - } - } - return operation || m; - } - }, - addition: function () { - var m, a, op, operation, isSpaced; - if (m = $(this.multiplication)) { - isSpaced = isWhitespace(input.charAt(i - 1)); - while ((op = $(/^[-+]\s+/) || (!isSpaced && ($('+') || $('-')))) && - (a = $(this.multiplication))) { - m.parensInOp = true; - a.parensInOp = true; - operation = new(tree.Operation)(op, [operation || m, a], isSpaced); - isSpaced = isWhitespace(input.charAt(i - 1)); - } - return operation || m; - } - }, - conditions: function () { - var a, b, index = i, condition; - - if (a = $(this.condition)) { - while (peek(/^,\s*(not\s*)?\(/) && $(',') && (b = $(this.condition))) { - condition = new(tree.Condition)('or', condition || a, b, index); - } - return condition || a; - } - }, - condition: function () { - var a, b, c, op, index = i, negate = false; - - if ($(/^not/)) { negate = true; } - expect('('); - if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) { - if (op = $(/^(?:>=|<=|=<|[<=>])/)) { - if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) { - c = new(tree.Condition)(op, a, b, index, negate); - } else { - error('expected expression'); - } - } else { - c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate); - } - expect(')'); - return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c; - } - }, - - // - // An operand is anything that can be part of an operation, - // such as a Color, or a Variable - // - operand: function () { - var negate, p = input.charAt(i + 1); - - if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-'); } - var o = $(this.sub) || $(this.entities.dimension) || - $(this.entities.color) || $(this.entities.variable) || - $(this.entities.call); - - if (negate) { - o.parensInOp = true; - o = new(tree.Negative)(o); - } - - return o; - }, - - // - // Expressions either represent mathematical operations, - // or white-space delimited Entities. - // - // 1px solid black - // @var * 2 - // - expression: function () { - var e, delim, entities = []; - - while (e = $(this.addition) || $(this.entity)) { - entities.push(e); - // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here - if (!peek(/^\/[\/*]/) && (delim = $('/'))) { - entities.push(new(tree.Anonymous)(delim)); - } - } - if (entities.length > 0) { - return new(tree.Expression)(entities); - } - }, - property: function () { - var name; - - if (name = $(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/)) { - return name[1]; - } - }, - ruleProperty: function () { - var name; - - if (name = $(/^(\*?-?[_a-zA-Z0-9-]+)\s*(\+?)\s*:/)) { - return name[1] + (name[2] || ""); - } - } - } - }; -}; - - -(function (tree) { - -tree.functions = { - rgb: function (r, g, b) { - return this.rgba(r, g, b, 1.0); - }, - rgba: function (r, g, b, a) { - var rgb = [r, g, b].map(function (c) { return scaled(c, 256); }); - a = number(a); - return new(tree.Color)(rgb, a); - }, - hsl: function (h, s, l) { - return this.hsla(h, s, l, 1.0); - }, - hsla: function (h, s, l, a) { - function hue(h) { - h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h); - if (h * 6 < 1) { return m1 + (m2 - m1) * h * 6; } - else if (h * 2 < 1) { return m2; } - else if (h * 3 < 2) { return m1 + (m2 - m1) * (2/3 - h) * 6; } - else { return m1; } - } - - h = (number(h) % 360) / 360; - s = clamp(number(s)); l = clamp(number(l)); a = clamp(number(a)); - - var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; - var m1 = l * 2 - m2; - - return this.rgba(hue(h + 1/3) * 255, - hue(h) * 255, - hue(h - 1/3) * 255, - a); - }, - - hsv: function(h, s, v) { - return this.hsva(h, s, v, 1.0); - }, - - hsva: function(h, s, v, a) { - h = ((number(h) % 360) / 360) * 360; - s = number(s); v = number(v); a = number(a); - - var i, f; - i = Math.floor((h / 60) % 6); - f = (h / 60) - i; - - var vs = [v, - v * (1 - s), - v * (1 - f * s), - v * (1 - (1 - f) * s)]; - var perm = [[0, 3, 1], - [2, 0, 1], - [1, 0, 3], - [1, 2, 0], - [3, 1, 0], - [0, 1, 2]]; - - return this.rgba(vs[perm[i][0]] * 255, - vs[perm[i][1]] * 255, - vs[perm[i][2]] * 255, - a); - }, - - hue: function (color) { - return new(tree.Dimension)(Math.round(color.toHSL().h)); - }, - saturation: function (color) { - return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%'); - }, - lightness: function (color) { - return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%'); - }, - hsvhue: function(color) { - return new(tree.Dimension)(Math.round(color.toHSV().h)); - }, - hsvsaturation: function (color) { - return new(tree.Dimension)(Math.round(color.toHSV().s * 100), '%'); - }, - hsvvalue: function (color) { - return new(tree.Dimension)(Math.round(color.toHSV().v * 100), '%'); - }, - red: function (color) { - return new(tree.Dimension)(color.rgb[0]); - }, - green: function (color) { - return new(tree.Dimension)(color.rgb[1]); - }, - blue: function (color) { - return new(tree.Dimension)(color.rgb[2]); - }, - alpha: function (color) { - return new(tree.Dimension)(color.toHSL().a); - }, - luma: function (color) { - return new(tree.Dimension)(Math.round(color.luma() * color.alpha * 100), '%'); - }, - saturate: function (color, amount) { - // filter: saturate(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - var hsl = color.toHSL(); - - hsl.s += amount.value / 100; - hsl.s = clamp(hsl.s); - return hsla(hsl); - }, - desaturate: function (color, amount) { - var hsl = color.toHSL(); - - hsl.s -= amount.value / 100; - hsl.s = clamp(hsl.s); - return hsla(hsl); - }, - lighten: function (color, amount) { - var hsl = color.toHSL(); - - hsl.l += amount.value / 100; - hsl.l = clamp(hsl.l); - return hsla(hsl); - }, - darken: function (color, amount) { - var hsl = color.toHSL(); - - hsl.l -= amount.value / 100; - hsl.l = clamp(hsl.l); - return hsla(hsl); - }, - fadein: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a += amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - fadeout: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a -= amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - fade: function (color, amount) { - var hsl = color.toHSL(); - - hsl.a = amount.value / 100; - hsl.a = clamp(hsl.a); - return hsla(hsl); - }, - spin: function (color, amount) { - var hsl = color.toHSL(); - var hue = (hsl.h + amount.value) % 360; - - hsl.h = hue < 0 ? 360 + hue : hue; - - return hsla(hsl); - }, - // - // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein - // http://sass-lang.com - // - mix: function (color1, color2, weight) { - if (!weight) { - weight = new(tree.Dimension)(50); - } - var p = weight.value / 100.0; - var w = p * 2 - 1; - var a = color1.toHSL().a - color2.toHSL().a; - - var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; - var w2 = 1 - w1; - - var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, - color1.rgb[1] * w1 + color2.rgb[1] * w2, - color1.rgb[2] * w1 + color2.rgb[2] * w2]; - - var alpha = color1.alpha * p + color2.alpha * (1 - p); - - return new(tree.Color)(rgb, alpha); - }, - greyscale: function (color) { - return this.desaturate(color, new(tree.Dimension)(100)); - }, - contrast: function (color, dark, light, threshold) { - // filter: contrast(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - if (typeof light === 'undefined') { - light = this.rgba(255, 255, 255, 1.0); - } - if (typeof dark === 'undefined') { - dark = this.rgba(0, 0, 0, 1.0); - } - //Figure out which is actually light and dark! - if (dark.luma() > light.luma()) { - var t = light; - light = dark; - dark = t; - } - if (typeof threshold === 'undefined') { - threshold = 0.43; - } else { - threshold = number(threshold); - } - if ((color.luma() * color.alpha) < threshold) { - return light; - } else { - return dark; - } - }, - e: function (str) { - return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str); - }, - escape: function (str) { - return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29")); - }, - '%': function (quoted /* arg, arg, ...*/) { - var args = Array.prototype.slice.call(arguments, 1), - str = quoted.value; - - for (var i = 0; i < args.length; i++) { - /*jshint loopfunc:true */ - str = str.replace(/%[sda]/i, function(token) { - var value = token.match(/s/i) ? args[i].value : args[i].toCSS(); - return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; - }); - } - str = str.replace(/%%/g, '%'); - return new(tree.Quoted)('"' + str + '"', str); - }, - unit: function (val, unit) { - if(!(val instanceof tree.Dimension)) { - throw { type: "Argument", message: "the first argument to unit must be a number" + (val instanceof tree.Operation ? ". Have you forgotten parenthesis?" : "") }; - } - return new(tree.Dimension)(val.value, unit ? unit.toCSS() : ""); - }, - convert: function (val, unit) { - return val.convertTo(unit.value); - }, - round: function (n, f) { - var fraction = typeof(f) === "undefined" ? 0 : f.value; - return this._math(function(num) { return num.toFixed(fraction); }, null, n); - }, - pi: function () { - return new(tree.Dimension)(Math.PI); - }, - mod: function(a, b) { - return new(tree.Dimension)(a.value % b.value, a.unit); - }, - pow: function(x, y) { - if (typeof x === "number" && typeof y === "number") { - x = new(tree.Dimension)(x); - y = new(tree.Dimension)(y); - } else if (!(x instanceof tree.Dimension) || !(y instanceof tree.Dimension)) { - throw { type: "Argument", message: "arguments must be numbers" }; - } - - return new(tree.Dimension)(Math.pow(x.value, y.value), x.unit); - }, - _math: function (fn, unit, n) { - if (n instanceof tree.Dimension) { - /*jshint eqnull:true */ - return new(tree.Dimension)(fn(parseFloat(n.value)), unit == null ? n.unit : unit); - } else if (typeof(n) === 'number') { - return fn(n); - } else { - throw { type: "Argument", message: "argument must be a number" }; - } - }, - _minmax: function (isMin, args) { - args = Array.prototype.slice.call(args); - switch(args.length) { - case 0: throw { type: "Argument", message: "one or more arguments required" }; - case 1: return args[0]; - } - var i, j, current, currentUnified, referenceUnified, unit, - order = [], // elems only contains original argument values. - values = {}; // key is the unit.toString() for unified tree.Dimension values, - // value is the index into the order array. - for (i = 0; i < args.length; i++) { - current = args[i]; - if (!(current instanceof tree.Dimension)) { - order.push(current); - continue; - } - currentUnified = current.unify(); - unit = currentUnified.unit.toString(); - j = values[unit]; - if (j === undefined) { - values[unit] = order.length; - order.push(current); - continue; - } - referenceUnified = order[j].unify(); - if ( isMin && currentUnified.value < referenceUnified.value || - !isMin && currentUnified.value > referenceUnified.value) { - order[j] = current; - } - } - if (order.length == 1) { - return order[0]; - } - args = order.map(function (a) { return a.toCSS(this.env); }) - .join(this.env.compress ? "," : ", "); - return new(tree.Anonymous)((isMin ? "min" : "max") + "(" + args + ")"); - }, - min: function () { - return this._minmax(true, arguments); - }, - max: function () { - return this._minmax(false, arguments); - }, - argb: function (color) { - return new(tree.Anonymous)(color.toARGB()); - - }, - percentage: function (n) { - return new(tree.Dimension)(n.value * 100, '%'); - }, - color: function (n) { - if (n instanceof tree.Quoted) { - var colorCandidate = n.value, - returnColor; - returnColor = tree.Color.fromKeyword(colorCandidate); - if (returnColor) { - return returnColor; - } - if (/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/.test(colorCandidate)) { - return new(tree.Color)(colorCandidate.slice(1)); - } - throw { type: "Argument", message: "argument must be a color keyword or 3/6 digit hex e.g. #FFF" }; - } else { - throw { type: "Argument", message: "argument must be a string" }; - } - }, - iscolor: function (n) { - return this._isa(n, tree.Color); - }, - isnumber: function (n) { - return this._isa(n, tree.Dimension); - }, - isstring: function (n) { - return this._isa(n, tree.Quoted); - }, - iskeyword: function (n) { - return this._isa(n, tree.Keyword); - }, - isurl: function (n) { - return this._isa(n, tree.URL); - }, - ispixel: function (n) { - return this.isunit(n, 'px'); - }, - ispercentage: function (n) { - return this.isunit(n, '%'); - }, - isem: function (n) { - return this.isunit(n, 'em'); - }, - isunit: function (n, unit) { - return (n instanceof tree.Dimension) && n.unit.is(unit.value || unit) ? tree.True : tree.False; - }, - _isa: function (n, Type) { - return (n instanceof Type) ? tree.True : tree.False; - }, - - /* Blending modes */ - - multiply: function(color1, color2) { - var r = color1.rgb[0] * color2.rgb[0] / 255; - var g = color1.rgb[1] * color2.rgb[1] / 255; - var b = color1.rgb[2] * color2.rgb[2] / 255; - return this.rgb(r, g, b); - }, - screen: function(color1, color2) { - var r = 255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255; - var g = 255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255; - var b = 255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255; - return this.rgb(r, g, b); - }, - overlay: function(color1, color2) { - var r = color1.rgb[0] < 128 ? 2 * color1.rgb[0] * color2.rgb[0] / 255 : 255 - 2 * (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255; - var g = color1.rgb[1] < 128 ? 2 * color1.rgb[1] * color2.rgb[1] / 255 : 255 - 2 * (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255; - var b = color1.rgb[2] < 128 ? 2 * color1.rgb[2] * color2.rgb[2] / 255 : 255 - 2 * (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255; - return this.rgb(r, g, b); - }, - softlight: function(color1, color2) { - var t = color2.rgb[0] * color1.rgb[0] / 255; - var r = t + color1.rgb[0] * (255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255 - t) / 255; - t = color2.rgb[1] * color1.rgb[1] / 255; - var g = t + color1.rgb[1] * (255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255 - t) / 255; - t = color2.rgb[2] * color1.rgb[2] / 255; - var b = t + color1.rgb[2] * (255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255 - t) / 255; - return this.rgb(r, g, b); - }, - hardlight: function(color1, color2) { - var r = color2.rgb[0] < 128 ? 2 * color2.rgb[0] * color1.rgb[0] / 255 : 255 - 2 * (255 - color2.rgb[0]) * (255 - color1.rgb[0]) / 255; - var g = color2.rgb[1] < 128 ? 2 * color2.rgb[1] * color1.rgb[1] / 255 : 255 - 2 * (255 - color2.rgb[1]) * (255 - color1.rgb[1]) / 255; - var b = color2.rgb[2] < 128 ? 2 * color2.rgb[2] * color1.rgb[2] / 255 : 255 - 2 * (255 - color2.rgb[2]) * (255 - color1.rgb[2]) / 255; - return this.rgb(r, g, b); - }, - difference: function(color1, color2) { - var r = Math.abs(color1.rgb[0] - color2.rgb[0]); - var g = Math.abs(color1.rgb[1] - color2.rgb[1]); - var b = Math.abs(color1.rgb[2] - color2.rgb[2]); - return this.rgb(r, g, b); - }, - exclusion: function(color1, color2) { - var r = color1.rgb[0] + color2.rgb[0] * (255 - color1.rgb[0] - color1.rgb[0]) / 255; - var g = color1.rgb[1] + color2.rgb[1] * (255 - color1.rgb[1] - color1.rgb[1]) / 255; - var b = color1.rgb[2] + color2.rgb[2] * (255 - color1.rgb[2] - color1.rgb[2]) / 255; - return this.rgb(r, g, b); - }, - average: function(color1, color2) { - var r = (color1.rgb[0] + color2.rgb[0]) / 2; - var g = (color1.rgb[1] + color2.rgb[1]) / 2; - var b = (color1.rgb[2] + color2.rgb[2]) / 2; - return this.rgb(r, g, b); - }, - negation: function(color1, color2) { - var r = 255 - Math.abs(255 - color2.rgb[0] - color1.rgb[0]); - var g = 255 - Math.abs(255 - color2.rgb[1] - color1.rgb[1]); - var b = 255 - Math.abs(255 - color2.rgb[2] - color1.rgb[2]); - return this.rgb(r, g, b); - }, - tint: function(color, amount) { - return this.mix(this.rgb(255,255,255), color, amount); - }, - shade: function(color, amount) { - return this.mix(this.rgb(0, 0, 0), color, amount); - }, - extract: function(values, index) { - index = index.value - 1; // (1-based index) - // handle non-array values as an array of length 1 - // return 'undefined' if index is invalid - return Array.isArray(values.value) - ? values.value[index] : Array(values)[index]; - }, - length: function(values) { - var n = Array.isArray(values.value) ? values.value.length : 1; - return new tree.Dimension(n); - }, - - "data-uri": function(mimetypeNode, filePathNode) { - - if (typeof window !== 'undefined') { - return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); - } - - var mimetype = mimetypeNode.value; - var filePath = (filePathNode && filePathNode.value); - - var fs = require("fs"), - path = require("path"), - useBase64 = false; - - if (arguments.length < 2) { - filePath = mimetype; - } - - if (this.env.isPathRelative(filePath)) { - if (this.currentFileInfo.relativeUrls) { - filePath = path.join(this.currentFileInfo.currentDirectory, filePath); - } else { - filePath = path.join(this.currentFileInfo.entryPath, filePath); - } - } - - // detect the mimetype if not given - if (arguments.length < 2) { - var mime; - try { - mime = require('mime'); - } catch (ex) { - mime = tree._mime; - } - - mimetype = mime.lookup(filePath); - - // use base 64 unless it's an ASCII or UTF-8 format - var charset = mime.charsets.lookup(mimetype); - useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; - if (useBase64) { mimetype += ';base64'; } - } - else { - useBase64 = /;base64$/.test(mimetype); - } - - var buf = fs.readFileSync(filePath); - - // IE8 cannot handle a data-uri larger than 32KB. If this is exceeded - // and the --ieCompat flag is enabled, return a normal url() instead. - var DATA_URI_MAX_KB = 32, - fileSizeInKB = parseInt((buf.length / 1024), 10); - if (fileSizeInKB >= DATA_URI_MAX_KB) { - - if (this.env.ieCompat !== false) { - if (!this.env.silent) { - console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!", filePath, fileSizeInKB, DATA_URI_MAX_KB); - } - - return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); - } - } - - buf = useBase64 ? buf.toString('base64') - : encodeURIComponent(buf); - - var uri = "'data:" + mimetype + ',' + buf + "'"; - return new(tree.URL)(new(tree.Anonymous)(uri)); - }, - - "svg-gradient": function(direction) { - - function throwArgumentDescriptor() { - throw { type: "Argument", message: "svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]" }; - } - - if (arguments.length < 3) { - throwArgumentDescriptor(); - } - var stops = Array.prototype.slice.call(arguments, 1), - gradientDirectionSvg, - gradientType = "linear", - rectangleDimension = 'x="0" y="0" width="1" height="1"', - useBase64 = true, - renderEnv = {compress: false}, - returner, - directionValue = direction.toCSS(renderEnv), - i, color, position, positionValue, alpha; - - switch (directionValue) { - case "to bottom": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; - break; - case "to right": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; - break; - case "to bottom right": - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; - break; - case "to top right": - gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; - break; - case "ellipse": - case "ellipse at center": - gradientType = "radial"; - gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; - rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; - break; - default: - throw { type: "Argument", message: "svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'" }; - } - returner = '<?xml version="1.0" ?>' + - '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none">' + - '<' + gradientType + 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' + gradientDirectionSvg + '>'; - - for (i = 0; i < stops.length; i+= 1) { - if (stops[i].value) { - color = stops[i].value[0]; - position = stops[i].value[1]; - } else { - color = stops[i]; - position = undefined; - } - - if (!(color instanceof tree.Color) || (!((i === 0 || i+1 === stops.length) && position === undefined) && !(position instanceof tree.Dimension))) { - throwArgumentDescriptor(); - } - positionValue = position ? position.toCSS(renderEnv) : i === 0 ? "0%" : "100%"; - alpha = color.alpha; - returner += '<stop offset="' + positionValue + '" stop-color="' + color.toRGB() + '"' + (alpha < 1 ? ' stop-opacity="' + alpha + '"' : '') + '/>'; - } - returner += '</' + gradientType + 'Gradient>' + - '<rect ' + rectangleDimension + ' fill="url(#gradient)" /></svg>'; - - if (useBase64) { - // only works in node, needs interface to what is supported in environment - try { - returner = new Buffer(returner).toString('base64'); - } catch(e) { - useBase64 = false; - } - } - - returner = "'data:image/svg+xml" + (useBase64 ? ";base64" : "") + "," + returner + "'"; - return new(tree.URL)(new(tree.Anonymous)(returner)); - } -}; - -// these static methods are used as a fallback when the optional 'mime' dependency is missing -tree._mime = { - // this map is intentionally incomplete - // if you want more, install 'mime' dep - _types: { - '.htm' : 'text/html', - '.html': 'text/html', - '.gif' : 'image/gif', - '.jpg' : 'image/jpeg', - '.jpeg': 'image/jpeg', - '.png' : 'image/png' - }, - lookup: function (filepath) { - var ext = require('path').extname(filepath), - type = tree._mime._types[ext]; - if (type === undefined) { - throw new Error('Optional dependency "mime" is required for ' + ext); - } - return type; - }, - charsets: { - lookup: function (type) { - // assumes all text types are UTF-8 - return type && (/^text\//).test(type) ? 'UTF-8' : ''; - } - } -}; - -var mathFunctions = [{name:"ceil"}, {name:"floor"}, {name: "sqrt"}, {name:"abs"}, - {name:"tan", unit: ""}, {name:"sin", unit: ""}, {name:"cos", unit: ""}, - {name:"atan", unit: "rad"}, {name:"asin", unit: "rad"}, {name:"acos", unit: "rad"}], - createMathFunction = function(name, unit) { - return function(n) { - /*jshint eqnull:true */ - if (unit != null) { - n = n.unify(); - } - return this._math(Math[name], unit, n); - }; - }; - -for(var i = 0; i < mathFunctions.length; i++) { - tree.functions[mathFunctions[i].name] = createMathFunction(mathFunctions[i].name, mathFunctions[i].unit); -} - -function hsla(color) { - return tree.functions.hsla(color.h, color.s, color.l, color.a); -} - -function scaled(n, size) { - if (n instanceof tree.Dimension && n.unit.is('%')) { - return parseFloat(n.value * size / 100); - } else { - return number(n); - } -} - -function number(n) { - if (n instanceof tree.Dimension) { - return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); - } else if (typeof(n) === 'number') { - return n; - } else { - throw { - error: "RuntimeError", - message: "color functions take numbers as parameters" - }; - } -} - -function clamp(val) { - return Math.min(1, Math.max(0, val)); -} - -tree.functionCall = function(env, currentFileInfo) { - this.env = env; - this.currentFileInfo = currentFileInfo; -}; - -tree.functionCall.prototype = tree.functions; - -})(require('./tree')); - -(function (tree) { - tree.colors = { - 'aliceblue':'#f0f8ff', - 'antiquewhite':'#faebd7', - 'aqua':'#00ffff', - 'aquamarine':'#7fffd4', - 'azure':'#f0ffff', - 'beige':'#f5f5dc', - 'bisque':'#ffe4c4', - 'black':'#000000', - 'blanchedalmond':'#ffebcd', - 'blue':'#0000ff', - 'blueviolet':'#8a2be2', - 'brown':'#a52a2a', - 'burlywood':'#deb887', - 'cadetblue':'#5f9ea0', - 'chartreuse':'#7fff00', - 'chocolate':'#d2691e', - 'coral':'#ff7f50', - 'cornflowerblue':'#6495ed', - 'cornsilk':'#fff8dc', - 'crimson':'#dc143c', - 'cyan':'#00ffff', - 'darkblue':'#00008b', - 'darkcyan':'#008b8b', - 'darkgoldenrod':'#b8860b', - 'darkgray':'#a9a9a9', - 'darkgrey':'#a9a9a9', - 'darkgreen':'#006400', - 'darkkhaki':'#bdb76b', - 'darkmagenta':'#8b008b', - 'darkolivegreen':'#556b2f', - 'darkorange':'#ff8c00', - 'darkorchid':'#9932cc', - 'darkred':'#8b0000', - 'darksalmon':'#e9967a', - 'darkseagreen':'#8fbc8f', - 'darkslateblue':'#483d8b', - 'darkslategray':'#2f4f4f', - 'darkslategrey':'#2f4f4f', - 'darkturquoise':'#00ced1', - 'darkviolet':'#9400d3', - 'deeppink':'#ff1493', - 'deepskyblue':'#00bfff', - 'dimgray':'#696969', - 'dimgrey':'#696969', - 'dodgerblue':'#1e90ff', - 'firebrick':'#b22222', - 'floralwhite':'#fffaf0', - 'forestgreen':'#228b22', - 'fuchsia':'#ff00ff', - 'gainsboro':'#dcdcdc', - 'ghostwhite':'#f8f8ff', - 'gold':'#ffd700', - 'goldenrod':'#daa520', - 'gray':'#808080', - 'grey':'#808080', - 'green':'#008000', - 'greenyellow':'#adff2f', - 'honeydew':'#f0fff0', - 'hotpink':'#ff69b4', - 'indianred':'#cd5c5c', - 'indigo':'#4b0082', - 'ivory':'#fffff0', - 'khaki':'#f0e68c', - 'lavender':'#e6e6fa', - 'lavenderblush':'#fff0f5', - 'lawngreen':'#7cfc00', - 'lemonchiffon':'#fffacd', - 'lightblue':'#add8e6', - 'lightcoral':'#f08080', - 'lightcyan':'#e0ffff', - 'lightgoldenrodyellow':'#fafad2', - 'lightgray':'#d3d3d3', - 'lightgrey':'#d3d3d3', - 'lightgreen':'#90ee90', - 'lightpink':'#ffb6c1', - 'lightsalmon':'#ffa07a', - 'lightseagreen':'#20b2aa', - 'lightskyblue':'#87cefa', - 'lightslategray':'#778899', - 'lightslategrey':'#778899', - 'lightsteelblue':'#b0c4de', - 'lightyellow':'#ffffe0', - 'lime':'#00ff00', - 'limegreen':'#32cd32', - 'linen':'#faf0e6', - 'magenta':'#ff00ff', - 'maroon':'#800000', - 'mediumaquamarine':'#66cdaa', - 'mediumblue':'#0000cd', - 'mediumorchid':'#ba55d3', - 'mediumpurple':'#9370d8', - 'mediumseagreen':'#3cb371', - 'mediumslateblue':'#7b68ee', - 'mediumspringgreen':'#00fa9a', - 'mediumturquoise':'#48d1cc', - 'mediumvioletred':'#c71585', - 'midnightblue':'#191970', - 'mintcream':'#f5fffa', - 'mistyrose':'#ffe4e1', - 'moccasin':'#ffe4b5', - 'navajowhite':'#ffdead', - 'navy':'#000080', - 'oldlace':'#fdf5e6', - 'olive':'#808000', - 'olivedrab':'#6b8e23', - 'orange':'#ffa500', - 'orangered':'#ff4500', - 'orchid':'#da70d6', - 'palegoldenrod':'#eee8aa', - 'palegreen':'#98fb98', - 'paleturquoise':'#afeeee', - 'palevioletred':'#d87093', - 'papayawhip':'#ffefd5', - 'peachpuff':'#ffdab9', - 'peru':'#cd853f', - 'pink':'#ffc0cb', - 'plum':'#dda0dd', - 'powderblue':'#b0e0e6', - 'purple':'#800080', - 'red':'#ff0000', - 'rosybrown':'#bc8f8f', - 'royalblue':'#4169e1', - 'saddlebrown':'#8b4513', - 'salmon':'#fa8072', - 'sandybrown':'#f4a460', - 'seagreen':'#2e8b57', - 'seashell':'#fff5ee', - 'sienna':'#a0522d', - 'silver':'#c0c0c0', - 'skyblue':'#87ceeb', - 'slateblue':'#6a5acd', - 'slategray':'#708090', - 'slategrey':'#708090', - 'snow':'#fffafa', - 'springgreen':'#00ff7f', - 'steelblue':'#4682b4', - 'tan':'#d2b48c', - 'teal':'#008080', - 'thistle':'#d8bfd8', - 'tomato':'#ff6347', - 'turquoise':'#40e0d0', - 'violet':'#ee82ee', - 'wheat':'#f5deb3', - 'white':'#ffffff', - 'whitesmoke':'#f5f5f5', - 'yellow':'#ffff00', - 'yellowgreen':'#9acd32' - }; -})(require('./tree')); - -(function (tree) { - -tree.debugInfo = function(env, ctx, lineSeperator) { - var result=""; - if (env.dumpLineNumbers && !env.compress) { - switch(env.dumpLineNumbers) { - case 'comments': - result = tree.debugInfo.asComment(ctx); - break; - case 'mediaquery': - result = tree.debugInfo.asMediaQuery(ctx); - break; - case 'all': - result = tree.debugInfo.asComment(ctx) + (lineSeperator || "") + tree.debugInfo.asMediaQuery(ctx); - break; - } - } - return result; -}; - -tree.debugInfo.asComment = function(ctx) { - return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n'; -}; - -tree.debugInfo.asMediaQuery = function(ctx) { - return '@media -sass-debug-info{filename{font-family:' + - ('file://' + ctx.debugInfo.fileName).replace(/([.:/\\])/g, function (a) { - if (a == '\\') { - a = '\/'; - } - return '\\' + a; - }) + - '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n'; -}; - -tree.find = function (obj, fun) { - for (var i = 0, r; i < obj.length; i++) { - if (r = fun.call(obj, obj[i])) { return r; } - } - return null; -}; - -tree.jsify = function (obj) { - if (Array.isArray(obj.value) && (obj.value.length > 1)) { - return '[' + obj.value.map(function (v) { return v.toCSS(false); }).join(', ') + ']'; - } else { - return obj.toCSS(false); - } -}; - -tree.toCSS = function (env) { - var strs = []; - this.genCSS(env, { - add: function(chunk, fileInfo, index) { - strs.push(chunk); - }, - isEmpty: function () { - return strs.length === 0; - } - }); - return strs.join(''); -}; - -tree.outputRuleset = function (env, output, rules) { - output.add((env.compress ? '{' : ' {\n')); - env.tabLevel = (env.tabLevel || 0) + 1; - var tabRuleStr = env.compress ? '' : Array(env.tabLevel + 1).join(" "), - tabSetStr = env.compress ? '' : Array(env.tabLevel).join(" "); - for(var i = 0; i < rules.length; i++) { - output.add(tabRuleStr); - rules[i].genCSS(env, output); - output.add(env.compress ? '' : '\n'); - } - env.tabLevel--; - output.add(tabSetStr + "}"); -}; - -})(require('./tree')); - -(function (tree) { - -tree.Alpha = function (val) { - this.value = val; -}; -tree.Alpha.prototype = { - type: "Alpha", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - if (this.value.eval) { return new tree.Alpha(this.value.eval(env)); } - return this; - }, - genCSS: function (env, output) { - output.add("alpha(opacity="); - - if (this.value.genCSS) { - this.value.genCSS(env, output); - } else { - output.add(this.value); - } - - output.add(")"); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Anonymous = function (string, index, currentFileInfo, mapLines) { - this.value = string.value || string; - this.index = index; - this.mapLines = mapLines; - this.currentFileInfo = currentFileInfo; -}; -tree.Anonymous.prototype = { - type: "Anonymous", - eval: function () { return this; }, - compare: function (x) { - if (!x.toCSS) { - return -1; - } - - var left = this.toCSS(), - right = x.toCSS(); - - if (left === right) { - return 0; - } - - return left < right ? -1 : 1; - }, - genCSS: function (env, output) { - output.add(this.value, this.currentFileInfo, this.index, this.mapLines); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Assignment = function (key, val) { - this.key = key; - this.value = val; -}; -tree.Assignment.prototype = { - type: "Assignment", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - if (this.value.eval) { - return new(tree.Assignment)(this.key, this.value.eval(env)); - } - return this; - }, - genCSS: function (env, output) { - output.add(this.key + '='); - if (this.value.genCSS) { - this.value.genCSS(env, output); - } else { - output.add(this.value); - } - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -// -// A function call node. -// -tree.Call = function (name, args, index, currentFileInfo) { - this.name = name; - this.args = args; - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Call.prototype = { - type: "Call", - accept: function (visitor) { - this.args = visitor.visit(this.args); - }, - // - // When evaluating a function call, - // we either find the function in `tree.functions` [1], - // in which case we call it, passing the evaluated arguments, - // if this returns null or we cannot find the function, we - // simply print it out as it appeared originally [2]. - // - // The *functions.js* file contains the built-in functions. - // - // The reason why we evaluate the arguments, is in the case where - // we try to pass a variable to a function, like: `saturate(@color)`. - // The function should receive the value, not the variable. - // - eval: function (env) { - var args = this.args.map(function (a) { return a.eval(env); }), - nameLC = this.name.toLowerCase(), - result, func; - - if (nameLC in tree.functions) { // 1. - try { - func = new tree.functionCall(env, this.currentFileInfo); - result = func[nameLC].apply(func, args); - /*jshint eqnull:true */ - if (result != null) { - return result; - } - } catch (e) { - throw { type: e.type || "Runtime", - message: "error evaluating function `" + this.name + "`" + - (e.message ? ': ' + e.message : ''), - index: this.index, filename: this.currentFileInfo.filename }; - } - } - - return new tree.Call(this.name, args, this.index, this.currentFileInfo); - }, - - genCSS: function (env, output) { - output.add(this.name + "(", this.currentFileInfo, this.index); - - for(var i = 0; i < this.args.length; i++) { - this.args[i].genCSS(env, output); - if (i + 1 < this.args.length) { - output.add(", "); - } - } - - output.add(")"); - }, - - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { -// -// RGB Colors - #ff0014, #eee -// -tree.Color = function (rgb, a) { - // - // The end goal here, is to parse the arguments - // into an integer triplet, such as `128, 255, 0` - // - // This facilitates operations and conversions. - // - if (Array.isArray(rgb)) { - this.rgb = rgb; - } else if (rgb.length == 6) { - this.rgb = rgb.match(/.{2}/g).map(function (c) { - return parseInt(c, 16); - }); - } else { - this.rgb = rgb.split('').map(function (c) { - return parseInt(c + c, 16); - }); - } - this.alpha = typeof(a) === 'number' ? a : 1; -}; - -var transparentKeyword = "transparent"; - -tree.Color.prototype = { - type: "Color", - eval: function () { return this; }, - luma: function () { return (0.2126 * this.rgb[0] / 255) + (0.7152 * this.rgb[1] / 255) + (0.0722 * this.rgb[2] / 255); }, - - genCSS: function (env, output) { - output.add(this.toCSS(env)); - }, - toCSS: function (env, doNotCompress) { - var compress = env && env.compress && !doNotCompress; - - // If we have some transparency, the only way to represent it - // is via `rgba`. Otherwise, we use the hex representation, - // which has better compatibility with older browsers. - // Values are capped between `0` and `255`, rounded and zero-padded. - if (this.alpha < 1.0) { - if (this.alpha === 0 && this.isTransparentKeyword) { - return transparentKeyword; - } - return "rgba(" + this.rgb.map(function (c) { - return Math.round(c); - }).concat(this.alpha).join(',' + (compress ? '' : ' ')) + ")"; - } else { - var color = this.toRGB(); - - if (compress) { - var splitcolor = color.split(''); - - // Convert color to short format - if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { - color = '#' + splitcolor[1] + splitcolor[3] + splitcolor[5]; - } - } - - return color; - } - }, - - // - // Operations have to be done per-channel, if not, - // channels will spill onto each other. Once we have - // our result, in the form of an integer triplet, - // we create a new Color node to hold the result. - // - operate: function (env, op, other) { - var result = []; - - if (! (other instanceof tree.Color)) { - other = other.toColor(); - } - - for (var c = 0; c < 3; c++) { - result[c] = tree.operate(env, op, this.rgb[c], other.rgb[c]); - } - return new(tree.Color)(result, this.alpha + other.alpha); - }, - - toRGB: function () { - return '#' + this.rgb.map(function (i) { - i = Math.round(i); - i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16); - return i.length === 1 ? '0' + i : i; - }).join(''); - }, - - toHSL: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255, - a = this.alpha; - - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, l = (max + min) / 2, d = max - min; - - if (max === min) { - h = s = 0; - } else { - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - - switch (max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - return { h: h * 360, s: s, l: l, a: a }; - }, - //Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - toHSV: function () { - var r = this.rgb[0] / 255, - g = this.rgb[1] / 255, - b = this.rgb[2] / 255, - a = this.alpha; - - var max = Math.max(r, g, b), min = Math.min(r, g, b); - var h, s, v = max; - - var d = max - min; - if (max === 0) { - s = 0; - } else { - s = d / max; - } - - if (max === min) { - h = 0; - } else { - switch(max){ - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - return { h: h * 360, s: s, v: v, a: a }; - }, - toARGB: function () { - var argb = [Math.round(this.alpha * 255)].concat(this.rgb); - return '#' + argb.map(function (i) { - i = Math.round(i); - i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16); - return i.length === 1 ? '0' + i : i; - }).join(''); - }, - compare: function (x) { - if (!x.rgb) { - return -1; - } - - return (x.rgb[0] === this.rgb[0] && - x.rgb[1] === this.rgb[1] && - x.rgb[2] === this.rgb[2] && - x.alpha === this.alpha) ? 0 : -1; - } -}; - -tree.Color.fromKeyword = function(keyword) { - if (tree.colors.hasOwnProperty(keyword)) { - // detect named color - return new(tree.Color)(tree.colors[keyword].slice(1)); - } - if (keyword === transparentKeyword) { - var transparent = new(tree.Color)([0, 0, 0], 0); - transparent.isTransparentKeyword = true; - return transparent; - } -}; - - -})(require('../tree')); - -(function (tree) { - -tree.Comment = function (value, silent, index, currentFileInfo) { - this.value = value; - this.silent = !!silent; - this.currentFileInfo = currentFileInfo; -}; -tree.Comment.prototype = { - type: "Comment", - genCSS: function (env, output) { - if (this.debugInfo) { - output.add(tree.debugInfo(env, this), this.currentFileInfo, this.index); - } - output.add(this.value.trim()); //TODO shouldn't need to trim, we shouldn't grab the \n - }, - toCSS: tree.toCSS, - isSilent: function(env) { - var isReference = (this.currentFileInfo && this.currentFileInfo.reference && !this.isReferenced), - isCompressed = env.compress && !this.value.match(/^\/\*!/); - return this.silent || isReference || isCompressed; - }, - eval: function () { return this; }, - markReferenced: function () { - this.isReferenced = true; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Condition = function (op, l, r, i, negate) { - this.op = op.trim(); - this.lvalue = l; - this.rvalue = r; - this.index = i; - this.negate = negate; -}; -tree.Condition.prototype = { - type: "Condition", - accept: function (visitor) { - this.lvalue = visitor.visit(this.lvalue); - this.rvalue = visitor.visit(this.rvalue); - }, - eval: function (env) { - var a = this.lvalue.eval(env), - b = this.rvalue.eval(env); - - var i = this.index, result; - - result = (function (op) { - switch (op) { - case 'and': - return a && b; - case 'or': - return a || b; - default: - if (a.compare) { - result = a.compare(b); - } else if (b.compare) { - result = b.compare(a); - } else { - throw { type: "Type", - message: "Unable to perform comparison", - index: i }; - } - switch (result) { - case -1: return op === '<' || op === '=<' || op === '<='; - case 0: return op === '=' || op === '>=' || op === '=<' || op === '<='; - case 1: return op === '>' || op === '>='; - } - } - })(this.op); - return this.negate ? !result : result; - } -}; - -})(require('../tree')); - -(function (tree) { - -// -// A number with a unit -// -tree.Dimension = function (value, unit) { - this.value = parseFloat(value); - this.unit = (unit && unit instanceof tree.Unit) ? unit : - new(tree.Unit)(unit ? [unit] : undefined); -}; - -tree.Dimension.prototype = { - type: "Dimension", - accept: function (visitor) { - this.unit = visitor.visit(this.unit); - }, - eval: function (env) { - return this; - }, - toColor: function () { - return new(tree.Color)([this.value, this.value, this.value]); - }, - genCSS: function (env, output) { - if ((env && env.strictUnits) && !this.unit.isSingular()) { - throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString()); - } - - var value = this.value, - strValue = String(value); - - if (value !== 0 && value < 0.000001 && value > -0.000001) { - // would be output 1e-6 etc. - strValue = value.toFixed(20).replace(/0+$/, ""); - } - - if (env && env.compress) { - // Zero values doesn't need a unit - if (value === 0 && this.unit.isLength()) { - output.add(strValue); - return; - } - - // Float values doesn't need a leading zero - if (value > 0 && value < 1) { - strValue = (strValue).substr(1); - } - } - - output.add(strValue); - this.unit.genCSS(env, output); - }, - toCSS: tree.toCSS, - - // In an operation between two Dimensions, - // we default to the first Dimension's unit, - // so `1px + 2` will yield `3px`. - operate: function (env, op, other) { - /*jshint noempty:false */ - var value = tree.operate(env, op, this.value, other.value), - unit = this.unit.clone(); - - if (op === '+' || op === '-') { - if (unit.numerator.length === 0 && unit.denominator.length === 0) { - unit.numerator = other.unit.numerator.slice(0); - unit.denominator = other.unit.denominator.slice(0); - } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) { - // do nothing - } else { - other = other.convertTo(this.unit.usedUnits()); - - if(env.strictUnits && other.unit.toString() !== unit.toString()) { - throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '" + unit.toString() + - "' and '" + other.unit.toString() + "'."); - } - - value = tree.operate(env, op, this.value, other.value); - } - } else if (op === '*') { - unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); - unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); - unit.cancel(); - } else if (op === '/') { - unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); - unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); - unit.cancel(); - } - return new(tree.Dimension)(value, unit); - }, - - compare: function (other) { - if (other instanceof tree.Dimension) { - var a = this.unify(), b = other.unify(), - aValue = a.value, bValue = b.value; - - if (bValue > aValue) { - return -1; - } else if (bValue < aValue) { - return 1; - } else { - if (!b.unit.isEmpty() && a.unit.compare(b.unit) !== 0) { - return -1; - } - return 0; - } - } else { - return -1; - } - }, - - unify: function () { - return this.convertTo({ length: 'm', duration: 's', angle: 'rad' }); - }, - - convertTo: function (conversions) { - var value = this.value, unit = this.unit.clone(), - i, groupName, group, targetUnit, derivedConversions = {}, applyUnit; - - if (typeof conversions === 'string') { - for(i in tree.UnitConversions) { - if (tree.UnitConversions[i].hasOwnProperty(conversions)) { - derivedConversions = {}; - derivedConversions[i] = conversions; - } - } - conversions = derivedConversions; - } - applyUnit = function (atomicUnit, denominator) { - /*jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit)) { - if (denominator) { - value = value / (group[atomicUnit] / group[targetUnit]); - } else { - value = value * (group[atomicUnit] / group[targetUnit]); - } - - return targetUnit; - } - - return atomicUnit; - }; - - for (groupName in conversions) { - if (conversions.hasOwnProperty(groupName)) { - targetUnit = conversions[groupName]; - group = tree.UnitConversions[groupName]; - - unit.map(applyUnit); - } - } - - unit.cancel(); - - return new(tree.Dimension)(value, unit); - } -}; - -// http://www.w3.org/TR/css3-values/#absolute-lengths -tree.UnitConversions = { - length: { - 'm': 1, - 'cm': 0.01, - 'mm': 0.001, - 'in': 0.0254, - 'pt': 0.0254 / 72, - 'pc': 0.0254 / 72 * 12 - }, - duration: { - 's': 1, - 'ms': 0.001 - }, - angle: { - 'rad': 1/(2*Math.PI), - 'deg': 1/360, - 'grad': 1/400, - 'turn': 1 - } -}; - -tree.Unit = function (numerator, denominator, backupUnit) { - this.numerator = numerator ? numerator.slice(0).sort() : []; - this.denominator = denominator ? denominator.slice(0).sort() : []; - this.backupUnit = backupUnit; -}; - -tree.Unit.prototype = { - type: "Unit", - clone: function () { - return new tree.Unit(this.numerator.slice(0), this.denominator.slice(0), this.backupUnit); - }, - genCSS: function (env, output) { - if (this.numerator.length >= 1) { - output.add(this.numerator[0]); - } else - if (this.denominator.length >= 1) { - output.add(this.denominator[0]); - } else - if ((!env || !env.strictUnits) && this.backupUnit) { - output.add(this.backupUnit); - } - }, - toCSS: tree.toCSS, - - toString: function () { - var i, returnStr = this.numerator.join("*"); - for (i = 0; i < this.denominator.length; i++) { - returnStr += "/" + this.denominator[i]; - } - return returnStr; - }, - - compare: function (other) { - return this.is(other.toString()) ? 0 : -1; - }, - - is: function (unitString) { - return this.toString() === unitString; - }, - - isLength: function () { - return Boolean(this.toCSS().match(/px|em|%|in|cm|mm|pc|pt|ex/)); - }, - - isEmpty: function () { - return this.numerator.length === 0 && this.denominator.length === 0; - }, - - isSingular: function() { - return this.numerator.length <= 1 && this.denominator.length === 0; - }, - - map: function(callback) { - var i; - - for (i = 0; i < this.numerator.length; i++) { - this.numerator[i] = callback(this.numerator[i], false); - } - - for (i = 0; i < this.denominator.length; i++) { - this.denominator[i] = callback(this.denominator[i], true); - } - }, - - usedUnits: function() { - var group, result = {}, mapUnit; - - mapUnit = function (atomicUnit) { - /*jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { - result[groupName] = atomicUnit; - } - - return atomicUnit; - }; - - for (var groupName in tree.UnitConversions) { - if (tree.UnitConversions.hasOwnProperty(groupName)) { - group = tree.UnitConversions[groupName]; - - this.map(mapUnit); - } - } - - return result; - }, - - cancel: function () { - var counter = {}, atomicUnit, i, backup; - - for (i = 0; i < this.numerator.length; i++) { - atomicUnit = this.numerator[i]; - if (!backup) { - backup = atomicUnit; - } - counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; - } - - for (i = 0; i < this.denominator.length; i++) { - atomicUnit = this.denominator[i]; - if (!backup) { - backup = atomicUnit; - } - counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; - } - - this.numerator = []; - this.denominator = []; - - for (atomicUnit in counter) { - if (counter.hasOwnProperty(atomicUnit)) { - var count = counter[atomicUnit]; - - if (count > 0) { - for (i = 0; i < count; i++) { - this.numerator.push(atomicUnit); - } - } else if (count < 0) { - for (i = 0; i < -count; i++) { - this.denominator.push(atomicUnit); - } - } - } - } - - if (this.numerator.length === 0 && this.denominator.length === 0 && backup) { - this.backupUnit = backup; - } - - this.numerator.sort(); - this.denominator.sort(); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Directive = function (name, value, index, currentFileInfo) { - this.name = name; - - if (Array.isArray(value)) { - this.rules = [new(tree.Ruleset)([], value)]; - this.rules[0].allowImports = true; - } else { - this.value = value; - } - this.currentFileInfo = currentFileInfo; - -}; -tree.Directive.prototype = { - type: "Directive", - accept: function (visitor) { - this.rules = visitor.visit(this.rules); - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add(this.name, this.currentFileInfo, this.index); - if (this.rules) { - tree.outputRuleset(env, output, this.rules); - } else { - output.add(' '); - this.value.genCSS(env, output); - output.add(';'); - } - }, - toCSS: tree.toCSS, - eval: function (env) { - var evaldDirective = this; - if (this.rules) { - env.frames.unshift(this); - evaldDirective = new(tree.Directive)(this.name, null, this.index, this.currentFileInfo); - evaldDirective.rules = [this.rules[0].eval(env)]; - evaldDirective.rules[0].root = true; - env.frames.shift(); - } - return evaldDirective; - }, - variable: function (name) { return tree.Ruleset.prototype.variable.call(this.rules[0], name); }, - find: function () { return tree.Ruleset.prototype.find.apply(this.rules[0], arguments); }, - rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.rules[0]); }, - markReferenced: function () { - var i, rules; - this.isReferenced = true; - if (this.rules) { - rules = this.rules[0].rules; - for (i = 0; i < rules.length; i++) { - if (rules[i].markReferenced) { - rules[i].markReferenced(); - } - } - } - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Element = function (combinator, value, index, currentFileInfo) { - this.combinator = combinator instanceof tree.Combinator ? - combinator : new(tree.Combinator)(combinator); - - if (typeof(value) === 'string') { - this.value = value.trim(); - } else if (value) { - this.value = value; - } else { - this.value = ""; - } - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Element.prototype = { - type: "Element", - accept: function (visitor) { - this.combinator = visitor.visit(this.combinator); - this.value = visitor.visit(this.value); - }, - eval: function (env) { - return new(tree.Element)(this.combinator, - this.value.eval ? this.value.eval(env) : this.value, - this.index, - this.currentFileInfo); - }, - genCSS: function (env, output) { - output.add(this.toCSS(env), this.currentFileInfo, this.index); - }, - toCSS: function (env) { - var value = (this.value.toCSS ? this.value.toCSS(env) : this.value); - if (value === '' && this.combinator.value.charAt(0) === '&') { - return ''; - } else { - return this.combinator.toCSS(env || {}) + value; - } - } -}; - -tree.Attribute = function (key, op, value) { - this.key = key; - this.op = op; - this.value = value; -}; -tree.Attribute.prototype = { - type: "Attribute", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - return new(tree.Attribute)(this.key.eval ? this.key.eval(env) : this.key, - this.op, (this.value && this.value.eval) ? this.value.eval(env) : this.value); - }, - genCSS: function (env, output) { - output.add(this.toCSS(env)); - }, - toCSS: function (env) { - var value = this.key.toCSS ? this.key.toCSS(env) : this.key; - - if (this.op) { - value += this.op; - value += (this.value.toCSS ? this.value.toCSS(env) : this.value); - } - - return '[' + value + ']'; - } -}; - -tree.Combinator = function (value) { - if (value === ' ') { - this.value = ' '; - } else { - this.value = value ? value.trim() : ""; - } -}; -tree.Combinator.prototype = { - type: "Combinator", - _outputMap: { - '' : '', - ' ' : ' ', - ':' : ' :', - '+' : ' + ', - '~' : ' ~ ', - '>' : ' > ', - '|' : '|' - }, - _outputMapCompressed: { - '' : '', - ' ' : ' ', - ':' : ' :', - '+' : '+', - '~' : '~', - '>' : '>', - '|' : '|' - }, - genCSS: function (env, output) { - output.add((env.compress ? this._outputMapCompressed : this._outputMap)[this.value]); - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Expression = function (value) { this.value = value; }; -tree.Expression.prototype = { - type: "Expression", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - var returnValue, - inParenthesis = this.parens && !this.parensInOp, - doubleParen = false; - if (inParenthesis) { - env.inParenthesis(); - } - if (this.value.length > 1) { - returnValue = new(tree.Expression)(this.value.map(function (e) { - return e.eval(env); - })); - } else if (this.value.length === 1) { - if (this.value[0].parens && !this.value[0].parensInOp) { - doubleParen = true; - } - returnValue = this.value[0].eval(env); - } else { - returnValue = this; - } - if (inParenthesis) { - env.outOfParenthesis(); - } - if (this.parens && this.parensInOp && !(env.isMathOn()) && !doubleParen) { - returnValue = new(tree.Paren)(returnValue); - } - return returnValue; - }, - genCSS: function (env, output) { - for(var i = 0; i < this.value.length; i++) { - this.value[i].genCSS(env, output); - if (i + 1 < this.value.length) { - output.add(" "); - } - } - }, - toCSS: tree.toCSS, - throwAwayComments: function () { - this.value = this.value.filter(function(v) { - return !(v instanceof tree.Comment); - }); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Extend = function Extend(selector, option, index) { - this.selector = selector; - this.option = option; - this.index = index; - - switch(option) { - case "all": - this.allowBefore = true; - this.allowAfter = true; - break; - default: - this.allowBefore = false; - this.allowAfter = false; - break; - } -}; - -tree.Extend.prototype = { - type: "Extend", - accept: function (visitor) { - this.selector = visitor.visit(this.selector); - }, - eval: function (env) { - return new(tree.Extend)(this.selector.eval(env), this.option, this.index); - }, - clone: function (env) { - return new(tree.Extend)(this.selector, this.option, this.index); - }, - findSelfSelectors: function (selectors) { - var selfElements = [], - i, - selectorElements; - - for(i = 0; i < selectors.length; i++) { - selectorElements = selectors[i].elements; - // duplicate the logic in genCSS function inside the selector node. - // future TODO - move both logics into the selector joiner visitor - if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === "") { - selectorElements[0].combinator.value = ' '; - } - selfElements = selfElements.concat(selectors[i].elements); - } - - this.selfSelectors = [{ elements: selfElements }]; - } -}; - -})(require('../tree')); - -(function (tree) { -// -// CSS @import node -// -// The general strategy here is that we don't want to wait -// for the parsing to be completed, before we start importing -// the file. That's because in the context of a browser, -// most of the time will be spent waiting for the server to respond. -// -// On creation, we push the import path to our import queue, though -// `import,push`, we also pass it a callback, which it'll call once -// the file has been fetched, and parsed. -// -tree.Import = function (path, features, options, index, currentFileInfo) { - this.options = options; - this.index = index; - this.path = path; - this.features = features; - this.currentFileInfo = currentFileInfo; - - if (this.options.less !== undefined || this.options.inline) { - this.css = !this.options.less || this.options.inline; - } else { - var pathValue = this.getPath(); - if (pathValue && /css([\?;].*)?$/.test(pathValue)) { - this.css = true; - } - } -}; - -// -// The actual import node doesn't return anything, when converted to CSS. -// The reason is that it's used at the evaluation stage, so that the rules -// it imports can be treated like any other rules. -// -// In `eval`, we make sure all Import nodes get evaluated, recursively, so -// we end up with a flat structure, which can easily be imported in the parent -// ruleset. -// -tree.Import.prototype = { - type: "Import", - accept: function (visitor) { - this.features = visitor.visit(this.features); - this.path = visitor.visit(this.path); - if (!this.options.inline) { - this.root = visitor.visit(this.root); - } - }, - genCSS: function (env, output) { - if (this.css) { - output.add("@import ", this.currentFileInfo, this.index); - this.path.genCSS(env, output); - if (this.features) { - output.add(" "); - this.features.genCSS(env, output); - } - output.add(';'); - } - }, - toCSS: tree.toCSS, - getPath: function () { - if (this.path instanceof tree.Quoted) { - var path = this.path.value; - return (this.css !== undefined || /(\.[a-z]*$)|([\?;].*)$/.test(path)) ? path : path + '.less'; - } else if (this.path instanceof tree.URL) { - return this.path.value.value; - } - return null; - }, - evalForImport: function (env) { - return new(tree.Import)(this.path.eval(env), this.features, this.options, this.index, this.currentFileInfo); - }, - evalPath: function (env) { - var path = this.path.eval(env); - var rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; - - if (!(path instanceof tree.URL)) { - if (rootpath) { - var pathValue = path.value; - // Add the base path if the import is relative - if (pathValue && env.isPathRelative(pathValue)) { - path.value = rootpath + pathValue; - } - } - path.value = env.normalizePath(path.value); - } - - return path; - }, - eval: function (env) { - var ruleset, features = this.features && this.features.eval(env); - - if (this.skip) { return []; } - - if (this.options.inline) { - //todo needs to reference css file not import - var contents = new(tree.Anonymous)(this.root, 0, {filename: this.importedFilename}, true); - return this.features ? new(tree.Media)([contents], this.features.value) : [contents]; - } else if (this.css) { - var newImport = new(tree.Import)(this.evalPath(env), features, this.options, this.index); - if (!newImport.css && this.error) { - throw this.error; - } - return newImport; - } else { - ruleset = new(tree.Ruleset)([], this.root.rules.slice(0)); - - ruleset.evalImports(env); - - return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules; - } - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.JavaScript = function (string, index, escaped) { - this.escaped = escaped; - this.expression = string; - this.index = index; -}; -tree.JavaScript.prototype = { - type: "JavaScript", - eval: function (env) { - var result, - that = this, - context = {}; - - var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) { - return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env)); - }); - - try { - expression = new(Function)('return (' + expression + ')'); - } catch (e) { - throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`" , - index: this.index }; - } - - for (var k in env.frames[0].variables()) { - /*jshint loopfunc:true */ - context[k.slice(1)] = { - value: env.frames[0].variables()[k].value, - toJS: function () { - return this.value.eval(env).toCSS(); - } - }; - } - - try { - result = expression.call(context); - } catch (e) { - throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" , - index: this.index }; - } - if (typeof(result) === 'string') { - return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index); - } else if (Array.isArray(result)) { - return new(tree.Anonymous)(result.join(', ')); - } else { - return new(tree.Anonymous)(result); - } - } -}; - -})(require('../tree')); - - -(function (tree) { - -tree.Keyword = function (value) { this.value = value; }; -tree.Keyword.prototype = { - type: "Keyword", - eval: function () { return this; }, - genCSS: function (env, output) { - output.add(this.value); - }, - toCSS: tree.toCSS, - compare: function (other) { - if (other instanceof tree.Keyword) { - return other.value === this.value ? 0 : 1; - } else { - return -1; - } - } -}; - -tree.True = new(tree.Keyword)('true'); -tree.False = new(tree.Keyword)('false'); - -})(require('../tree')); - -(function (tree) { - -tree.Media = function (value, features, index, currentFileInfo) { - this.index = index; - this.currentFileInfo = currentFileInfo; - - var selectors = this.emptySelectors(); - - this.features = new(tree.Value)(features); - this.rules = [new(tree.Ruleset)(selectors, value)]; - this.rules[0].allowImports = true; -}; -tree.Media.prototype = { - type: "Media", - accept: function (visitor) { - this.features = visitor.visit(this.features); - this.rules = visitor.visit(this.rules); - }, - genCSS: function (env, output) { - output.add('@media ', this.currentFileInfo, this.index); - this.features.genCSS(env, output); - tree.outputRuleset(env, output, this.rules); - }, - toCSS: tree.toCSS, - eval: function (env) { - if (!env.mediaBlocks) { - env.mediaBlocks = []; - env.mediaPath = []; - } - - var media = new(tree.Media)([], [], this.index, this.currentFileInfo); - if(this.debugInfo) { - this.rules[0].debugInfo = this.debugInfo; - media.debugInfo = this.debugInfo; - } - var strictMathBypass = false; - if (!env.strictMath) { - strictMathBypass = true; - env.strictMath = true; - } - try { - media.features = this.features.eval(env); - } - finally { - if (strictMathBypass) { - env.strictMath = false; - } - } - - env.mediaPath.push(media); - env.mediaBlocks.push(media); - - env.frames.unshift(this.rules[0]); - media.rules = [this.rules[0].eval(env)]; - env.frames.shift(); - - env.mediaPath.pop(); - - return env.mediaPath.length === 0 ? media.evalTop(env) : - media.evalNested(env); - }, - variable: function (name) { return tree.Ruleset.prototype.variable.call(this.rules[0], name); }, - find: function () { return tree.Ruleset.prototype.find.apply(this.rules[0], arguments); }, - rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.rules[0]); }, - emptySelectors: function() { - var el = new(tree.Element)('', '&', this.index, this.currentFileInfo); - return [new(tree.Selector)([el], null, null, this.index, this.currentFileInfo)]; - }, - markReferenced: function () { - var i, rules = this.rules[0].rules; - this.isReferenced = true; - for (i = 0; i < rules.length; i++) { - if (rules[i].markReferenced) { - rules[i].markReferenced(); - } - } - }, - - evalTop: function (env) { - var result = this; - - // Render all dependent Media blocks. - if (env.mediaBlocks.length > 1) { - var selectors = this.emptySelectors(); - result = new(tree.Ruleset)(selectors, env.mediaBlocks); - result.multiMedia = true; - } - - delete env.mediaBlocks; - delete env.mediaPath; - - return result; - }, - evalNested: function (env) { - var i, value, - path = env.mediaPath.concat([this]); - - // Extract the media-query conditions separated with `,` (OR). - for (i = 0; i < path.length; i++) { - value = path[i].features instanceof tree.Value ? - path[i].features.value : path[i].features; - path[i] = Array.isArray(value) ? value : [value]; - } - - // Trace all permutations to generate the resulting media-query. - // - // (a, b and c) with nested (d, e) -> - // a and d - // a and e - // b and c and d - // b and c and e - this.features = new(tree.Value)(this.permute(path).map(function (path) { - path = path.map(function (fragment) { - return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment); - }); - - for(i = path.length - 1; i > 0; i--) { - path.splice(i, 0, new(tree.Anonymous)("and")); - } - - return new(tree.Expression)(path); - })); - - // Fake a tree-node that doesn't output anything. - return new(tree.Ruleset)([], []); - }, - permute: function (arr) { - if (arr.length === 0) { - return []; - } else if (arr.length === 1) { - return arr[0]; - } else { - var result = []; - var rest = this.permute(arr.slice(1)); - for (var i = 0; i < rest.length; i++) { - for (var j = 0; j < arr[0].length; j++) { - result.push([arr[0][j]].concat(rest[i])); - } - } - return result; - } - }, - bubbleSelectors: function (selectors) { - this.rules = [new(tree.Ruleset)(selectors.slice(0), [this.rules[0]])]; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.mixin = {}; -tree.mixin.Call = function (elements, args, index, currentFileInfo, important) { - this.selector = new(tree.Selector)(elements); - this.arguments = args; - this.index = index; - this.currentFileInfo = currentFileInfo; - this.important = important; -}; -tree.mixin.Call.prototype = { - type: "MixinCall", - accept: function (visitor) { - this.selector = visitor.visit(this.selector); - this.arguments = visitor.visit(this.arguments); - }, - eval: function (env) { - var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule; - - args = this.arguments && this.arguments.map(function (a) { - return { name: a.name, value: a.value.eval(env) }; - }); - - for (i = 0; i < env.frames.length; i++) { - if ((mixins = env.frames[i].find(this.selector)).length > 0) { - isOneFound = true; - for (m = 0; m < mixins.length; m++) { - mixin = mixins[m]; - isRecursive = false; - for(f = 0; f < env.frames.length; f++) { - if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) { - isRecursive = true; - break; - } - } - if (isRecursive) { - continue; - } - if (mixin.matchArgs(args, env)) { - if (!mixin.matchCondition || mixin.matchCondition(args, env)) { - try { - if (!(mixin instanceof tree.mixin.Definition)) { - mixin = new tree.mixin.Definition("", [], mixin.rules, null, false); - mixin.originalRuleset = mixins[m].originalRuleset || mixins[m]; - } - //if (this.important) { - // isImportant = env.isImportant; - // env.isImportant = true; - //} - Array.prototype.push.apply( - rules, mixin.eval(env, args, this.important).rules); - //if (this.important) { - // env.isImportant = isImportant; - //} - } catch (e) { - throw { message: e.message, index: this.index, filename: this.currentFileInfo.filename, stack: e.stack }; - } - } - match = true; - } - } - if (match) { - if (!this.currentFileInfo || !this.currentFileInfo.reference) { - for (i = 0; i < rules.length; i++) { - rule = rules[i]; - if (rule.markReferenced) { - rule.markReferenced(); - } - } - } - return rules; - } - } - } - if (isOneFound) { - throw { type: 'Runtime', - message: 'No matching definition was found for `' + - this.selector.toCSS().trim() + '(' + - (args ? args.map(function (a) { - var argValue = ""; - if (a.name) { - argValue += a.name + ":"; - } - if (a.value.toCSS) { - argValue += a.value.toCSS(); - } else { - argValue += "???"; - } - return argValue; - }).join(', ') : "") + ")`", - index: this.index, filename: this.currentFileInfo.filename }; - } else { - throw { type: 'Name', - message: this.selector.toCSS().trim() + " is undefined", - index: this.index, filename: this.currentFileInfo.filename }; - } - } -}; - -tree.mixin.Definition = function (name, params, rules, condition, variadic) { - this.name = name; - this.selectors = [new(tree.Selector)([new(tree.Element)(null, name, this.index, this.currentFileInfo)])]; - this.params = params; - this.condition = condition; - this.variadic = variadic; - this.arity = params.length; - this.rules = rules; - this._lookups = {}; - this.required = params.reduce(function (count, p) { - if (!p.name || (p.name && !p.value)) { return count + 1; } - else { return count; } - }, 0); - this.parent = tree.Ruleset.prototype; - this.frames = []; -}; -tree.mixin.Definition.prototype = { - type: "MixinDefinition", - accept: function (visitor) { - this.params = visitor.visit(this.params); - this.rules = visitor.visit(this.rules); - this.condition = visitor.visit(this.condition); - }, - variable: function (name) { return this.parent.variable.call(this, name); }, - variables: function () { return this.parent.variables.call(this); }, - find: function () { return this.parent.find.apply(this, arguments); }, - rulesets: function () { return this.parent.rulesets.apply(this); }, - - evalParams: function (env, mixinEnv, args, evaldArguments) { - /*jshint boss:true */ - var frame = new(tree.Ruleset)(null, []), - varargs, arg, - params = this.params.slice(0), - i, j, val, name, isNamedFound, argIndex; - - mixinEnv = new tree.evalEnv(mixinEnv, [frame].concat(mixinEnv.frames)); - - if (args) { - args = args.slice(0); - - for(i = 0; i < args.length; i++) { - arg = args[i]; - if (name = (arg && arg.name)) { - isNamedFound = false; - for(j = 0; j < params.length; j++) { - if (!evaldArguments[j] && name === params[j].name) { - evaldArguments[j] = arg.value.eval(env); - frame.rules.unshift(new(tree.Rule)(name, arg.value.eval(env))); - isNamedFound = true; - break; - } - } - if (isNamedFound) { - args.splice(i, 1); - i--; - continue; - } else { - throw { type: 'Runtime', message: "Named argument for " + this.name + - ' ' + args[i].name + ' not found' }; - } - } - } - } - argIndex = 0; - for (i = 0; i < params.length; i++) { - if (evaldArguments[i]) { continue; } - - arg = args && args[argIndex]; - - if (name = params[i].name) { - if (params[i].variadic && args) { - varargs = []; - for (j = argIndex; j < args.length; j++) { - varargs.push(args[j].value.eval(env)); - } - frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env))); - } else { - val = arg && arg.value; - if (val) { - val = val.eval(env); - } else if (params[i].value) { - val = params[i].value.eval(mixinEnv); - frame.resetCache(); - } else { - throw { type: 'Runtime', message: "wrong number of arguments for " + this.name + - ' (' + args.length + ' for ' + this.arity + ')' }; - } - - frame.rules.unshift(new(tree.Rule)(name, val)); - evaldArguments[i] = val; - } - } - - if (params[i].variadic && args) { - for (j = argIndex; j < args.length; j++) { - evaldArguments[j] = args[j].value.eval(env); - } - } - argIndex++; - } - - return frame; - }, - eval: function (env, args, important) { - var _arguments = [], - mixinFrames = this.frames.concat(env.frames), - frame = this.evalParams(env, new(tree.evalEnv)(env, mixinFrames), args, _arguments), - rules, ruleset; - - frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env))); - - rules = this.rules.slice(0); - - ruleset = new(tree.Ruleset)(null, rules); - ruleset.originalRuleset = this; - ruleset = ruleset.eval(new(tree.evalEnv)(env, [this, frame].concat(mixinFrames))); - if (important) { - ruleset = this.parent.makeImportant.apply(ruleset); - } - return ruleset; - }, - matchCondition: function (args, env) { - if (this.condition && !this.condition.eval( - new(tree.evalEnv)(env, - [this.evalParams(env, new(tree.evalEnv)(env, this.frames.concat(env.frames)), args, [])] // the parameter variables - .concat(this.frames) // the parent namespace/mixin frames - .concat(env.frames)))) { // the current environment frames - return false; - } - return true; - }, - matchArgs: function (args, env) { - var argsLength = (args && args.length) || 0, len; - - if (! this.variadic) { - if (argsLength < this.required) { return false; } - if (argsLength > this.params.length) { return false; } - } else { - if (argsLength < (this.required - 1)) { return false; } - } - - len = Math.min(argsLength, this.arity); - - for (var i = 0; i < len; i++) { - if (!this.params[i].name && !this.params[i].variadic) { - if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) { - return false; - } - } - } - return true; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Negative = function (node) { - this.value = node; -}; -tree.Negative.prototype = { - type: "Negative", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add('-'); - this.value.genCSS(env, output); - }, - toCSS: tree.toCSS, - eval: function (env) { - if (env.isMathOn()) { - return (new(tree.Operation)('*', [new(tree.Dimension)(-1), this.value])).eval(env); - } - return new(tree.Negative)(this.value.eval(env)); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Operation = function (op, operands, isSpaced) { - this.op = op.trim(); - this.operands = operands; - this.isSpaced = isSpaced; -}; -tree.Operation.prototype = { - type: "Operation", - accept: function (visitor) { - this.operands = visitor.visit(this.operands); - }, - eval: function (env) { - var a = this.operands[0].eval(env), - b = this.operands[1].eval(env), - temp; - - if (env.isMathOn()) { - if (a instanceof tree.Dimension && b instanceof tree.Color) { - if (this.op === '*' || this.op === '+') { - temp = b, b = a, a = temp; - } else { - throw { type: "Operation", - message: "Can't substract or divide a color from a number" }; - } - } - if (!a.operate) { - throw { type: "Operation", - message: "Operation on an invalid type" }; - } - - return a.operate(env, this.op, b); - } else { - return new(tree.Operation)(this.op, [a, b], this.isSpaced); - } - }, - genCSS: function (env, output) { - this.operands[0].genCSS(env, output); - if (this.isSpaced) { - output.add(" "); - } - output.add(this.op); - if (this.isSpaced) { - output.add(" "); - } - this.operands[1].genCSS(env, output); - }, - toCSS: tree.toCSS -}; - -tree.operate = function (env, op, a, b) { - switch (op) { - case '+': return a + b; - case '-': return a - b; - case '*': return a * b; - case '/': return a / b; - } -}; - -})(require('../tree')); - - -(function (tree) { - -tree.Paren = function (node) { - this.value = node; -}; -tree.Paren.prototype = { - type: "Paren", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add('('); - this.value.genCSS(env, output); - output.add(')'); - }, - toCSS: tree.toCSS, - eval: function (env) { - return new(tree.Paren)(this.value.eval(env)); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Quoted = function (str, content, escaped, index, currentFileInfo) { - this.escaped = escaped; - this.value = content || ''; - this.quote = str.charAt(0); - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Quoted.prototype = { - type: "Quoted", - genCSS: function (env, output) { - if (!this.escaped) { - output.add(this.quote, this.currentFileInfo, this.index); - } - output.add(this.value); - if (!this.escaped) { - output.add(this.quote); - } - }, - toCSS: tree.toCSS, - eval: function (env) { - var that = this; - var value = this.value.replace(/`([^`]+)`/g, function (_, exp) { - return new(tree.JavaScript)(exp, that.index, true).eval(env).value; - }).replace(/@\{([\w-]+)\}/g, function (_, name) { - var v = new(tree.Variable)('@' + name, that.index, that.currentFileInfo).eval(env, true); - return (v instanceof tree.Quoted) ? v.value : v.toCSS(); - }); - return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index, this.currentFileInfo); - }, - compare: function (x) { - if (!x.toCSS) { - return -1; - } - - var left = this.toCSS(), - right = x.toCSS(); - - if (left === right) { - return 0; - } - - return left < right ? -1 : 1; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Rule = function (name, value, important, merge, index, currentFileInfo, inline) { - this.name = name; - this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]); - this.important = important ? ' ' + important.trim() : ''; - this.merge = merge; - this.index = index; - this.currentFileInfo = currentFileInfo; - this.inline = inline || false; - this.variable = (name.charAt(0) === '@'); -}; - -tree.Rule.prototype = { - type: "Rule", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add(this.name + (env.compress ? ':' : ': '), this.currentFileInfo, this.index); - try { - this.value.genCSS(env, output); - } - catch(e) { - e.index = this.index; - e.filename = this.currentFileInfo.filename; - throw e; - } - output.add(this.important + ((this.inline || (env.lastRule && env.compress)) ? "" : ";"), this.currentFileInfo, this.index); - }, - toCSS: tree.toCSS, - eval: function (env) { - var strictMathBypass = false; - if (this.name === "font" && !env.strictMath) { - strictMathBypass = true; - env.strictMath = true; - } - try { - return new(tree.Rule)(this.name, - this.value.eval(env), - this.important, - this.merge, - this.index, this.currentFileInfo, this.inline); - } - finally { - if (strictMathBypass) { - env.strictMath = false; - } - } - }, - makeImportant: function () { - return new(tree.Rule)(this.name, - this.value, - "!important", - this.merge, - this.index, this.currentFileInfo, this.inline); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Ruleset = function (selectors, rules, strictImports) { - this.selectors = selectors; - this.rules = rules; - this._lookups = {}; - this.strictImports = strictImports; -}; -tree.Ruleset.prototype = { - type: "Ruleset", - accept: function (visitor) { - if (this.paths) { - for(var i = 0; i < this.paths.length; i++) { - this.paths[i] = visitor.visit(this.paths[i]); - } - } else { - this.selectors = visitor.visit(this.selectors); - } - this.rules = visitor.visit(this.rules); - }, - eval: function (env) { - var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env); }); - var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0), this.strictImports); - var rules; - var rule; - var i; - - ruleset.originalRuleset = this; - ruleset.root = this.root; - ruleset.firstRoot = this.firstRoot; - ruleset.allowImports = this.allowImports; - - if(this.debugInfo) { - ruleset.debugInfo = this.debugInfo; - } - - // push the current ruleset to the frames stack - env.frames.unshift(ruleset); - - // currrent selectors - if (!env.selectors) { - env.selectors = []; - } - env.selectors.unshift(this.selectors); - - // Evaluate imports - if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { - ruleset.evalImports(env); - } - - // Store the frames around mixin definitions, - // so they can be evaluated like closures when the time comes. - for (i = 0; i < ruleset.rules.length; i++) { - if (ruleset.rules[i] instanceof tree.mixin.Definition) { - ruleset.rules[i].frames = env.frames.slice(0); - } - } - - var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0; - - // Evaluate mixin calls. - for (i = 0; i < ruleset.rules.length; i++) { - if (ruleset.rules[i] instanceof tree.mixin.Call) { - /*jshint loopfunc:true */ - rules = ruleset.rules[i].eval(env).filter(function(r) { - if ((r instanceof tree.Rule) && r.variable) { - // do not pollute the scope if the variable is - // already there. consider returning false here - // but we need a way to "return" variable from mixins - return !(ruleset.variable(r.name)); - } - return true; - }); - ruleset.rules.splice.apply(ruleset.rules, [i, 1].concat(rules)); - i += rules.length-1; - ruleset.resetCache(); - } - } - - // Evaluate everything else - for (i = 0; i < ruleset.rules.length; i++) { - rule = ruleset.rules[i]; - - if (! (rule instanceof tree.mixin.Definition)) { - ruleset.rules[i] = rule.eval ? rule.eval(env) : rule; - } - } - - // Pop the stack - env.frames.shift(); - env.selectors.shift(); - - if (env.mediaBlocks) { - for (i = mediaBlockCount; i < env.mediaBlocks.length; i++) { - env.mediaBlocks[i].bubbleSelectors(selectors); - } - } - - return ruleset; - }, - evalImports: function(env) { - var i, rules; - for (i = 0; i < this.rules.length; i++) { - if (this.rules[i] instanceof tree.Import) { - rules = this.rules[i].eval(env); - if (typeof rules.length === "number") { - this.rules.splice.apply(this.rules, [i, 1].concat(rules)); - i+= rules.length-1; - } else { - this.rules.splice(i, 1, rules); - } - this.resetCache(); - } - } - }, - makeImportant: function() { - return new tree.Ruleset(this.selectors, this.rules.map(function (r) { - if (r.makeImportant) { - return r.makeImportant(); - } else { - return r; - } - }), this.strictImports); - }, - matchArgs: function (args) { - return !args || args.length === 0; - }, - matchCondition: function (args, env) { - var lastSelector = this.selectors[this.selectors.length-1]; - if (lastSelector.condition && - !lastSelector.condition.eval( - new(tree.evalEnv)(env, - env.frames))) { - return false; - } - return true; - }, - resetCache: function () { - this._rulesets = null; - this._variables = null; - this._lookups = {}; - }, - variables: function () { - if (this._variables) { return this._variables; } - else { - return this._variables = this.rules.reduce(function (hash, r) { - if (r instanceof tree.Rule && r.variable === true) { - hash[r.name] = r; - } - return hash; - }, {}); - } - }, - variable: function (name) { - return this.variables()[name]; - }, - rulesets: function () { - return this.rules.filter(function (r) { - return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition); - }); - }, - find: function (selector, self) { - self = self || this; - var rules = [], match, - key = selector.toCSS(); - - if (key in this._lookups) { return this._lookups[key]; } - - this.rulesets().forEach(function (rule) { - if (rule !== self) { - for (var j = 0; j < rule.selectors.length; j++) { - if (match = selector.match(rule.selectors[j])) { - if (selector.elements.length > match) { - Array.prototype.push.apply(rules, rule.find( - new(tree.Selector)(selector.elements.slice(match)), self)); - } else { - rules.push(rule); - } - break; - } - } - } - }); - return this._lookups[key] = rules; - }, - genCSS: function (env, output) { - var i, j, - ruleNodes = [], - rulesetNodes = [], - debugInfo, // Line number debugging - rule, - firstRuleset = true, - path; - - env.tabLevel = (env.tabLevel || 0); - - if (!this.root) { - env.tabLevel++; - } - - var tabRuleStr = env.compress ? '' : Array(env.tabLevel + 1).join(" "), - tabSetStr = env.compress ? '' : Array(env.tabLevel).join(" "); - - for (i = 0; i < this.rules.length; i++) { - rule = this.rules[i]; - if (rule.rules || (rule instanceof tree.Media) || rule instanceof tree.Directive || (this.root && rule instanceof tree.Comment)) { - rulesetNodes.push(rule); - } else { - ruleNodes.push(rule); - } - } - - // If this is the root node, we don't render - // a selector, or {}. - if (!this.root) { - debugInfo = tree.debugInfo(env, this, tabSetStr); - - if (debugInfo) { - output.add(debugInfo); - output.add(tabSetStr); - } - - for(i = 0; i < this.paths.length; i++) { - path = this.paths[i]; - env.firstSelector = true; - for(j = 0; j < path.length; j++) { - path[j].genCSS(env, output); - env.firstSelector = false; - } - if (i + 1 < this.paths.length) { - output.add(env.compress ? ',' : (',\n' + tabSetStr)); - } - } - - output.add((env.compress ? '{' : ' {\n') + tabRuleStr); - } - - // Compile rules and rulesets - for (i = 0; i < ruleNodes.length; i++) { - rule = ruleNodes[i]; - - // @page{ directive ends up with root elements inside it, a mix of rules and rulesets - // In this instance we do not know whether it is the last property - if (i + 1 === ruleNodes.length && (!this.root || rulesetNodes.length === 0 || this.firstRoot)) { - env.lastRule = true; - } - - if (rule.genCSS) { - rule.genCSS(env, output); - } else if (rule.value) { - output.add(rule.value.toString()); - } - - if (!env.lastRule) { - output.add(env.compress ? '' : ('\n' + tabRuleStr)); - } else { - env.lastRule = false; - } - } - - if (!this.root) { - output.add((env.compress ? '}' : '\n' + tabSetStr + '}')); - env.tabLevel--; - } - - for (i = 0; i < rulesetNodes.length; i++) { - if (ruleNodes.length && firstRuleset) { - output.add((env.compress ? "" : "\n") + (this.root ? tabRuleStr : tabSetStr)); - } - if (!firstRuleset) { - output.add((env.compress ? "" : "\n") + (this.root ? tabRuleStr : tabSetStr)); - } - firstRuleset = false; - rulesetNodes[i].genCSS(env, output); - } - - if (!output.isEmpty() && !env.compress && this.firstRoot) { - output.add('\n'); - } - }, - - toCSS: tree.toCSS, - - markReferenced: function () { - for (var s = 0; s < this.selectors.length; s++) { - this.selectors[s].markReferenced(); - } - }, - - joinSelectors: function (paths, context, selectors) { - for (var s = 0; s < selectors.length; s++) { - this.joinSelector(paths, context, selectors[s]); - } - }, - - joinSelector: function (paths, context, selector) { - - var i, j, k, - hasParentSelector, newSelectors, el, sel, parentSel, - newSelectorPath, afterParentJoin, newJoinedSelector, - newJoinedSelectorEmpty, lastSelector, currentElements, - selectorsMultiplied; - - for (i = 0; i < selector.elements.length; i++) { - el = selector.elements[i]; - if (el.value === '&') { - hasParentSelector = true; - } - } - - if (!hasParentSelector) { - if (context.length > 0) { - for (i = 0; i < context.length; i++) { - paths.push(context[i].concat(selector)); - } - } - else { - paths.push([selector]); - } - return; - } - - // The paths are [[Selector]] - // The first list is a list of comma seperated selectors - // The inner list is a list of inheritance seperated selectors - // e.g. - // .a, .b { - // .c { - // } - // } - // == [[.a] [.c]] [[.b] [.c]] - // - - // the elements from the current selector so far - currentElements = []; - // the current list of new selectors to add to the path. - // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors - // by the parents - newSelectors = [[]]; - - for (i = 0; i < selector.elements.length; i++) { - el = selector.elements[i]; - // non parent reference elements just get added - if (el.value !== "&") { - currentElements.push(el); - } else { - // the new list of selectors to add - selectorsMultiplied = []; - - // merge the current list of non parent selector elements - // on to the current list of selectors to add - if (currentElements.length > 0) { - this.mergeElementsOnToSelectors(currentElements, newSelectors); - } - - // loop through our current selectors - for (j = 0; j < newSelectors.length; j++) { - sel = newSelectors[j]; - // if we don't have any parent paths, the & might be in a mixin so that it can be used - // whether there are parents or not - if (context.length === 0) { - // the combinator used on el should now be applied to the next element instead so that - // it is not lost - if (sel.length > 0) { - sel[0].elements = sel[0].elements.slice(0); - sel[0].elements.push(new(tree.Element)(el.combinator, '', 0, el.index, el.currentFileInfo)); - } - selectorsMultiplied.push(sel); - } - else { - // and the parent selectors - for (k = 0; k < context.length; k++) { - parentSel = context[k]; - // We need to put the current selectors - // then join the last selector's elements on to the parents selectors - - // our new selector path - newSelectorPath = []; - // selectors from the parent after the join - afterParentJoin = []; - newJoinedSelectorEmpty = true; - - //construct the joined selector - if & is the first thing this will be empty, - // if not newJoinedSelector will be the last set of elements in the selector - if (sel.length > 0) { - newSelectorPath = sel.slice(0); - lastSelector = newSelectorPath.pop(); - newJoinedSelector = selector.createDerived(lastSelector.elements.slice(0)); - newJoinedSelectorEmpty = false; - } - else { - newJoinedSelector = selector.createDerived([]); - } - - //put together the parent selectors after the join - if (parentSel.length > 1) { - afterParentJoin = afterParentJoin.concat(parentSel.slice(1)); - } - - if (parentSel.length > 0) { - newJoinedSelectorEmpty = false; - - // join the elements so far with the first part of the parent - newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, el.index, el.currentFileInfo)); - newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1)); - } - - if (!newJoinedSelectorEmpty) { - // now add the joined selector - newSelectorPath.push(newJoinedSelector); - } - - // and the rest of the parent - newSelectorPath = newSelectorPath.concat(afterParentJoin); - - // add that to our new set of selectors - selectorsMultiplied.push(newSelectorPath); - } - } - } - - // our new selectors has been multiplied, so reset the state - newSelectors = selectorsMultiplied; - currentElements = []; - } - } - - // if we have any elements left over (e.g. .a& .b == .b) - // add them on to all the current selectors - if (currentElements.length > 0) { - this.mergeElementsOnToSelectors(currentElements, newSelectors); - } - - for (i = 0; i < newSelectors.length; i++) { - if (newSelectors[i].length > 0) { - paths.push(newSelectors[i]); - } - } - }, - - mergeElementsOnToSelectors: function(elements, selectors) { - var i, sel; - - if (selectors.length === 0) { - selectors.push([ new(tree.Selector)(elements) ]); - return; - } - - for (i = 0; i < selectors.length; i++) { - sel = selectors[i]; - - // if the previous thing in sel is a parent this needs to join on to it - if (sel.length > 0) { - sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); - } - else { - sel.push(new(tree.Selector)(elements)); - } - } - } -}; -})(require('../tree')); - -(function (tree) { - -tree.Selector = function (elements, extendList, condition, index, currentFileInfo, isReferenced) { - this.elements = elements; - this.extendList = extendList || []; - this.condition = condition; - this.currentFileInfo = currentFileInfo || {}; - this.isReferenced = isReferenced; - if (!condition) { - this.evaldCondition = true; - } -}; -tree.Selector.prototype = { - type: "Selector", - accept: function (visitor) { - this.elements = visitor.visit(this.elements); - this.extendList = visitor.visit(this.extendList); - this.condition = visitor.visit(this.condition); - }, - createDerived: function(elements, extendList, evaldCondition) { - /*jshint eqnull:true */ - evaldCondition = evaldCondition != null ? evaldCondition : this.evaldCondition; - var newSelector = new(tree.Selector)(elements, extendList || this.extendList, this.condition, this.index, this.currentFileInfo, this.isReferenced); - newSelector.evaldCondition = evaldCondition; - return newSelector; - }, - match: function (other) { - var elements = this.elements, - len = elements.length, - oelements, olen, max, i; - - oelements = other.elements.slice( - (other.elements.length && other.elements[0].value === "&") ? 1 : 0); - olen = oelements.length; - max = Math.min(len, olen); - - if (olen === 0 || len < olen) { - return 0; - } else { - for (i = 0; i < max; i++) { - if (elements[i].value !== oelements[i].value) { - return 0; - } - } - } - return max; // return number of matched selectors - }, - eval: function (env) { - var evaldCondition = this.condition && this.condition.eval(env); - - return this.createDerived(this.elements.map(function (e) { - return e.eval(env); - }), this.extendList.map(function(extend) { - return extend.eval(env); - }), evaldCondition); - }, - genCSS: function (env, output) { - var i, element; - if ((!env || !env.firstSelector) && this.elements[0].combinator.value === "") { - output.add(' ', this.currentFileInfo, this.index); - } - if (!this._css) { - //TODO caching? speed comparison? - for(i = 0; i < this.elements.length; i++) { - element = this.elements[i]; - element.genCSS(env, output); - } - } - }, - toCSS: tree.toCSS, - markReferenced: function () { - this.isReferenced = true; - }, - getIsReferenced: function() { - return !this.currentFileInfo.reference || this.isReferenced; - }, - getIsOutput: function() { - return this.evaldCondition; - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.UnicodeDescriptor = function (value) { - this.value = value; -}; -tree.UnicodeDescriptor.prototype = { - type: "UnicodeDescriptor", - genCSS: function (env, output) { - output.add(this.value); - }, - toCSS: tree.toCSS, - eval: function () { return this; } -}; - -})(require('../tree')); - -(function (tree) { - -tree.URL = function (val, currentFileInfo) { - this.value = val; - this.currentFileInfo = currentFileInfo; -}; -tree.URL.prototype = { - type: "Url", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - genCSS: function (env, output) { - output.add("url("); - this.value.genCSS(env, output); - output.add(")"); - }, - toCSS: tree.toCSS, - eval: function (ctx) { - var val = this.value.eval(ctx), rootpath; - - // Add the base path if the URL is relative - rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; - if (rootpath && typeof val.value === "string" && ctx.isPathRelative(val.value)) { - if (!val.quote) { - rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; }); - } - val.value = rootpath + val.value; - } - - val.value = ctx.normalizePath(val.value); - - return new(tree.URL)(val, null); - } -}; - -})(require('../tree')); - -(function (tree) { - -tree.Value = function (value) { - this.value = value; -}; -tree.Value.prototype = { - type: "Value", - accept: function (visitor) { - this.value = visitor.visit(this.value); - }, - eval: function (env) { - if (this.value.length === 1) { - return this.value[0].eval(env); - } else { - return new(tree.Value)(this.value.map(function (v) { - return v.eval(env); - })); - } - }, - genCSS: function (env, output) { - var i; - for(i = 0; i < this.value.length; i++) { - this.value[i].genCSS(env, output); - if (i+1 < this.value.length) { - output.add((env && env.compress) ? ',' : ', '); - } - } - }, - toCSS: tree.toCSS -}; - -})(require('../tree')); - -(function (tree) { - -tree.Variable = function (name, index, currentFileInfo) { - this.name = name; - this.index = index; - this.currentFileInfo = currentFileInfo; -}; -tree.Variable.prototype = { - type: "Variable", - eval: function (env) { - var variable, v, name = this.name; - - if (name.indexOf('@@') === 0) { - name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value; - } - - if (this.evaluating) { - throw { type: 'Name', - message: "Recursive variable definition for " + name, - filename: this.currentFileInfo.file, - index: this.index }; - } - - this.evaluating = true; - - if (variable = tree.find(env.frames, function (frame) { - if (v = frame.variable(name)) { - return v.value.eval(env); - } - })) { - this.evaluating = false; - return variable; - } - else { - throw { type: 'Name', - message: "variable " + name + " is undefined", - filename: this.currentFileInfo.filename, - index: this.index }; - } - } -}; - -})(require('../tree')); - -(function (tree) { - - var parseCopyProperties = [ - 'paths', // option - unmodified - paths to search for imports on - 'optimization', // option - optimization level (for the chunker) - 'files', // list of files that have been imported, used for import-once - 'contents', // browser-only, contents of all the files - 'relativeUrls', // option - whether to adjust URL's to be relative - 'rootpath', // option - rootpath to append to URL's - 'strictImports', // option - - 'insecure', // option - whether to allow imports from insecure ssl hosts - 'dumpLineNumbers', // option - whether to dump line numbers - 'compress', // option - whether to compress - 'processImports', // option - whether to process imports. if false then imports will not be imported - 'syncImport', // option - whether to import synchronously - 'javascriptEnabled',// option - whether JavaScript is enabled. if undefined, defaults to true - 'mime', // browser only - mime type for sheet import - 'useFileCache', // browser only - whether to use the per file session cache - 'currentFileInfo' // information about the current file - for error reporting and importing and making urls relative etc. - ]; - - //currentFileInfo = { - // 'relativeUrls' - option - whether to adjust URL's to be relative - // 'filename' - full resolved filename of current file - // 'rootpath' - path to append to normal URLs for this node - // 'currentDirectory' - path to the current file, absolute - // 'rootFilename' - filename of the base file - // 'entryPath' - absolute path to the entry file - // 'reference' - whether the file should not be output and only output parts that are referenced - - tree.parseEnv = function(options) { - copyFromOriginal(options, this, parseCopyProperties); - - if (!this.contents) { this.contents = {}; } - if (!this.files) { this.files = {}; } - - if (!this.currentFileInfo) { - var filename = (options && options.filename) || "input"; - var entryPath = filename.replace(/[^\/\\]*$/, ""); - if (options) { - options.filename = null; - } - this.currentFileInfo = { - filename: filename, - relativeUrls: this.relativeUrls, - rootpath: (options && options.rootpath) || "", - currentDirectory: entryPath, - entryPath: entryPath, - rootFilename: filename - }; - } - }; - - var evalCopyProperties = [ - 'silent', // whether to swallow errors and warnings - 'verbose', // whether to log more activity - 'compress', // whether to compress - 'yuicompress', // whether to compress with the outside tool yui compressor - 'ieCompat', // whether to enforce IE compatibility (IE8 data-uri) - 'strictMath', // whether math has to be within parenthesis - 'strictUnits', // whether units need to evaluate correctly - 'cleancss', // whether to compress with clean-css - 'sourceMap', // whether to output a source map - 'importMultiple'// whether we are currently importing multiple copies - ]; - - tree.evalEnv = function(options, frames) { - copyFromOriginal(options, this, evalCopyProperties); - - this.frames = frames || []; - }; - - tree.evalEnv.prototype.inParenthesis = function () { - if (!this.parensStack) { - this.parensStack = []; - } - this.parensStack.push(true); - }; - - tree.evalEnv.prototype.outOfParenthesis = function () { - this.parensStack.pop(); - }; - - tree.evalEnv.prototype.isMathOn = function () { - return this.strictMath ? (this.parensStack && this.parensStack.length) : true; - }; - - tree.evalEnv.prototype.isPathRelative = function (path) { - return !/^(?:[a-z-]+:|\/)/.test(path); - }; - - tree.evalEnv.prototype.normalizePath = function( path ) { - var - segments = path.split("/").reverse(), - segment; - - path = []; - while (segments.length !== 0 ) { - segment = segments.pop(); - switch( segment ) { - case ".": - break; - case "..": - if ((path.length === 0) || (path[path.length - 1] === "..")) { - path.push( segment ); - } else { - path.pop(); - } - break; - default: - path.push( segment ); - break; - } - } - - return path.join("/"); - }; - - //todo - do the same for the toCSS env - //tree.toCSSEnv = function (options) { - //}; - - var copyFromOriginal = function(original, destination, propertiesToCopy) { - if (!original) { return; } - - for(var i = 0; i < propertiesToCopy.length; i++) { - if (original.hasOwnProperty(propertiesToCopy[i])) { - destination[propertiesToCopy[i]] = original[propertiesToCopy[i]]; - } - } - }; - -})(require('./tree')); - -(function (tree) { - - tree.visitor = function(implementation) { - this._implementation = implementation; - }; - - tree.visitor.prototype = { - visit: function(node) { - - if (node instanceof Array) { - return this.visitArray(node); - } - - if (!node || !node.type) { - return node; - } - - var funcName = "visit" + node.type, - func = this._implementation[funcName], - visitArgs, newNode; - if (func) { - visitArgs = {visitDeeper: true}; - newNode = func.call(this._implementation, node, visitArgs); - if (this._implementation.isReplacing) { - node = newNode; - } - } - if ((!visitArgs || visitArgs.visitDeeper) && node && node.accept) { - node.accept(this); - } - funcName = funcName + "Out"; - if (this._implementation[funcName]) { - this._implementation[funcName](node); - } - return node; - }, - visitArray: function(nodes) { - var i, newNodes = []; - for(i = 0; i < nodes.length; i++) { - var evald = this.visit(nodes[i]); - if (evald instanceof Array) { - evald = this.flatten(evald); - newNodes = newNodes.concat(evald); - } else { - newNodes.push(evald); - } - } - if (this._implementation.isReplacing) { - return newNodes; - } - return nodes; - }, - doAccept: function (node) { - node.accept(this); - }, - flatten: function(arr, master) { - return arr.reduce(this.flattenReduce.bind(this), master || []); - }, - flattenReduce: function(sum, element) { - if (element instanceof Array) { - sum = this.flatten(element, sum); - } else { - sum.push(element); - } - return sum; - } - }; - -})(require('./tree')); -(function (tree) { - tree.importVisitor = function(importer, finish, evalEnv) { - this._visitor = new tree.visitor(this); - this._importer = importer; - this._finish = finish; - this.env = evalEnv || new tree.evalEnv(); - this.importCount = 0; - }; - - tree.importVisitor.prototype = { - isReplacing: true, - run: function (root) { - var error; - try { - // process the contents - this._visitor.visit(root); - } - catch(e) { - error = e; - } - - this.isFinished = true; - - if (this.importCount === 0) { - this._finish(error); - } - }, - visitImport: function (importNode, visitArgs) { - var importVisitor = this, - evaldImportNode, - inlineCSS = importNode.options.inline; - - if (!importNode.css || inlineCSS) { - - try { - evaldImportNode = importNode.evalForImport(this.env); - } catch(e){ - if (!e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; } - // attempt to eval properly and treat as css - importNode.css = true; - // if that fails, this error will be thrown - importNode.error = e; - } - - if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { - importNode = evaldImportNode; - this.importCount++; - var env = new tree.evalEnv(this.env, this.env.frames.slice(0)); - - if (importNode.options.multiple) { - env.importMultiple = true; - } - - this._importer.push(importNode.getPath(), importNode.currentFileInfo, importNode.options, function (e, root, imported, fullPath) { - if (e && !e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; } - - if (imported && !env.importMultiple) { importNode.skip = imported; } - - var subFinish = function(e) { - importVisitor.importCount--; - - if (importVisitor.importCount === 0 && importVisitor.isFinished) { - importVisitor._finish(e); - } - }; - - if (root) { - importNode.root = root; - importNode.importedFilename = fullPath; - if (!inlineCSS && !importNode.skip) { - new(tree.importVisitor)(importVisitor._importer, subFinish, env) - .run(root); - return; - } - } - - subFinish(); - }); - } - } - visitArgs.visitDeeper = false; - return importNode; - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - return ruleNode; - }, - visitDirective: function (directiveNode, visitArgs) { - this.env.frames.unshift(directiveNode); - return directiveNode; - }, - visitDirectiveOut: function (directiveNode) { - this.env.frames.shift(); - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - this.env.frames.unshift(mixinDefinitionNode); - return mixinDefinitionNode; - }, - visitMixinDefinitionOut: function (mixinDefinitionNode) { - this.env.frames.shift(); - }, - visitRuleset: function (rulesetNode, visitArgs) { - this.env.frames.unshift(rulesetNode); - return rulesetNode; - }, - visitRulesetOut: function (rulesetNode) { - this.env.frames.shift(); - }, - visitMedia: function (mediaNode, visitArgs) { - this.env.frames.unshift(mediaNode.ruleset); - return mediaNode; - }, - visitMediaOut: function (mediaNode) { - this.env.frames.shift(); - } - }; - -})(require('./tree')); -(function (tree) { - tree.joinSelectorVisitor = function() { - this.contexts = [[]]; - this._visitor = new tree.visitor(this); - }; - - tree.joinSelectorVisitor.prototype = { - run: function (root) { - return this._visitor.visit(root); - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - - visitRuleset: function (rulesetNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - var paths = []; - this.contexts.push(paths); - - if (! rulesetNode.root) { - rulesetNode.selectors = rulesetNode.selectors.filter(function(selector) { return selector.getIsOutput(); }); - if (rulesetNode.selectors.length === 0) { - rulesetNode.rules.length = 0; - } - rulesetNode.joinSelectors(paths, context, rulesetNode.selectors); - rulesetNode.paths = paths; - } - }, - visitRulesetOut: function (rulesetNode) { - this.contexts.length = this.contexts.length - 1; - }, - visitMedia: function (mediaNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia); - } - }; - -})(require('./tree')); -(function (tree) { - tree.toCSSVisitor = function(env) { - this._visitor = new tree.visitor(this); - this._env = env; - }; - - tree.toCSSVisitor.prototype = { - isReplacing: true, - run: function (root) { - return this._visitor.visit(root); - }, - - visitRule: function (ruleNode, visitArgs) { - if (ruleNode.variable) { - return []; - } - return ruleNode; - }, - - visitMixinDefinition: function (mixinNode, visitArgs) { - return []; - }, - - visitExtend: function (extendNode, visitArgs) { - return []; - }, - - visitComment: function (commentNode, visitArgs) { - if (commentNode.isSilent(this._env)) { - return []; - } - return commentNode; - }, - - visitMedia: function(mediaNode, visitArgs) { - mediaNode.accept(this._visitor); - visitArgs.visitDeeper = false; - - if (!mediaNode.rules.length) { - return []; - } - return mediaNode; - }, - - visitDirective: function(directiveNode, visitArgs) { - if (directiveNode.currentFileInfo.reference && !directiveNode.isReferenced) { - return []; - } - if (directiveNode.name === "@charset") { - // Only output the debug info together with subsequent @charset definitions - // a comment (or @media statement) before the actual @charset directive would - // be considered illegal css as it has to be on the first line - if (this.charset) { - if (directiveNode.debugInfo) { - var comment = new tree.Comment("/* " + directiveNode.toCSS(this._env).replace(/\n/g, "")+" */\n"); - comment.debugInfo = directiveNode.debugInfo; - return this._visitor.visit(comment); - } - return []; - } - this.charset = true; - } - return directiveNode; - }, - - checkPropertiesInRoot: function(rules) { - var ruleNode; - for(var i = 0; i < rules.length; i++) { - ruleNode = rules[i]; - if (ruleNode instanceof tree.Rule && !ruleNode.variable) { - throw { message: "properties must be inside selector blocks, they cannot be in the root.", - index: ruleNode.index, filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null}; - } - } - }, - - visitRuleset: function (rulesetNode, visitArgs) { - var rule, rulesets = []; - if (rulesetNode.firstRoot) { - this.checkPropertiesInRoot(rulesetNode.rules); - } - if (! rulesetNode.root) { - - rulesetNode.paths = rulesetNode.paths - .filter(function(p) { - var i; - if (p[0].elements[0].combinator.value === ' ') { - p[0].elements[0].combinator = new(tree.Combinator)(''); - } - for(i = 0; i < p.length; i++) { - if (p[i].getIsReferenced() && p[i].getIsOutput()) { - return true; - } - return false; - } - }); - - // Compile rules and rulesets - for (var i = 0; i < rulesetNode.rules.length; i++) { - rule = rulesetNode.rules[i]; - - if (rule.rules) { - // visit because we are moving them out from being a child - rulesets.push(this._visitor.visit(rule)); - rulesetNode.rules.splice(i, 1); - i--; - continue; - } - } - // accept the visitor to remove rules and refactor itself - // then we can decide now whether we want it or not - if (rulesetNode.rules.length > 0) { - rulesetNode.accept(this._visitor); - } - visitArgs.visitDeeper = false; - - this._mergeRules(rulesetNode.rules); - this._removeDuplicateRules(rulesetNode.rules); - - // now decide whether we keep the ruleset - if (rulesetNode.rules.length > 0 && rulesetNode.paths.length > 0) { - rulesets.splice(0, 0, rulesetNode); - } - } else { - rulesetNode.accept(this._visitor); - visitArgs.visitDeeper = false; - if (rulesetNode.firstRoot || rulesetNode.rules.length > 0) { - rulesets.splice(0, 0, rulesetNode); - } - } - if (rulesets.length === 1) { - return rulesets[0]; - } - return rulesets; - }, - - _removeDuplicateRules: function(rules) { - // remove duplicates - var ruleCache = {}, - ruleList, rule, i; - for(i = rules.length - 1; i >= 0 ; i--) { - rule = rules[i]; - if (rule instanceof tree.Rule) { - if (!ruleCache[rule.name]) { - ruleCache[rule.name] = rule; - } else { - ruleList = ruleCache[rule.name]; - if (ruleList instanceof tree.Rule) { - ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._env)]; - } - var ruleCSS = rule.toCSS(this._env); - if (ruleList.indexOf(ruleCSS) !== -1) { - rules.splice(i, 1); - } else { - ruleList.push(ruleCSS); - } - } - } - } - }, - - _mergeRules: function (rules) { - var groups = {}, - parts, - rule, - key; - - for (var i = 0; i < rules.length; i++) { - rule = rules[i]; - - if ((rule instanceof tree.Rule) && rule.merge) { - key = [rule.name, - rule.important ? "!" : ""].join(","); - - if (!groups[key]) { - parts = groups[key] = []; - } else { - rules.splice(i--, 1); - } - - parts.push(rule); - } - } - - Object.keys(groups).map(function (k) { - parts = groups[k]; - - if (parts.length > 1) { - rule = parts[0]; - - rule.value = new (tree.Value)(parts.map(function (p) { - return p.value; - })); - } - }); - } - }; - -})(require('./tree')); -(function (tree) { - /*jshint loopfunc:true */ - - tree.extendFinderVisitor = function() { - this._visitor = new tree.visitor(this); - this.contexts = []; - this.allExtendsStack = [[]]; - }; - - tree.extendFinderVisitor.prototype = { - run: function (root) { - root = this._visitor.visit(root); - root.allExtends = this.allExtendsStack[0]; - return root; - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitRuleset: function (rulesetNode, visitArgs) { - - if (rulesetNode.root) { - return; - } - - var i, j, extend, allSelectorsExtendList = [], extendList; - - // get &:extend(.a); rules which apply to all selectors in this ruleset - for(i = 0; i < rulesetNode.rules.length; i++) { - if (rulesetNode.rules[i] instanceof tree.Extend) { - allSelectorsExtendList.push(rulesetNode.rules[i]); - rulesetNode.extendOnEveryPath = true; - } - } - - // now find every selector and apply the extends that apply to all extends - // and the ones which apply to an individual extend - for(i = 0; i < rulesetNode.paths.length; i++) { - var selectorPath = rulesetNode.paths[i], - selector = selectorPath[selectorPath.length-1]; - extendList = selector.extendList.slice(0).concat(allSelectorsExtendList).map(function(allSelectorsExtend) { - return allSelectorsExtend.clone(); - }); - for(j = 0; j < extendList.length; j++) { - this.foundExtends = true; - extend = extendList[j]; - extend.findSelfSelectors(selectorPath); - extend.ruleset = rulesetNode; - if (j === 0) { extend.firstExtendOnThisSelectorPath = true; } - this.allExtendsStack[this.allExtendsStack.length-1].push(extend); - } - } - - this.contexts.push(rulesetNode.selectors); - }, - visitRulesetOut: function (rulesetNode) { - if (!rulesetNode.root) { - this.contexts.length = this.contexts.length - 1; - } - }, - visitMedia: function (mediaNode, visitArgs) { - mediaNode.allExtends = []; - this.allExtendsStack.push(mediaNode.allExtends); - }, - visitMediaOut: function (mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - }, - visitDirective: function (directiveNode, visitArgs) { - directiveNode.allExtends = []; - this.allExtendsStack.push(directiveNode.allExtends); - }, - visitDirectiveOut: function (directiveNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }; - - tree.processExtendsVisitor = function() { - this._visitor = new tree.visitor(this); - }; - - tree.processExtendsVisitor.prototype = { - run: function(root) { - var extendFinder = new tree.extendFinderVisitor(); - extendFinder.run(root); - if (!extendFinder.foundExtends) { return root; } - root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); - this.allExtendsStack = [root.allExtends]; - return this._visitor.visit(root); - }, - doExtendChaining: function (extendsList, extendsListTarget, iterationCount) { - // - // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering and pasting - // the selector we would do normally, but we are also adding an extend with the same target selector - // this means this new extend can then go and alter other extends - // - // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors - // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already processed if - // we look at each selector at a time, as is done in visitRuleset - - var extendIndex, targetExtendIndex, matches, extendsToAdd = [], newSelector, extendVisitor = this, selectorPath, extend, targetExtend, newExtend; - - iterationCount = iterationCount || 0; - - //loop through comparing every extend with every target extend. - // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place - // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one - // and the second is the target. - // the seperation into two lists allows us to process a subset of chains with a bigger set, as is the - // case when processing media queries - for(extendIndex = 0; extendIndex < extendsList.length; extendIndex++){ - for(targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++){ - - extend = extendsList[extendIndex]; - targetExtend = extendsListTarget[targetExtendIndex]; - - // look for circular references - if (this.inInheritanceChain(targetExtend, extend)) { continue; } - - // find a match in the target extends self selector (the bit before :extend) - selectorPath = [targetExtend.selfSelectors[0]]; - matches = extendVisitor.findMatch(extend, selectorPath); - - if (matches.length) { - - // we found a match, so for each self selector.. - extend.selfSelectors.forEach(function(selfSelector) { - - // process the extend as usual - newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector); - - // but now we create a new extend from it - newExtend = new(tree.Extend)(targetExtend.selector, targetExtend.option, 0); - newExtend.selfSelectors = newSelector; - - // add the extend onto the list of extends for that selector - newSelector[newSelector.length-1].extendList = [newExtend]; - - // record that we need to add it. - extendsToAdd.push(newExtend); - newExtend.ruleset = targetExtend.ruleset; - - //remember its parents for circular references - newExtend.parents = [targetExtend, extend]; - - // only process the selector once.. if we have :extend(.a,.b) then multiple - // extends will look at the same selector path, so when extending - // we know that any others will be duplicates in terms of what is added to the css - if (targetExtend.firstExtendOnThisSelectorPath) { - newExtend.firstExtendOnThisSelectorPath = true; - targetExtend.ruleset.paths.push(newSelector); - } - }); - } - } - } - - if (extendsToAdd.length) { - // try to detect circular references to stop a stack overflow. - // may no longer be needed. - this.extendChainCount++; - if (iterationCount > 100) { - var selectorOne = "{unable to calculate}"; - var selectorTwo = "{unable to calculate}"; - try - { - selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); - selectorTwo = extendsToAdd[0].selector.toCSS(); - } - catch(e) {} - throw {message: "extend circular reference detected. One of the circular extends is currently:"+selectorOne+":extend(" + selectorTwo+")"}; - } - - // now process the new extends on the existing rules so that we can handle a extending b extending c ectending d extending e... - return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount+1)); - } else { - return extendsToAdd; - } - }, - inInheritanceChain: function (possibleParent, possibleChild) { - if (possibleParent === possibleChild) { - return true; - } - if (possibleChild.parents) { - if (this.inInheritanceChain(possibleParent, possibleChild.parents[0])) { - return true; - } - if (this.inInheritanceChain(possibleParent, possibleChild.parents[1])) { - return true; - } - } - return false; - }, - visitRule: function (ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitSelector: function (selectorNode, visitArgs) { - visitArgs.visitDeeper = false; - }, - visitRuleset: function (rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - var matches, pathIndex, extendIndex, allExtends = this.allExtendsStack[this.allExtendsStack.length-1], selectorsToAdd = [], extendVisitor = this, selectorPath; - - // look at each selector path in the ruleset, find any extend matches and then copy, find and replace - - for(extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { - for(pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { - - selectorPath = rulesetNode.paths[pathIndex]; - - // extending extends happens initially, before the main pass - if (rulesetNode.extendOnEveryPath || selectorPath[selectorPath.length-1].extendList.length) { continue; } - - matches = this.findMatch(allExtends[extendIndex], selectorPath); - - if (matches.length) { - - allExtends[extendIndex].selfSelectors.forEach(function(selfSelector) { - selectorsToAdd.push(extendVisitor.extendSelector(matches, selectorPath, selfSelector)); - }); - } - } - } - rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); - }, - findMatch: function (extend, haystackSelectorPath) { - // - // look through the haystack selector path to try and find the needle - extend.selector - // returns an array of selector matches that can then be replaced - // - var haystackSelectorIndex, hackstackSelector, hackstackElementIndex, haystackElement, - targetCombinator, i, - extendVisitor = this, - needleElements = extend.selector.elements, - potentialMatches = [], potentialMatch, matches = []; - - // loop through the haystack elements - for(haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { - hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; - - for(hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { - - haystackElement = hackstackSelector.elements[hackstackElementIndex]; - - // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. - if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) { - potentialMatches.push({pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0, initialCombinator: haystackElement.combinator}); - } - - for(i = 0; i < potentialMatches.length; i++) { - potentialMatch = potentialMatches[i]; - - // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't - // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to work out - // what the resulting combinator will be - targetCombinator = haystackElement.combinator.value; - if (targetCombinator === '' && hackstackElementIndex === 0) { - targetCombinator = ' '; - } - - // if we don't match, null our match to indicate failure - if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || - (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) { - potentialMatch = null; - } else { - potentialMatch.matched++; - } - - // if we are still valid and have finished, test whether we have elements after and whether these are allowed - if (potentialMatch) { - potentialMatch.finished = potentialMatch.matched === needleElements.length; - if (potentialMatch.finished && - (!extend.allowAfter && (hackstackElementIndex+1 < hackstackSelector.elements.length || haystackSelectorIndex+1 < haystackSelectorPath.length))) { - potentialMatch = null; - } - } - // if null we remove, if not, we are still valid, so either push as a valid match or continue - if (potentialMatch) { - if (potentialMatch.finished) { - potentialMatch.length = needleElements.length; - potentialMatch.endPathIndex = haystackSelectorIndex; - potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match - potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again - matches.push(potentialMatch); - } - } else { - potentialMatches.splice(i, 1); - i--; - } - } - } - } - return matches; - }, - isElementValuesEqual: function(elementValue1, elementValue2) { - if (typeof elementValue1 === "string" || typeof elementValue2 === "string") { - return elementValue1 === elementValue2; - } - if (elementValue1 instanceof tree.Attribute) { - if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { - return false; - } - if (!elementValue1.value || !elementValue2.value) { - if (elementValue1.value || elementValue2.value) { - return false; - } - return true; - } - elementValue1 = elementValue1.value.value || elementValue1.value; - elementValue2 = elementValue2.value.value || elementValue2.value; - return elementValue1 === elementValue2; - } - elementValue1 = elementValue1.value; - elementValue2 = elementValue2.value; - if (elementValue1 instanceof tree.Selector) { - if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { - return false; - } - for(var i = 0; i <elementValue1.elements.length; i++) { - if (elementValue1.elements[i].combinator.value !== elementValue2.elements[i].combinator.value) { - if (i !== 0 || (elementValue1.elements[i].combinator.value || ' ') !== (elementValue2.elements[i].combinator.value || ' ')) { - return false; - } - } - if (!this.isElementValuesEqual(elementValue1.elements[i].value, elementValue2.elements[i].value)) { - return false; - } - } - return true; - } - return false; - }, - extendSelector:function (matches, selectorPath, replacementSelector) { - - //for a set of matches, replace each match with the replacement selector - - var currentSelectorPathIndex = 0, - currentSelectorPathElementIndex = 0, - path = [], - matchIndex, - selector, - firstElement, - match, - newElements; - - for (matchIndex = 0; matchIndex < matches.length; matchIndex++) { - match = matches[matchIndex]; - selector = selectorPath[match.pathIndex]; - firstElement = new tree.Element( - match.initialCombinator, - replacementSelector.elements[0].value, - replacementSelector.elements[0].index, - replacementSelector.elements[0].currentFileInfo - ); - - if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; - } - - newElements = selector.elements - .slice(currentSelectorPathElementIndex, match.index) - .concat([firstElement]) - .concat(replacementSelector.elements.slice(1)); - - if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { - path[path.length - 1].elements = - path[path.length - 1].elements.concat(newElements); - } else { - path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); - - path.push(new tree.Selector( - newElements - )); - } - currentSelectorPathIndex = match.endPathIndex; - currentSelectorPathElementIndex = match.endPathElementIndex; - if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; - } - } - - if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathIndex++; - } - - path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); - - return path; - }, - visitRulesetOut: function (rulesetNode) { - }, - visitMedia: function (mediaNode, visitArgs) { - var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - }, - visitMediaOut: function (mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - }, - visitDirective: function (directiveNode, visitArgs) { - var newAllExtends = directiveNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, directiveNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - }, - visitDirectiveOut: function (directiveNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }; - -})(require('./tree')); - -(function (tree) { - - tree.sourceMapOutput = function (options) { - this._css = []; - this._rootNode = options.rootNode; - this._writeSourceMap = options.writeSourceMap; - this._contentsMap = options.contentsMap; - this._sourceMapFilename = options.sourceMapFilename; - this._outputFilename = options.outputFilename; - this._sourceMapBasepath = options.sourceMapBasepath; - this._sourceMapRootpath = options.sourceMapRootpath; - this._outputSourceFiles = options.outputSourceFiles; - this._sourceMapGeneratorConstructor = options.sourceMapGenerator || require("source-map").SourceMapGenerator; - - if (this._sourceMapRootpath && this._sourceMapRootpath.charAt(this._sourceMapRootpath.length-1) !== '/') { - this._sourceMapRootpath += '/'; - } - - this._lineNumber = 0; - this._column = 0; - }; - - tree.sourceMapOutput.prototype.normalizeFilename = function(filename) { - if (this._sourceMapBasepath && filename.indexOf(this._sourceMapBasepath) === 0) { - filename = filename.substring(this._sourceMapBasepath.length); - if (filename.charAt(0) === '\\' || filename.charAt(0) === '/') { - filename = filename.substring(1); - } - } - return (this._sourceMapRootpath || "") + filename.replace(/\\/g, '/'); - }; - - tree.sourceMapOutput.prototype.add = function(chunk, fileInfo, index, mapLines) { - - //ignore adding empty strings - if (!chunk) { - return; - } - - var lines, - sourceLines, - columns, - sourceColumns, - i; - - if (fileInfo) { - var inputSource = this._contentsMap[fileInfo.filename].substring(0, index); - sourceLines = inputSource.split("\n"); - sourceColumns = sourceLines[sourceLines.length-1]; - } - - lines = chunk.split("\n"); - columns = lines[lines.length-1]; - - if (fileInfo) { - if (!mapLines) { - this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column}, - original: { line: sourceLines.length, column: sourceColumns.length}, - source: this.normalizeFilename(fileInfo.filename)}); - } else { - for(i = 0; i < lines.length; i++) { - this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0}, - original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0}, - source: this.normalizeFilename(fileInfo.filename)}); - } - } - } - - if (lines.length === 1) { - this._column += columns.length; - } else { - this._lineNumber += lines.length - 1; - this._column = columns.length; - } - - this._css.push(chunk); - }; - - tree.sourceMapOutput.prototype.isEmpty = function() { - return this._css.length === 0; - }; - - tree.sourceMapOutput.prototype.toCSS = function(env) { - this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null }); - - if (this._outputSourceFiles) { - for(var filename in this._contentsMap) { - this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), this._contentsMap[filename]); - } - } - - this._rootNode.genCSS(env, this); - - if (this._css.length > 0) { - var sourceMapFilename, - sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); - - if (this._sourceMapFilename) { - sourceMapFilename = this.normalizeFilename(this._sourceMapFilename); - } - - if (this._writeSourceMap) { - this._writeSourceMap(sourceMapContent); - } else { - sourceMapFilename = "data:application/json," + encodeURIComponent(sourceMapContent); - } - - if (sourceMapFilename) { - this._css.push("/*# sourceMappingURL=" + sourceMapFilename + " */"); - } - } - - return this._css.join(''); - }; - -})(require('./tree')); - -// -// browser.js - client-side engine -// -/*global less, window, document, XMLHttpRequest, location */ - -var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol); - -less.env = less.env || (location.hostname == '127.0.0.1' || - location.hostname == '0.0.0.0' || - location.hostname == 'localhost' || - (location.port && - location.port.length > 0) || - isFileProtocol ? 'development' - : 'production'); - -var logLevel = { - info: 2, - errors: 1, - none: 0 -}; - -// The amount of logging in the javascript console. -// 2 - Information and errors -// 1 - Errors -// 0 - None -// Defaults to 2 -less.logLevel = typeof(less.logLevel) != 'undefined' ? less.logLevel : logLevel.info; - -// Load styles asynchronously (default: false) -// -// This is set to `false` by default, so that the body -// doesn't start loading before the stylesheets are parsed. -// Setting this to `true` can result in flickering. -// -less.async = less.async || false; -less.fileAsync = less.fileAsync || false; - -// Interval between watch polls -less.poll = less.poll || (isFileProtocol ? 1000 : 1500); - -//Setup user functions -if (less.functions) { - for(var func in less.functions) { - less.tree.functions[func] = less.functions[func]; - } -} - -var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash); -if (dumpLineNumbers) { - less.dumpLineNumbers = dumpLineNumbers[1]; -} - -var typePattern = /^text\/(x-)?less$/; -var cache = null; -var fileCache = {}; -var varsPre = ""; - -function log(str, level) { - if (less.env == 'development' && typeof(console) !== 'undefined' && less.logLevel >= level) { - console.log('less: ' + str); - } -} - -function extractId(href) { - return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain - .replace(/^\//, '' ) // Remove root / - .replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension - .replace(/[^\.\w-]+/g, '-') // Replace illegal characters - .replace(/\./g, ':'); // Replace dots with colons(for valid id) -} - -function errorConsole(e, rootHref) { - var template = '{line} {content}'; - var filename = e.filename || rootHref; - var errors = []; - var content = (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + - " in " + filename + " "; - - var errorline = function (e, i, classname) { - if (e.extract[i] !== undefined) { - errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) - .replace(/\{class\}/, classname) - .replace(/\{content\}/, e.extract[i])); - } - }; - - if (e.extract) { - errorline(e, 0, ''); - errorline(e, 1, 'line'); - errorline(e, 2, ''); - content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n' + - errors.join('\n'); - } else if (e.stack) { - content += e.stack; - } - log(content, logLevel.errors); -} - -function createCSS(styles, sheet, lastModified) { - // Strip the query-string - var href = sheet.href || ''; - - // If there is no title set, use the filename, minus the extension - var id = 'less:' + (sheet.title || extractId(href)); - - // If this has already been inserted into the DOM, we may need to replace it - var oldCss = document.getElementById(id); - var keepOldCss = false; - - // Create a new stylesheet node for insertion or (if necessary) replacement - var css = document.createElement('style'); - css.setAttribute('type', 'text/css'); - if (sheet.media) { - css.setAttribute('media', sheet.media); - } - css.id = id; - - if (css.styleSheet) { // IE - try { - css.styleSheet.cssText = styles; - } catch (e) { - throw new(Error)("Couldn't reassign styleSheet.cssText."); - } - } else { - css.appendChild(document.createTextNode(styles)); - - // If new contents match contents of oldCss, don't replace oldCss - keepOldCss = (oldCss !== null && oldCss.childNodes.length > 0 && css.childNodes.length > 0 && - oldCss.firstChild.nodeValue === css.firstChild.nodeValue); - } - - var head = document.getElementsByTagName('head')[0]; - - // If there is no oldCss, just append; otherwise, only append if we need - // to replace oldCss with an updated stylesheet - if (oldCss === null || keepOldCss === false) { - var nextEl = sheet && sheet.nextSibling || null; - if (nextEl) { - nextEl.parentNode.insertBefore(css, nextEl); - } else { - head.appendChild(css); - } - } - if (oldCss && keepOldCss === false) { - oldCss.parentNode.removeChild(oldCss); - } - - // Don't update the local store if the file wasn't modified - if (lastModified && cache) { - log('saving ' + href + ' to cache.', logLevel.info); - try { - cache.setItem(href, styles); - cache.setItem(href + ':timestamp', lastModified); - } catch(e) { - //TODO - could do with adding more robust error handling - log('failed to save', logLevel.errors); - } - } -} - -function errorHTML(e, rootHref) { - var id = 'less-error-message:' + extractId(rootHref || ""); - var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>'; - var elem = document.createElement('div'), timer, content, errors = []; - var filename = e.filename || rootHref; - var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1]; - - elem.id = id; - elem.className = "less-error-message"; - - content = '<h3>' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + - '</h3>' + '<p>in <a href="' + filename + '">' + filenameNoPath + "</a> "; - - var errorline = function (e, i, classname) { - if (e.extract[i] !== undefined) { - errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) - .replace(/\{class\}/, classname) - .replace(/\{content\}/, e.extract[i])); - } - }; - - if (e.extract) { - errorline(e, 0, ''); - errorline(e, 1, 'line'); - errorline(e, 2, ''); - content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' + - '<ul>' + errors.join('') + '</ul>'; - } else if (e.stack) { - content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>'); - } - elem.innerHTML = content; - - // CSS for error messages - createCSS([ - '.less-error-message ul, .less-error-message li {', - 'list-style-type: none;', - 'margin-right: 15px;', - 'padding: 4px 0;', - 'margin: 0;', - '}', - '.less-error-message label {', - 'font-size: 12px;', - 'margin-right: 15px;', - 'padding: 4px 0;', - 'color: #cc7777;', - '}', - '.less-error-message pre {', - 'color: #dd6666;', - 'padding: 4px 0;', - 'margin: 0;', - 'display: inline-block;', - '}', - '.less-error-message pre.line {', - 'color: #ff0000;', - '}', - '.less-error-message h3 {', - 'font-size: 20px;', - 'font-weight: bold;', - 'padding: 15px 0 5px 0;', - 'margin: 0;', - '}', - '.less-error-message a {', - 'color: #10a', - '}', - '.less-error-message .error {', - 'color: red;', - 'font-weight: bold;', - 'padding-bottom: 2px;', - 'border-bottom: 1px dashed red;', - '}' - ].join('\n'), { title: 'error-message' }); - - elem.style.cssText = [ - "font-family: Arial, sans-serif", - "border: 1px solid #e00", - "background-color: #eee", - "border-radius: 5px", - "-webkit-border-radius: 5px", - "-moz-border-radius: 5px", - "color: #e00", - "padding: 15px", - "margin-bottom: 15px" - ].join(';'); - - if (less.env == 'development') { - timer = setInterval(function () { - if (document.body) { - if (document.getElementById(id)) { - document.body.replaceChild(elem, document.getElementById(id)); - } else { - document.body.insertBefore(elem, document.body.firstChild); - } - clearInterval(timer); - } - }, 10); - } -} - -function error(e, rootHref) { - if (!less.errorReporting || less.errorReporting === "html") { - errorHTML(e, rootHref); - } else if (less.errorReporting === "console") { - errorConsole(e, rootHref); - } else if (typeof less.errorReporting === 'function') { - less.errorReporting("add", e, rootHref); - } -} - -function removeErrorHTML(path) { - var node = document.getElementById('less-error-message:' + extractId(path)); - if (node) { - node.parentNode.removeChild(node); - } -} - -function removeErrorConsole(path) { - //no action -} - -function removeError(path) { - if (!less.errorReporting || less.errorReporting === "html") { - removeErrorHTML(path); - } else if (less.errorReporting === "console") { - removeErrorConsole(path); - } else if (typeof less.errorReporting === 'function') { - less.errorReporting("remove", path); - } -} - -function loadStyles(newVars) { - var styles = document.getElementsByTagName('style'), - style; - for (var i = 0; i < styles.length; i++) { - style = styles[i]; - if (style.type.match(typePattern)) { - var env = new less.tree.parseEnv(less), - lessText = style.innerHTML || ''; - env.filename = document.location.href.replace(/#.*$/, ''); - - if (newVars || varsPre) { - env.useFileCache = true; - - lessText = varsPre + lessText; - - if (newVars) { - lessText += "\n" + newVars; - } - } - - /*jshint loopfunc:true */ - // use closure to store current value of i - var callback = (function(style) { - return function (e, cssAST) { - if (e) { - return error(e, "inline"); - } - var css = cssAST.toCSS(less); - style.type = 'text/css'; - if (style.styleSheet) { - style.styleSheet.cssText = css; - } else { - style.innerHTML = css; - } - }; - })(style); - new(less.Parser)(env).parse(lessText, callback); - } - } -} - -function extractUrlParts(url, baseUrl) { - // urlParts[1] = protocol&hostname || / - // urlParts[2] = / if path relative to host base - // urlParts[3] = directories - // urlParts[4] = filename - // urlParts[5] = parameters - - var urlPartsRegex = /^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i, - urlParts = url.match(urlPartsRegex), - returner = {}, directories = [], i, baseUrlParts; - - if (!urlParts) { - throw new Error("Could not parse sheet href - '"+url+"'"); - } - - // Stylesheets in IE don't always return the full path - if (!urlParts[1] || urlParts[2]) { - baseUrlParts = baseUrl.match(urlPartsRegex); - if (!baseUrlParts) { - throw new Error("Could not parse page url - '"+baseUrl+"'"); - } - urlParts[1] = urlParts[1] || baseUrlParts[1] || ""; - if (!urlParts[2]) { - urlParts[3] = baseUrlParts[3] + urlParts[3]; - } - } - - if (urlParts[3]) { - directories = urlParts[3].replace(/\\/g, "/").split("/"); - - // extract out . before .. so .. doesn't absorb a non-directory - for(i = 0; i < directories.length; i++) { - if (directories[i] === ".") { - directories.splice(i, 1); - i -= 1; - } - } - - for(i = 0; i < directories.length; i++) { - if (directories[i] === ".." && i > 0) { - directories.splice(i-1, 2); - i -= 2; - } - } - } - - returner.hostPart = urlParts[1]; - returner.directories = directories; - returner.path = urlParts[1] + directories.join("/"); - returner.fileUrl = returner.path + (urlParts[4] || ""); - returner.url = returner.fileUrl + (urlParts[5] || ""); - return returner; -} - -function pathDiff(url, baseUrl) { - // diff between two paths to create a relative path - - var urlParts = extractUrlParts(url), - baseUrlParts = extractUrlParts(baseUrl), - i, max, urlDirectories, baseUrlDirectories, diff = ""; - if (urlParts.hostPart !== baseUrlParts.hostPart) { - return ""; - } - max = Math.max(baseUrlParts.directories.length, urlParts.directories.length); - for(i = 0; i < max; i++) { - if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; } - } - baseUrlDirectories = baseUrlParts.directories.slice(i); - urlDirectories = urlParts.directories.slice(i); - for(i = 0; i < baseUrlDirectories.length-1; i++) { - diff += "../"; - } - for(i = 0; i < urlDirectories.length-1; i++) { - diff += urlDirectories[i] + "/"; - } - return diff; -} - -function getXMLHttpRequest() { - if (window.XMLHttpRequest) { - return new XMLHttpRequest(); - } else { - try { - /*global ActiveXObject */ - return new ActiveXObject("MSXML2.XMLHTTP.3.0"); - } catch (e) { - log("browser doesn't support AJAX.", logLevel.errors); - return null; - } - } -} - -function doXHR(url, type, callback, errback) { - var xhr = getXMLHttpRequest(); - var async = isFileProtocol ? less.fileAsync : less.async; - - if (typeof(xhr.overrideMimeType) === 'function') { - xhr.overrideMimeType('text/css'); - } - log("XHR: Getting '" + url + "'", logLevel.info); - xhr.open('GET', url, async); - xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5'); - xhr.send(null); - - function handleResponse(xhr, callback, errback) { - if (xhr.status >= 200 && xhr.status < 300) { - callback(xhr.responseText, - xhr.getResponseHeader("Last-Modified")); - } else if (typeof(errback) === 'function') { - errback(xhr.status, url); - } - } - - if (isFileProtocol && !less.fileAsync) { - if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) { - callback(xhr.responseText); - } else { - errback(xhr.status, url); - } - } else if (async) { - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - handleResponse(xhr, callback, errback); - } - }; - } else { - handleResponse(xhr, callback, errback); - } -} - -function loadFile(originalHref, currentFileInfo, callback, env, newVars) { - - if (currentFileInfo && currentFileInfo.currentDirectory && !/^([a-z-]+:)?\//.test(originalHref)) { - originalHref = currentFileInfo.currentDirectory + originalHref; - } - - // sheet may be set to the stylesheet for the initial load or a collection of properties including - // some env variables for imports - var hrefParts = extractUrlParts(originalHref, window.location.href); - var href = hrefParts.url; - var newFileInfo = { - currentDirectory: hrefParts.path, - filename: href - }; - - if (currentFileInfo) { - newFileInfo.entryPath = currentFileInfo.entryPath; - newFileInfo.rootpath = currentFileInfo.rootpath; - newFileInfo.rootFilename = currentFileInfo.rootFilename; - newFileInfo.relativeUrls = currentFileInfo.relativeUrls; - } else { - newFileInfo.entryPath = hrefParts.path; - newFileInfo.rootpath = less.rootpath || hrefParts.path; - newFileInfo.rootFilename = href; - newFileInfo.relativeUrls = env.relativeUrls; - } - - if (newFileInfo.relativeUrls) { - if (env.rootpath) { - newFileInfo.rootpath = extractUrlParts(env.rootpath + pathDiff(hrefParts.path, newFileInfo.entryPath)).path; - } else { - newFileInfo.rootpath = hrefParts.path; - } - } - - if (env.useFileCache && fileCache[href]) { - try { - var lessText = fileCache[href]; - if (newVars) { - lessText += "\n" + newVars; - } - callback(null, lessText, href, newFileInfo, { lastModified: new Date() }); - } catch (e) { - callback(e, null, href); - } - return; - } - - doXHR(href, env.mime, function (data, lastModified) { - data = varsPre + data; - - // per file cache - fileCache[href] = data; - - // Use remote copy (re-parse) - try { - callback(null, data, href, newFileInfo, { lastModified: lastModified }); - } catch (e) { - callback(e, null, href); - } - }, function (status, url) { - callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")" }, null, href); - }); -} - -function loadStyleSheet(sheet, callback, reload, remaining, newVars) { - - var env = new less.tree.parseEnv(less); - env.mime = sheet.type; - - if (newVars || varsPre) { - env.useFileCache = true; - } - - loadFile(sheet.href, null, function(e, data, path, newFileInfo, webInfo) { - - if (webInfo) { - webInfo.remaining = remaining; - - var css = cache && cache.getItem(path), - timestamp = cache && cache.getItem(path + ':timestamp'); - - if (!reload && timestamp && webInfo.lastModified && - (new(Date)(webInfo.lastModified).valueOf() === - new(Date)(timestamp).valueOf())) { - // Use local copy - createCSS(css, sheet); - webInfo.local = true; - callback(null, null, data, sheet, webInfo, path); - return; - } - } - - //TODO add tests around how this behaves when reloading - removeError(path); - - if (data) { - env.currentFileInfo = newFileInfo; - new(less.Parser)(env).parse(data, function (e, root) { - if (e) { return callback(e, null, null, sheet); } - try { - callback(e, root, data, sheet, webInfo, path); - } catch (e) { - callback(e, null, null, sheet); - } - }); - } else { - callback(e, null, null, sheet, webInfo, path); - } - }, env, newVars); -} - -function loadStyleSheets(callback, reload, newVars) { - for (var i = 0; i < less.sheets.length; i++) { - loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), newVars); - } -} - -function initRunningMode(){ - if (less.env === 'development') { - less.optimization = 0; - less.watchTimer = setInterval(function () { - if (less.watchMode) { - loadStyleSheets(function (e, root, _, sheet, env) { - if (e) { - error(e, sheet.href); - } else if (root) { - createCSS(root.toCSS(less), sheet, env.lastModified); - } - }); - } - }, less.poll); - } else { - less.optimization = 3; - } -} - -function serializeVars(vars) { - var s = ""; - - for (var name in vars) { - s += ((name.slice(0,1) === '@')? '' : '@') + name +': '+ - ((vars[name].slice(-1) === ';')? vars[name] : vars[name] +';'); - } - - return s; -} - - -// -// Watch mode -// -less.watch = function () { - if (!less.watchMode ){ - less.env = 'development'; - initRunningMode(); - } - return this.watchMode = true; -}; - -less.unwatch = function () {clearInterval(less.watchTimer); return this.watchMode = false; }; - -if (/!watch/.test(location.hash)) { - less.watch(); -} - -if (less.env != 'development') { - try { - cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage; - } catch (_) {} -} - -// -// Get all <link> tags with the 'rel' attribute set to "stylesheet/less" -// -var links = document.getElementsByTagName('link'); - -less.sheets = []; - -for (var i = 0; i < links.length; i++) { - if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) && - (links[i].type.match(typePattern)))) { - less.sheets.push(links[i]); - } -} - -// -// With this function, it's possible to alter variables and re-render -// CSS without reloading less-files -// -less.modifyVars = function(record) { - less.refresh(false, serializeVars(record)); -}; - -less.refresh = function (reload, newVars) { - var startTime, endTime; - startTime = endTime = new Date(); - - loadStyleSheets(function (e, root, _, sheet, env) { - if (e) { - return error(e, sheet.href); - } - if (env.local) { - log("loading " + sheet.href + " from cache.", logLevel.info); - } else { - log("parsed " + sheet.href + " successfully.", logLevel.info); - createCSS(root.toCSS(less), sheet, env.lastModified); - } - log("css for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms', logLevel.info); - if (env.remaining === 0) { - log("css generated in " + (new Date() - startTime) + 'ms', logLevel.info); - } - endTime = new Date(); - }, reload, newVars); - - loadStyles(newVars); -}; - -if (less.globalVars) { - varsPre = serializeVars(less.globalVars) + "\n"; -} - -less.refreshStyles = loadStyles; - -less.Parser.fileLoader = loadFile; - -less.refresh(less.env === 'development'); - -// amd.js -// -// Define Less as an AMD module. -if (typeof define === "function" && define.amd) { - define(function () { return less; } ); -} - -})(window); \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/console-errors/test-error.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/console-errors/test-error.less deleted file mode 100644 index 7c60c004..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/console-errors/test-error.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - prop: (3 / #fff); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/console-errors/test-error.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/console-errors/test-error.txt deleted file mode 100644 index 643bd593..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/console-errors/test-error.txt +++ /dev/null @@ -1,2 +0,0 @@ -less: OperationError: Can't substract or divide a color from a number in {pathhref}console-errors/test-error.less on line null, column 0: -1 prop: (3 / #fff); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/global-vars/simple.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/global-vars/simple.less deleted file mode 100644 index 00545b16..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/global-vars/simple.less +++ /dev/null @@ -1,3 +0,0 @@ -.test { - color: @global-var; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/imports/urls.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/imports/urls.less deleted file mode 100644 index 290e6b41..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/imports/urls.less +++ /dev/null @@ -1,4 +0,0 @@ -@import "modify-this.css"; -.modify { - my-url: url("a.png"); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/imports/urls2.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/imports/urls2.less deleted file mode 100644 index b834bb9e..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/imports/urls2.less +++ /dev/null @@ -1,4 +0,0 @@ -@import "modify-again.css"; -.modify { - my-url: url("b.png"); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/modify-vars/imports/simple2.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/modify-vars/imports/simple2.less deleted file mode 100644 index 49fcf875..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/modify-vars/imports/simple2.less +++ /dev/null @@ -1,4 +0,0 @@ -@var2: blue; -.testisimported { - color: gainsboro; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/modify-vars/simple.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/modify-vars/simple.less deleted file mode 100644 index 64d99302..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/modify-vars/simple.less +++ /dev/null @@ -1,6 +0,0 @@ -@import "imports/simple2"; -@var1: red; -.test { - color1: @var1; - color2: @var2; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/relative-urls/urls.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/relative-urls/urls.less deleted file mode 100644 index 53fc940f..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/relative-urls/urls.less +++ /dev/null @@ -1,32 +0,0 @@ -@import ".././imports/urls.less"; -@import "http://localhost:8081/test/browser/less/imports/urls2.less"; -@font-face { - src: local(Futura-Medium), - url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} - -#svg-data-uri { - background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>'); -} - -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - @a: 'Trebuchet'; - url: url(@a); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/rootpath-relative/urls.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/rootpath-relative/urls.less deleted file mode 100644 index b8316a44..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/rootpath-relative/urls.less +++ /dev/null @@ -1,32 +0,0 @@ -@import "../imports/urls.less"; -@import "http://localhost:8081/test/browser/less/imports/urls2.less"; -@font-face { - src: local(Futura-Medium), - url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} - -#svg-data-uri { - background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>'); -} - -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - @a: 'Trebuchet'; - url: url(@a); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/rootpath/urls.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/rootpath/urls.less deleted file mode 100644 index b8316a44..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/rootpath/urls.less +++ /dev/null @@ -1,32 +0,0 @@ -@import "../imports/urls.less"; -@import "http://localhost:8081/test/browser/less/imports/urls2.less"; -@font-face { - src: local(Futura-Medium), - url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} - -#svg-data-uri { - background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>'); -} - -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - @a: 'Trebuchet'; - url: url(@a); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/urls.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/urls.less deleted file mode 100644 index 38198c08..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/less/urls.less +++ /dev/null @@ -1,56 +0,0 @@ -@import "imports/urls.less"; -@import "http://localhost:8081/test/browser/less/imports/urls2.less"; -@font-face { - src: local(Futura-Medium), - url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} - -#svg-data-uri { - background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>'); -} - -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - @a: 'Trebuchet'; - url: url(@a); -} -#data-uri { - uri: data-uri('image/jpeg;base64', '../../data/image.jpg'); -} - -#data-uri-guess { - uri: data-uri('../../data/image.jpg'); -} - -#data-uri-ascii { - uri-1: data-uri('text/html', '../../data/page.html'); - uri-2: data-uri('../../data/page.html'); -} - -#data-uri-toobig { - uri: data-uri('../../data/data-uri-fail.png'); -} -#svg-functions { - background-image: svg-gradient(to bottom, black, white); - background-image: svg-gradient(to bottom, black, orange 3%, white); - @green_5: green 5%; - @orange_percentage: 3%; - @orange_color: orange; - background-image: svg-gradient(to bottom, (mix(black, white) + #444) 1%, @orange_color @orange_percentage, ((@green_5)), white 95%); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/phantom-runner.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/phantom-runner.js deleted file mode 100644 index 8233deb8..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/phantom-runner.js +++ /dev/null @@ -1,150 +0,0 @@ -var webpage = require('webpage'); -var server = require('webserver').create(); -var system = require('system'); -var fs = require('fs'); -var host; -var port = 8081; - -var listening = server.listen(port, function(request, response) { - //console.log("Requested " + request.url); - - var filename = ("test/" + request.url.slice(1)).replace(/[\\\/]/g, fs.separator); - - if (!fs.exists(filename) || !fs.isFile(filename)) { - response.statusCode = 404; - response.write("<html><head></head><body><h1>File Not Found</h1><h2>File:" + filename + "</h2></body></html>"); - response.close(); - return; - } - - // we set the headers here - response.statusCode = 200; - response.headers = { - "Cache": "no-cache", - "Content-Type": "text/html" - }; - - response.write(fs.read(filename)); - - response.close(); -}); -if (!listening) { - console.log("could not create web server listening on port " + port); - phantom.exit(); -} - -/** - * Wait until the test condition is true or a timeout occurs. Useful for waiting - * on a server response or for a ui change (fadeIn, etc.) to occur. - * - * @param testFx javascript condition that evaluates to a boolean, - * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or - * as a callback function. - * @param onReady what to do when testFx condition is fulfilled, - * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or - * as a callback function. - * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used. - * @param timeOutErrorMessage the error message if time out occurs - */ - -function waitFor(testFx, onReady, timeOutMillis, timeOutErrorMessage) { - var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 10001, //< Default Max Timeout is 10s - start = new Date().getTime(), - condition = false, - interval = setInterval(function() { - if ((new Date().getTime() - start < maxtimeOutMillis) && !condition) { - // If not time-out yet and condition not yet fulfilled - condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code - } else { - if (!condition) { - // If condition still not fulfilled (timeout but condition is 'false') - console.log(timeOutErrorMessage || "'waitFor()' timeout"); - phantom.exit(1); - } else { - // Condition fulfilled (timeout and/or condition is 'true') - typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled - clearInterval(interval); //< Stop this interval - } - } - }, 100); //< repeat check every 100ms -} - -function testPage(url) { - var page = webpage.create(); - page.open(url, function(status) { - if (status !== "success") { - console.log("Unable to access network - " + status); - phantom.exit(); - } else { - waitFor(function() { - return page.evaluate(function() { - return document.body && document.body.querySelector && - document.body.querySelector('.symbolSummary .pending') === null && - document.body.querySelector('.results') !== null; - }); - }, function() { - page.onConsoleMessage = function(msg) { - console.log(msg); - }; - var exitCode = page.evaluate(function() { - console.log(''); - console.log(document.body.querySelector('.description').innerText); - var list = document.body.querySelectorAll('.results > #details > .specDetail.failed'); - if (list && list.length > 0) { - console.log(''); - console.log(list.length + ' test(s) FAILED:'); - for (var i = 0; i < list.length; ++i) { - var el = list[i], - desc = el.querySelector('.description'), - msg = el.querySelector('.resultMessage.fail'); - console.log(''); - console.log(desc.innerText); - console.log(msg.innerText); - console.log(''); - } - return 1; - } else { - console.log(document.body.querySelector('.alert > .passingAlert.bar').innerText); - return 0; - } - }); - testFinished(exitCode); - }, - 10000, // 10 second timeout - "Test failed waiting for jasmine results on page: " + url); - } - }); -} - -function scanDirectory(path, regex) { - var files = []; - fs.list(path).forEach(function(file) { - if (file.match(regex)) { - files.push(file); - } - }); - return files; -} - -var totalTests = 0, - totalFailed = 0, - totalDone = 0; - -function testFinished(failed) { - if (failed) { - totalFailed++; - } - totalDone++; - if (totalDone === totalTests) { - phantom.exit(totalFailed > 0 ? 1 : 0); - } -} - -if (system.args.length != 2 && system.args[1] != "--no-tests") { - var files = scanDirectory("test/browser/", /^test-runner-.+\.htm$/); - totalTests = files.length; - console.log("found " + files.length + " tests"); - files.forEach(function(file) { - testPage("http://localhost:8081/browser/" + file); - }); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-browser-options.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-browser-options.js deleted file mode 100644 index 3d73323e..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-browser-options.js +++ /dev/null @@ -1,42 +0,0 @@ -var less = {}; - -// There originally run inside describe method. However, since they have not -// been inside it, they run at jasmine compile time (not runtime). It all -// worked cause less.js was in async mode and custom phantom runner had -// different setup then grunt-contrib-jasmine. They have been created before -// less.js run, even as they have been defined in spec. - -// test inline less in style tags by grabbing an assortment of less files and doing `@import`s -var testFiles = ['charsets', 'colors', 'comments', 'css-3', 'strings', 'media', 'mixins'], - testSheets = []; - -// setup style tags with less and link tags pointing to expected css output -for (var i = 0; i < testFiles.length; i++) { - var file = testFiles[i], - lessPath = '/test/less/' + file + '.less', - cssPath = '/test/css/' + file + '.css', - lessStyle = document.createElement('style'), - cssLink = document.createElement('link'), - lessText = '@import "' + lessPath + '";'; - - lessStyle.type = 'text/less'; - lessStyle.id = file; - lessStyle.href = file; - - if (lessStyle.styleSheet) { - lessStyle.styleSheet.cssText = lessText; - } else { - lessStyle.innerHTML = lessText; - } - - cssLink.rel = 'stylesheet'; - cssLink.type = 'text/css'; - cssLink.href = cssPath; - cssLink.id = 'expected-' + file; - - var head = document.getElementsByTagName('head')[0]; - - head.appendChild(lessStyle); - head.appendChild(cssLink); - testSheets[i] = lessStyle; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-browser-spec.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-browser-spec.js deleted file mode 100644 index ead27b4a..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-browser-spec.js +++ /dev/null @@ -1,12 +0,0 @@ -describe("less.js browser behaviour", function() { - testLessEqualsInDocument(); - - it("has some log messages", function() { - expect(logMessages.length).toBeGreaterThan(0); - }); - - for (var i = 0; i < testFiles.length; i++) { - var sheet = testSheets[i]; - testSheet(sheet); - } -}); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-console-errors.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-console-errors.js deleted file mode 100644 index 7af7bdb1..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-console-errors.js +++ /dev/null @@ -1,5 +0,0 @@ -less.errorReporting = 'console'; - -describe("less.js error reporting console test", function() { - testLessErrorsInDocument(true); -}); \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-errors-options.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-errors-options.js deleted file mode 100644 index 840ba5d6..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-errors-options.js +++ /dev/null @@ -1,5 +0,0 @@ -var less = { - strictUnits: true, - strictMath: true -}; - diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-errors-spec.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-errors-spec.js deleted file mode 100644 index 0b720676..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-errors-spec.js +++ /dev/null @@ -1,4 +0,0 @@ -describe("less.js error tests", function() { - testLessErrorsInDocument(); -}); - diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-global-vars-options.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-global-vars-options.js deleted file mode 100644 index f313b2f7..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-global-vars-options.js +++ /dev/null @@ -1,4 +0,0 @@ -var less = {}; -less.globalVars = { - "@global-var": "red" -}; diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-global-vars-spec.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-global-vars-spec.js deleted file mode 100644 index 6dba8917..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-global-vars-spec.js +++ /dev/null @@ -1,3 +0,0 @@ -describe("less.js global vars", function() { - testLessEqualsInDocument(); -}); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-legacy-options.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-legacy-options.js deleted file mode 100644 index 9e4b9592..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-legacy-options.js +++ /dev/null @@ -1,4 +0,0 @@ -var less = {}; -less.strictMath = false; -less.strictUnits = false; - diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-legacy-spec.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-legacy-spec.js deleted file mode 100644 index 6ba7bfae..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-legacy-spec.js +++ /dev/null @@ -1,3 +0,0 @@ -describe("less.js legacy tests", function() { - testLessEqualsInDocument(); -}); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-main-options.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-main-options.js deleted file mode 100644 index df51782a..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-main-options.js +++ /dev/null @@ -1,15 +0,0 @@ -var less = {}; -less.strictMath = true; -less.functions = { - add: function(a, b) { - return new(less.tree.Dimension)(a.value + b.value); - }, - increment: function(a) { - return new(less.tree.Dimension)(a.value + 1); - }, - _color: function(str) { - if (str.value === "evil red") { - return new(less.tree.Color)("600"); - } - } -}; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-main-spec.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-main-spec.js deleted file mode 100644 index b5261e75..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-main-spec.js +++ /dev/null @@ -1,3 +0,0 @@ -describe("less.js main tests", function() { - testLessEqualsInDocument(); -}); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-modify-vars-options.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-modify-vars-options.js deleted file mode 100644 index 2799ad55..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-modify-vars-options.js +++ /dev/null @@ -1,2 +0,0 @@ -/* exported less */ -var less = {}; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-modify-vars-spec.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-modify-vars-spec.js deleted file mode 100644 index 25ea5b68..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-modify-vars-spec.js +++ /dev/null @@ -1,42 +0,0 @@ -var alreadyRun = false; - -describe("less.js modify vars", function() { - beforeEach(function() { - // simulating "setUp" or "beforeAll" method - var lessOutputObj; - if (alreadyRun) - return; - - alreadyRun = true; - - // wait until the sheet is compiled first time - waitsFor(function() { - lessOutputObj = document.getElementById("less:test-less-simple"); - return lessOutputObj !== null; - }, "first generation of less:test-less-simple", 7000); - - // modify variables - runs(function() { - lessOutputObj.type = "not compiled yet"; - less.modifyVars({ - var1: "green", - var2: "purple" - }); - }); - - // wait until variables are modified - waitsFor(function() { - lessOutputObj = document.getElementById("less:test-less-simple"); - return lessOutputObj !== null && lessOutputObj.type === "text/css"; - }, "second generation of less:test-less-simple", 7000); - - }); - - testLessEqualsInDocument(); - it("Should log only 2 XHR requests", function() { - var xhrLogMessages = logMessages.filter(function(item) { - return (/XHR: Getting '/).test(item); - }); - expect(xhrLogMessages.length).toEqual(2); - }); -}); \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-no-js-errors-options.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-no-js-errors-options.js deleted file mode 100644 index 2a464944..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-no-js-errors-options.js +++ /dev/null @@ -1,4 +0,0 @@ -var less = {}; - -less.strictUnits = true; -less.javascriptEnabled = false; diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-no-js-errors-spec.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-no-js-errors-spec.js deleted file mode 100644 index 38aefe29..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-no-js-errors-spec.js +++ /dev/null @@ -1,4 +0,0 @@ -describe("less.js javascript disabled error tests", function() { - testLessErrorsInDocument(); -}); - diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-production-options.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-production-options.js deleted file mode 100644 index f8189d6a..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-production-options.js +++ /dev/null @@ -1,3 +0,0 @@ -var less = {}; -less.env = "production"; - diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-production-spec.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-production-spec.js deleted file mode 100644 index 8c8d8f42..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-production-spec.js +++ /dev/null @@ -1,5 +0,0 @@ -describe("less.js production behaviour", function() { - it("doesn't log any messages", function() { - expect(logMessages.length).toEqual(0); - }); -}); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-relative-urls-options.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-relative-urls-options.js deleted file mode 100644 index a20eb591..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-relative-urls-options.js +++ /dev/null @@ -1,3 +0,0 @@ -var less = {}; -less.relativeUrls = true; - diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-relative-urls-spec.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-relative-urls-spec.js deleted file mode 100644 index b13911ee..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-relative-urls-spec.js +++ /dev/null @@ -1,3 +0,0 @@ -describe("less.js browser test - relative url's", function() { - testLessEqualsInDocument(); -}); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-options.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-options.js deleted file mode 100644 index 5e475bb4..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-options.js +++ /dev/null @@ -1,3 +0,0 @@ -var less = {}; -less.rootpath = "https://www.github.com/"; - diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-relative-options.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-relative-options.js deleted file mode 100644 index f97baa4b..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-relative-options.js +++ /dev/null @@ -1,4 +0,0 @@ -var less = {}; -less.rootpath = "https://www.github.com/cloudhead/less.js/"; -less.relativeUrls = true; - diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-relative-spec.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-relative-spec.js deleted file mode 100644 index cd905739..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-relative-spec.js +++ /dev/null @@ -1,3 +0,0 @@ -describe("less.js browser test - rootpath and relative url's", function() { - testLessEqualsInDocument(); -}); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-spec.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-spec.js deleted file mode 100644 index b7b9ba1d..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/runner-rootpath-spec.js +++ /dev/null @@ -1,3 +0,0 @@ -describe("less.js browser test - rootpath url's", function() { - testLessEqualsInDocument(); -}); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/test-runner-template.tmpl b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/test-runner-template.tmpl deleted file mode 100644 index 17f644f5..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/browser/test-runner-template.tmpl +++ /dev/null @@ -1,47 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - <head> - <meta charset="utf-8"> - <title>Jasmine Spec Runner</title> - - <!-- generate script tags for tests --> - <% var generateScriptTags = function(allScripts) { allScripts.forEach(function(script){ %> - <script src="<%= script %>"></script> - <% }); }; %> - - <!-- for each test, generate CSS/LESS link tags --> - <% scripts.src.forEach(function(fullLessName) { - var pathParts = fullLessName.split('/'); - var fullCssName = fullLessName.replace(/less/g, 'css'); - var lessName = pathParts[pathParts.length - 1]; - var name = lessName.split('.')[0]; %> - <!-- the tags to be generated --> - <link id="original-less:test-less-<%= name %>" title="test-less-<%= name %>" rel="stylesheet/less" type="text/css" href="<%= fullLessName %>"> - <link id="expected-less:test-less-<%= name %>" rel="stylesheet" type="text/css" href="<%= fullCssName %>"> - <% }); %> - - <!-- generate grunt-contrib-jasmine link tags --> - <% css.forEach(function(style){ %> - <link rel="stylesheet" type="text/css" href="<%= style %>"> - <% }) %> - - <!-- inital grunt-contrib-jasmine scripts --> - <% generateScriptTags([].concat(scripts.polyfills, scripts.jasmine)); %> - - <!-- Helpers - The less options --> - <% generateScriptTags(scripts.helpers); %> - - <!-- Vendor - less.js and common code --> - <% generateScriptTags(scripts.vendor); %> - - <!-- Spec --> - <% generateScriptTags(scripts.specs); %> - - <!-- final grunt-contrib-jasmine scripts --> - <% generateScriptTags([].concat(scripts.reporters, scripts.start)); %> - </head> - - <body> - <!-- content --> - </body> -</html> diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/charsets.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/charsets.css deleted file mode 100644 index 9f44090c..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/charsets.css +++ /dev/null @@ -1 +0,0 @@ -@charset "UTF-8"; diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/colors.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/colors.css deleted file mode 100644 index 16956772..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/colors.css +++ /dev/null @@ -1,80 +0,0 @@ -#yelow #short { - color: #fea; -} -#yelow #long { - color: #ffeeaa; -} -#yelow #rgba { - color: rgba(255, 238, 170, 0.1); -} -#yelow #argb { - color: #1affeeaa; -} -#blue #short { - color: #00f; -} -#blue #long { - color: #0000ff; -} -#blue #rgba { - color: rgba(0, 0, 255, 0.1); -} -#blue #argb { - color: #1a0000ff; -} -#alpha #hsla { - color: rgba(61, 45, 41, 0.6); -} -#overflow .a { - color: #000000; -} -#overflow .b { - color: #ffffff; -} -#overflow .c { - color: #ffffff; -} -#overflow .d { - color: #00ff00; -} -#grey { - color: #c8c8c8; -} -#333333 { - color: #333333; -} -#808080 { - color: #808080; -} -#00ff00 { - color: #00ff00; -} -.lightenblue { - color: #3333ff; -} -.darkenblue { - color: #0000cc; -} -.unknowncolors { - color: blue2; - border: 2px solid superred; -} -.transparent { - color: transparent; - background-color: rgba(0, 0, 0, 0); -} -#alpha #fromvar { - opacity: 0.7; -} -#alpha #short { - opacity: 1; -} -#alpha #long { - opacity: 1; -} -#alpha #rgba { - opacity: 0.2; -} -#alpha #hsl { - opacity: 1; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/comments.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/comments.css deleted file mode 100644 index b85f5b4f..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/comments.css +++ /dev/null @@ -1,69 +0,0 @@ -/******************\ -* * -* Comment Header * -* * -\******************/ -/* - - Comment - -*/ -/* - * Comment Test - * - * - cloudhead (http://cloudhead.net) - * - */ -/* Colors - * ------ - * #EDF8FC (background blue) - * #166C89 (darkest blue) - * - * Text: - * #333 (standard text) // A comment within a comment! - * #1F9EC9 (standard link) - * - */ -/* @group Variables -------------------- */ -#comments, -.comments { - /**/ - color: red; - /* A C-style comment */ - /* A C-style comment */ - background-color: orange; - font-size: 12px; - /* lost comment */ - content: "content"; - border: 1px solid black; - padding: 0; - margin: 2em; -} -/* commented out - #more-comments { - color: grey; - } -*/ -.selector, -.lots, -.comments { - color: #808080, /* blue */ #ffa500; - -webkit-border-radius: 2px /* webkit only */; - -moz-border-radius: 8px /* moz only with operation */; -} -.test { - color: 1px; -} -#last { - color: #0000ff; -} -/* */ -/* { */ -/* */ -/* */ -/* */ -#div { - color: #A33; -} -/* } */ diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/compression/compression.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/compression/compression.css deleted file mode 100644 index 8d6786e5..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/compression/compression.css +++ /dev/null @@ -1,3 +0,0 @@ -#colours{color1:#fea;color2:#fea;color3:rgba(255,238,170,0.1);string:"#ffeeaa";/*! but not this type - Note preserved whitespace - */}dimensions{val:.1px;val:0;val:4cm;val:.2;val:5;angles-must-have-unit:0deg;durations-must-have-unit:0s;length-doesnt-have-unit:0;width:auto\9}@page{marks:none;@top-left-corner{vertical-align:top}@top-left{vertical-align:top}} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css-3.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css-3.css deleted file mode 100644 index 93b0a001..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css-3.css +++ /dev/null @@ -1,125 +0,0 @@ -.comma-delimited { - text-shadow: -1px -1px 1px #ff0000, 6px 5px 5px #ffff00; - -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; - -webkit-transform: rotate(-0.0000000001deg); -} -@font-face { - font-family: Headline; - unicode-range: U+??????, U+0???, U+0-7F, U+A5; -} -.other { - -moz-transform: translate(0, 11em) rotate(-90deg); - transform: rotateX(45deg); -} -.item[data-cra_zy-attr1b-ut3=bold] { - font-weight: bold; -} -p:not([class*="lead"]) { - color: black; -} -input[type="text"].class#id[attr=32]:not(1) { - color: white; -} -div#id.class[a=1][b=2].class:not(1) { - color: white; -} -ul.comma > li:not(:only-child)::after { - color: white; -} -ol.comma > li:nth-last-child(2)::after { - color: white; -} -li:nth-child(4n+1), -li:nth-child(-5n), -li:nth-child(-n+2) { - color: white; -} -a[href^="http://"] { - color: black; -} -a[href$="http://"] { - color: black; -} -form[data-disabled] { - color: black; -} -p::before { - color: black; -} -#issue322 { - -webkit-animation: anim2 7s infinite ease-in-out; -} -@-webkit-keyframes frames { - 0% { - border: 1px; - } - 5.5% { - border: 2px; - } - 100% { - border: 3px; - } -} -@keyframes fontbulger1 { - to { - font-size: 15px; - } - from, - to { - font-size: 12px; - } - 0%, - 100% { - font-size: 12px; - } -} -.units { - font: 1.2rem/2rem; - font: 8vw/9vw; - font: 10vh/12vh; - font: 12vm/15vm; - font: 12vmin/15vmin; - font: 1.2ch/1.5ch; -} -@supports ( box-shadow: 2px 2px 2px black ) or - ( -moz-box-shadow: 2px 2px 2px black ) { - .outline { - box-shadow: 2px 2px 2px black; - -moz-box-shadow: 2px 2px 2px black; - } -} -@-x-document url-prefix(""github.com"") { - h1 { - color: red; - } -} -@viewport { - font-size: 10px; -} -@namespace foo url(http://www.example.com); -foo|h1 { - color: blue; -} -foo|* { - color: yellow; -} -|h1 { - color: red; -} -*|h1 { - color: green; -} -h1 { - color: green; -} -.upper-test { - UpperCaseProperties: allowed; -} -@host { - div { - display: block; - } -} -::distributed(input::placeholder) { - color: #b3b3b3; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css-escapes.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css-escapes.css deleted file mode 100644 index 4d343aa6..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css-escapes.css +++ /dev/null @@ -1,24 +0,0 @@ -.escape\|random\|char { - color: red; -} -.mixin\!tUp { - font-weight: bold; -} -.\34 04 { - background: red; -} -.\34 04 strong { - color: #ff00ff; - font-weight: bold; -} -.trailingTest\+ { - color: red; -} -/* This hideous test of hideousness checks for the selector "blockquote" with various permutations of hex escapes */ -\62\6c\6f \63 \6B \0071 \000075o\74 e { - color: silver; -} -[ng\:cloak], -ng\:form { - display: none; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css-guards.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css-guards.css deleted file mode 100644 index dbb27dae..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css-guards.css +++ /dev/null @@ -1,18 +0,0 @@ -.light { - color: green; -} -.see-the { - color: orange; -} -.hide-the { - color: green; -} -.multiple-conditions-1 { - color: red; -} -.inheritance .test { - color: black; -} -.inheritance:hover { - color: pink; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css.css deleted file mode 100644 index ee1d48eb..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/css.css +++ /dev/null @@ -1,94 +0,0 @@ -@charset "utf-8"; -div { - color: black; -} -div { - width: 99%; -} -* { - min-width: 45em; -} -h1, -h2 > a > p, -h3 { - color: unset; -} -div.class { - color: blue; -} -div#id { - color: green; -} -.class#id { - color: purple; -} -.one.two.three { - color: grey; -} -@media print { - * { - font-size: 3em; - } -} -@media screen { - * { - font-size: 10px; - } -} -@font-face { - font-family: 'Garamond Pro'; -} -a:hover, -a:link { - color: #999; -} -p, -p:first-child { - text-transform: none; -} -q:lang(no) { - quotes: none; -} -p + h1 { - font-size: 2.2em; -} -#shorthands { - border: 1px solid #000; - font: 12px/16px Arial; - font: 100%/16px Arial; - margin: 1px 0; - padding: 0 auto; -} -#more-shorthands { - margin: 0; - padding: 1px 0 2px 0; - font: normal small / 20px 'Trebuchet MS', Verdana, sans-serif; - font: 0/0 a; - border-radius: 5px / 10px; -} -.misc { - -moz-border-radius: 2px; - display: -moz-inline-stack; - width: .1em; - background-color: #009998; - background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), to(#0000ff)); - filter: alpha(opacity=100); - width: auto\9; -} -.misc .nested-multiple { - multiple-semi-colons: yes; -} -#important { - color: red !important; - width: 100%!important; - height: 20px ! important; -} -@font-face { - font-family: font-a; -} -@font-face { - font-family: font-b; -} -.æøå { - margin: 0; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/debug/linenumbers-all.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/debug/linenumbers-all.css deleted file mode 100644 index c6fb355b..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/debug/linenumbers-all.css +++ /dev/null @@ -1,43 +0,0 @@ -@charset "UTF-8"; -/* line 3, {pathimport}test.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000033}} -/* @charset "ISO-8859-1"; */ -/* line 23, {pathimport}test.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000323}} -.tst3 { - color: grey; -} -/* line 15, {path}linenumbers.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000315}} -.test1 { - color: black; -} -/* line 6, {path}linenumbers.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\000036}} -.test2 { - color: red; -} -@media all { - /* line 5, {pathimport}test.less */ - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000035}} - .tst { - color: black; - } -} -@media all and screen { - /* line 7, {pathimport}test.less */ - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000037}} - .tst { - color: red; - } - /* line 9, {pathimport}test.less */ - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000039}} - .tst .tst3 { - color: white; - } -} -/* line 18, {pathimport}test.less */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000318}} -.tst2 { - color: white; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/debug/linenumbers-comments.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/debug/linenumbers-comments.css deleted file mode 100644 index 9c48baa9..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/debug/linenumbers-comments.css +++ /dev/null @@ -1,35 +0,0 @@ -@charset "UTF-8"; -/* line 3, {pathimport}test.less */ -/* @charset "ISO-8859-1"; */ -/* line 23, {pathimport}test.less */ -.tst3 { - color: grey; -} -/* line 15, {path}linenumbers.less */ -.test1 { - color: black; -} -/* line 6, {path}linenumbers.less */ -.test2 { - color: red; -} -@media all { - /* line 5, {pathimport}test.less */ - .tst { - color: black; - } -} -@media all and screen { - /* line 7, {pathimport}test.less */ - .tst { - color: red; - } - /* line 9, {pathimport}test.less */ - .tst .tst3 { - color: white; - } -} -/* line 18, {pathimport}test.less */ -.tst2 { - color: white; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/debug/linenumbers-mediaquery.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/debug/linenumbers-mediaquery.css deleted file mode 100644 index 3fdbbafc..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/debug/linenumbers-mediaquery.css +++ /dev/null @@ -1,35 +0,0 @@ -@charset "UTF-8"; -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000033}} -/* @charset "ISO-8859-1"; */ -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000323}} -.tst3 { - color: grey; -} -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000315}} -.test1 { - color: black; -} -@media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\000036}} -.test2 { - color: red; -} -@media all { - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000035}} - .tst { - color: black; - } -} -@media all and screen { - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000037}} - .tst { - color: red; - } - @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000039}} - .tst .tst3 { - color: white; - } -} -@media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000318}} -.tst2 { - color: white; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-chaining.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-chaining.css deleted file mode 100644 index 820e134f..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-chaining.css +++ /dev/null @@ -1,81 +0,0 @@ -.a, -.b, -.c { - color: black; -} -.f, -.e, -.d { - color: black; -} -.g.h, -.i.j.h, -.k.j.h { - color: black; -} -.i.j, -.k.j { - color: white; -} -.l, -.m, -.n, -.o, -.p, -.q, -.r, -.s, -.t { - color: black; -} -.u, -.v.u.v { - color: black; -} -.w, -.v.w.v { - color: black; -} -.x, -.y, -.z { - color: x; -} -.y, -.z, -.x { - color: y; -} -.z, -.x, -.y { - color: z; -} -.va, -.vb, -.vc { - color: black; -} -.vb, -.vc { - color: white; -} -@media tv { - .ma, - .mb, - .mc { - color: black; - } - .md, - .ma, - .mb, - .mc { - color: white; - } -} -@media tv and plasma { - .me, - .mf { - background: red; - } -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-clearfix.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-clearfix.css deleted file mode 100644 index 966892a2..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-clearfix.css +++ /dev/null @@ -1,19 +0,0 @@ -.clearfix, -.foo, -.bar { - *zoom: 1; -} -.clearfix:after, -.foo:after, -.bar:after { - content: ''; - display: block; - clear: both; - height: 0; -} -.foo { - color: red; -} -.bar { - color: blue; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-exact.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-exact.css deleted file mode 100644 index beff4133..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-exact.css +++ /dev/null @@ -1,37 +0,0 @@ -.replace.replace .replace, -.c.replace + .replace .replace, -.replace.replace .c, -.c.replace + .replace .c, -.rep_ace { - prop: copy-paste-replace; -} -.a .b .c { - prop: not_effected; -} -.a, -.effected { - prop: is_effected; -} -.a .b { - prop: not_effected; -} -.a .b.c { - prop: not_effected; -} -.c .b .a, -.a .b .a, -.c .a .a, -.a .a .a, -.c .b .c, -.a .b .c, -.c .a .c, -.a .a .c { - prop: not_effected; -} -.e.e, -.dbl { - prop: extend-double; -} -.e.e:hover { - hover: not-extended; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-media.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-media.css deleted file mode 100644 index 23bd7b85..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-media.css +++ /dev/null @@ -1,24 +0,0 @@ -.ext1 .ext2, -.all .ext2 { - background: black; -} -@media tv { - .ext1 .ext3, - .tv-lowres .ext3, - .all .ext3 { - color: white; - } - .tv-lowres { - background: blue; - } -} -@media tv and hires { - .ext1 .ext4, - .tv-hires .ext4, - .all .ext4 { - color: green; - } - .tv-hires { - background: red; - } -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-nest.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-nest.css deleted file mode 100644 index 2c3905d9..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-nest.css +++ /dev/null @@ -1,57 +0,0 @@ -.sidebar, -.sidebar2, -.type1 .sidebar3, -.type2.sidebar4 { - width: 300px; - background: red; -} -.sidebar .box, -.sidebar2 .box, -.type1 .sidebar3 .box, -.type2.sidebar4 .box { - background: #FFF; - border: 1px solid #000; - margin: 10px 0; -} -.sidebar2 { - background: blue; -} -.type1 .sidebar3 { - background: green; -} -.type2.sidebar4 { - background: red; -} -.button, -.submit { - color: black; -} -.button:hover, -.submit:hover { - color: white; -} -.button2 :hover { - nested: white; -} -.button2 :hover { - notnested: black; -} -.amp-test-h, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-a.amp-test-d.amp-test-b.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-a.amp-test-e.amp-test-g, -.amp-test-f.amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e + .amp-test-c .amp-test-b.amp-test-d.amp-test-b.amp-test-e.amp-test-g { - test: extended by masses of selectors; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-selector.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-selector.css deleted file mode 100644 index da47254b..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend-selector.css +++ /dev/null @@ -1,80 +0,0 @@ -.error, -.badError { - border: 1px #f00; - background: #fdd; -} -.error.intrusion, -.badError.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error, -.intrusion .badError { - display: none; -} -.badError { - border-width: 3px; -} -.foo .bar, -.foo .baz, -.ext1 .ext2 .bar, -.ext1 .ext2 .baz, -.ext3 .bar, -.ext3 .baz, -.ext4 .bar, -.ext4 .baz { - display: none; -} -div.ext5, -.ext6 > .ext5, -div.ext7, -.ext6 > .ext7 { - width: 100px; -} -.ext, -.a .c, -.b .c { - test: 1; -} -.a, -.b { - test: 2; -} -.a .c, -.b .c { - test: 3; -} -.a .c .d, -.b .c .d { - test: 4; -} -.replace.replace .replace, -.c.replace + .replace .replace, -.replace.replace .c, -.c.replace + .replace .c, -.rep_ace.rep_ace .rep_ace, -.c.rep_ace + .rep_ace .rep_ace, -.rep_ace.rep_ace .c, -.c.rep_ace + .rep_ace .c { - prop: copy-paste-replace; -} -.attributes [data="test"], -.attributes .attributes .attribute-test { - extend: attributes; -} -.attributes [data], -.attributes .attributes .attribute-test2 { - extend: attributes2; -} -.attributes [data="test3"], -.attributes .attributes .attribute-test { - extend: attributes2; -} -.header .header-nav, -.footer .footer-nav { - background: red; -} -.header .header-nav:before, -.footer .footer-nav:before { - background: blue; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend.css deleted file mode 100644 index 2895641a..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extend.css +++ /dev/null @@ -1,76 +0,0 @@ -.error, -.badError { - border: 1px #f00; - background: #fdd; -} -.error.intrusion, -.badError.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error, -.intrusion .badError { - display: none; -} -.badError { - border-width: 3px; -} -.foo .bar, -.foo .baz, -.ext1 .ext2 .bar, -.ext1 .ext2 .baz, -.ext3 .bar, -.ext3 .baz, -.foo .ext3, -.ext4 .bar, -.ext4 .baz, -.foo .ext4 { - display: none; -} -div.ext5, -.ext6 > .ext5, -div.ext7, -.ext6 > .ext7 { - width: 100px; -} -.ext8.ext9, -.fuu { - result: add-foo; -} -.ext8 .ext9, -.ext8 + .ext9, -.ext8 > .ext9, -.buu, -.zap, -.zoo { - result: bar-matched; -} -.ext8.nomatch { - result: none; -} -.ext8 .ext9, -.buu { - result: match-nested-bar; -} -.ext8.ext9, -.fuu { - result: match-nested-foo; -} -.aa, -.cc { - color: black; -} -.aa .dd, -.aa .ee { - background: red; -} -.bb, -.cc, -.ee, -.ff { - background: red; -} -.bb .bb, -.ff .ff { - color: black; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extract-and-length.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extract-and-length.css deleted file mode 100644 index f550e201..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/extract-and-length.css +++ /dev/null @@ -1,133 +0,0 @@ -.multiunit { - length: 6; - extract: abc "abc" 1 1px 1% #112233; -} -.incorrect-index { - v1: extract(a b c, 5); - v2: extract(a, b, c, -2); -} -.scalar { - var-value: variable; - var-length: 1; - ill-index: extract(variable, 2); - name-value: name; - string-value: "string"; - number-value: 12345678; - color-value: #0000ff; - rgba-value: rgba(80, 160, 240, 0.67); - empty-value: ; - name-length: 1; - string-length: 1; - number-length: 1; - color-length: 1; - rgba-length: 1; - empty-length: 1; -} -.mixin-arguments-1 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-2 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-3 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-4 { - length: 0; - extract: extract(, 2) | extract(, 1); -} -.mixin-arguments-2 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-3 { - length: 4; - extract: c | b | a; -} -.mixin-arguments-4 { - length: 3; - extract: c | b; -} -.mixin-arguments-2 { - length: 4; - extract: 3 | 2 | 1; -} -.mixin-arguments-3 { - length: 4; - extract: 3 | 2 | 1; -} -.mixin-arguments-4 { - length: 3; - extract: 3 | 2; -} -.md-space-comma { - length-1: 3; - extract-1: 1 2 3; - length-2: 3; - extract-2: 2; -} -.md-space-comma-as-args-2 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-space-comma-as-args-3 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-space-comma-as-args-4 { - length: 2; - extract: "x" "y" "z" | 1 2 3; -} -.md-cat-space-comma { - length-1: 3; - extract-1: 1 2 3; - length-2: 3; - extract-2: 2; -} -.md-cat-space-comma-as-args-2 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-cat-space-comma-as-args-3 { - length: 3; - extract: "x" "y" "z" | 1 2 3 | a b c; -} -.md-cat-space-comma-as-args-4 { - length: 2; - extract: "x" "y" "z" | 1 2 3; -} -.md-cat-comma-space { - length-1: 3; - extract-1: 1, 2, 3; - length-2: 3; - extract-2: 2; -} -.md-cat-comma-space-as-args-1 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-2 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-3 { - length: 3; - extract: "x", "y", "z" | 1, 2, 3 | a, b, c; -} -.md-cat-comma-space-as-args-4 { - length: 0; - extract: extract(, 2) | extract(, 1); -} -.md-3D { - length-1: 2; - extract-1: a b c d, 1 2 3 4; - length-2: 2; - extract-2: 5 6 7 8; - length-3: 4; - extract-3: 7; - length-4: 1; - extract-4: 8; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/functions.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/functions.css deleted file mode 100644 index 9694a7a3..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/functions.css +++ /dev/null @@ -1,139 +0,0 @@ -#functions { - color: #660000; - width: 16; - height: undefined("self"); - border-width: 5; - variable: 11; - background: linear-gradient(#000000, #ffffff); -} -#built-in { - escaped: -Some::weird(#thing, y); - lighten: #ffcccc; - darken: #330000; - saturate: #203c31; - desaturate: #29332f; - greyscale: #2e2e2e; - hsl-clamp: #ffffff; - spin-p: #bf6a40; - spin-n: #bf4055; - luma-white: 100%; - luma-black: 0%; - luma-black-alpha: 0%; - luma-red: 21%; - luma-green: 72%; - luma-blue: 7%; - luma-yellow: 93%; - luma-cyan: 79%; - luma-white-alpha: 50%; - contrast-filter: contrast(30%); - saturate-filter: saturate(5%); - contrast-white: #000000; - contrast-black: #ffffff; - contrast-red: #ffffff; - contrast-green: #000000; - contrast-blue: #ffffff; - contrast-yellow: #000000; - contrast-cyan: #000000; - contrast-light: #111111; - contrast-dark: #eeeeee; - contrast-wrongorder: #111111; - contrast-light-thresh: #111111; - contrast-dark-thresh: #eeeeee; - contrast-high-thresh: #eeeeee; - contrast-low-thresh: #111111; - contrast-light-thresh-per: #111111; - contrast-dark-thresh-per: #eeeeee; - contrast-high-thresh-per: #eeeeee; - contrast-low-thresh-per: #111111; - format: "rgb(32, 128, 64)"; - format-string: "hello world"; - format-multiple: "hello earth 2"; - format-url-encode: "red is %23ff0000"; - eformat: rgb(32, 128, 64); - unitless: 12; - unit: 14em; - hue: 98; - saturation: 12%; - lightness: 95%; - hsvhue: 98; - hsvsaturation: 12%; - hsvvalue: 95%; - red: 255; - green: 255; - blue: 255; - rounded: 11; - rounded-two: 10.67; - roundedpx: 3px; - roundedpx-three: 3.333px; - rounded-percentage: 10%; - ceil: 11px; - floor: 12px; - sqrt: 5px; - pi: 3.141592653589793; - mod: 2m; - abs: 4%; - tan: 0.9004040442978399; - sin: 0.17364817766693033; - cos: 0.8438539587324921; - atan: 0.1rad; - atan: 34.00000000000001deg; - atan: 45.00000000000001deg; - pow: 64px; - pow: 64; - pow: 27; - min: 0; - min: min("junk", 5); - min: 3pt; - max: 3; - max: max(8%, 1cm); - percentage: 20%; - color: #ff0011; - tint: #898989; - tint-full: #ffffff; - tint-percent: #898989; - shade: #686868; - shade-full: #000000; - shade-percent: #686868; - fade-out: rgba(255, 0, 0, 0.95); - fade-in: rgba(255, 0, 0, 0.9500000000000001); - hsv: #4d2926; - hsva: rgba(77, 40, 38, 0.2); - mix: #ff3300; - mix-0: #ffff00; - mix-100: #ff0000; - mix-weightless: #ff8000; - mixt: rgba(255, 0, 0, 0.5); -} -#built-in .is-a { - color: true; - color1: true; - color2: true; - color3: true; - keyword: true; - number: true; - string: true; - pixel: true; - percent: true; - em: true; - cat: true; -} -#alpha { - alpha: rgba(153, 94, 51, 0.6); - alpha2: 0.5; - alpha3: 0; -} -#blendmodes { - multiply: #ed0000; - screen: #f600f6; - overlay: #ed0000; - softlight: #ff0000; - hardlight: #0000ed; - difference: #f600f6; - exclusion: #f600f6; - average: #7b007b; - negation: #d73131; -} -#extract-and-length { - extract: 3 2 1 C B A; - length: 6; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/ie-filters.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/ie-filters.css deleted file mode 100644 index 007aa536..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/ie-filters.css +++ /dev/null @@ -1,9 +0,0 @@ -.nav { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=20); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr="#000000", GradientType=0); -} -.evalTest1 { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=30); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=5); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-inline.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-inline.css deleted file mode 100644 index f198d3c1..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-inline.css +++ /dev/null @@ -1,5 +0,0 @@ -this isn't very valid CSS. -@media (min-width: 600px) { - #css { color: yellow; } - -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-interpolation.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-interpolation.css deleted file mode 100644 index 16b7a150..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-interpolation.css +++ /dev/null @@ -1,6 +0,0 @@ -body { - width: 100%; -} -.a { - var: test; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-once.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-once.css deleted file mode 100644 index 2f86b3b3..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-once.css +++ /dev/null @@ -1,15 +0,0 @@ -#import { - color: #ff0000; -} -body { - width: 100%; -} -.test-f { - height: 10px; -} -body { - width: 100%; -} -.test-f { - height: 10px; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-reference.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-reference.css deleted file mode 100644 index c2d055a7..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import-reference.css +++ /dev/null @@ -1,55 +0,0 @@ -/* - The media statement above is invalid (no selector) - We should ban invalid media queries with properties and no selector? -*/ -.visible { - color: red; -} -.visible .c { - color: green; -} -.visible { - color: green; -} -.visible:hover { - color: green; -} -.visible { - color: green; -} -.only-with-visible + .visible, -.visible + .only-with-visible, -.visible + .visible { - color: green; -} -.only-with-visible + .visible .sub, -.visible + .only-with-visible .sub, -.visible + .visible .sub { - color: green; -} -.b { - color: red; - color: green; -} -.b .c { - color: green; -} -.b:hover { - color: green; -} -.b { - color: green; -} -.b + .b { - color: green; -} -.b + .b .sub { - color: green; -} -.y { - pulled-in: yes; -} -/* comment pulled in */ -.visible { - extend: test; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import.css deleted file mode 100644 index a3749181..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/import.css +++ /dev/null @@ -1,36 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Open+Sans); -@import url(/absolute/something.css) screen and (color) and (max-width: 600px); -@import url("//ha.com/file.css") (min-width: 100px); -#import-test { - height: 10px; - color: #ff0000; - width: 10px; - height: 30%; -} -@media screen and (max-width: 600px) { - body { - width: 100%; - } -} -#import { - color: #ff0000; -} -.mixin { - height: 10px; - color: #ff0000; -} -@media screen and (max-width: 601px) { - #css { - color: yellow; - } -} -@media screen and (max-width: 602px) { - body { - width: 100%; - } -} -@media screen and (max-width: 603px) { - #css { - color: yellow; - } -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/javascript.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/javascript.css deleted file mode 100644 index 8268ab33..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/javascript.css +++ /dev/null @@ -1,23 +0,0 @@ -.eval { - js: 42; - js: 2; - js: "hello world"; - js: 1, 2, 3; - title: "string"; - ternary: true; - multiline: 2; -} -.scope { - var: 42; - escaped: 7px; -} -.vars { - width: 8; -} -.escape-interpol { - width: hello world; -} -.arrays { - ary: "1, 2, 3"; - ary1: "1, 2, 3"; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/lazy-eval.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/lazy-eval.css deleted file mode 100644 index 1adfb8f3..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/lazy-eval.css +++ /dev/null @@ -1,3 +0,0 @@ -.lazy-eval { - width: 100%; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/legacy/legacy.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/legacy/legacy.css deleted file mode 100644 index 2f9bb80b..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/legacy/legacy.css +++ /dev/null @@ -1,7 +0,0 @@ -@media (-o-min-device-pixel-ratio: 2/1) { - .test-math-and-units { - font: ignores 0/0 rules; - test-division: 7em; - simple: 2px; - } -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/media.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/media.css deleted file mode 100644 index 607f0e44..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/media.css +++ /dev/null @@ -1,219 +0,0 @@ -@media print { - .class { - color: blue; - } - .class .sub { - width: 42; - } - .top, - header > h1 { - color: #444444; - } -} -@media screen { - body { - max-width: 480; - } -} -@media all and (device-aspect-ratio: 16 / 9) { - body { - max-width: 800px; - } -} -@media all and (orientation: portrait) { - aside { - float: none; - } -} -@media handheld and (min-width: 42), screen and (min-width: 20em) { - body { - max-width: 480px; - } -} -@media print { - body { - padding: 20px; - } - body header { - background-color: red; - } -} -@media print and (orientation: landscape) { - body { - margin-left: 20px; - } -} -@media screen { - .sidebar { - width: 300px; - } -} -@media screen and (orientation: landscape) { - .sidebar { - width: 500px; - } -} -@media a and b { - .first .second .third { - width: 300px; - } - .first .second .fourth { - width: 3; - } -} -@media a and b and c { - .first .second .third { - width: 500px; - } -} -@media a, b and c { - body { - width: 95%; - } -} -@media a and x, b and c and x, a and y, b and c and y { - body { - width: 100%; - } -} -.a { - background: black; -} -@media handheld { - .a { - background: white; - } -} -@media handheld and (max-width: 100px) { - .a { - background: red; - } -} -.b { - background: black; -} -@media handheld { - .b { - background: white; - } -} -@media handheld and (max-width: 200px) { - .b { - background: red; - } -} -@media only screen and (max-width: 200px) { - body { - width: 480px; - } -} -@media print { - @page :left { - margin: 0.5cm; - } - @page :right { - margin: 0.5cm; - } - @page Test:first { - margin: 1cm; - } - @page :first { - size: 8.5in 11in; - - @top-left { - margin: 1cm; - } - @top-left-corner { - margin: 1cm; - } - @top-center { - margin: 1cm; - } - @top-right { - margin: 1cm; - } - @top-right-corner { - margin: 1cm; - } - @bottom-left { - margin: 1cm; - } - @bottom-left-corner { - margin: 1cm; - } - @bottom-center { - margin: 1cm; - } - @bottom-right { - margin: 1cm; - } - @bottom-right-corner { - margin: 1cm; - } - @left-top { - margin: 1cm; - } - @left-middle { - margin: 1cm; - } - @left-bottom { - margin: 1cm; - } - @right-top { - margin: 1cm; - } - @right-middle { - content: "Page " counter(page); - } - @right-bottom { - margin: 1cm; - } - } -} -@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 128dpcm) { - .b { - background: red; - } -} -body { - background: red; -} -@media (max-width: 500px) { - body { - background: green; - } -} -@media (max-width: 1000px) { - body { - background: red; - background: blue; - } -} -@media (max-width: 1000px) and (max-width: 500px) { - body { - background: green; - } -} -@media (max-width: 1200px) { - /* a comment */ -} -@media (max-width: 1200px) and (max-width: 900px) { - body { - font-size: 11px; - } -} -@media (min-width: 480px) { - .nav-justified > li { - display: table-cell; - } -} -@media (min-width: 768px) and (min-width: 480px) { - .menu > li { - display: table-cell; - } -} -@media all and tv { - .all-and-tv-variables { - var: all-and-tv; - } -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/merge.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/merge.css deleted file mode 100644 index 4cf8c579..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/merge.css +++ /dev/null @@ -1,22 +0,0 @@ -.test1 { - transform: rotate(90deg), skew(30deg), scale(2, 4); -} -.test2 { - transform: rotate(90deg), skew(30deg); - transform: scaleX(45deg); -} -.test3 { - transform: scaleX(45deg); - background: url(data://img1.png); -} -.test4 { - transform: rotate(90deg), skew(30deg); - transform: scale(2, 4) !important; -} -.test5 { - transform: rotate(90deg), skew(30deg); - transform: scale(2, 4) !important; -} -.test6 { - transform: scale(2, 4); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-args.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-args.css deleted file mode 100644 index 2b6c5c96..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-args.css +++ /dev/null @@ -1,113 +0,0 @@ -#hidden { - color: transparent; -} -#hidden1 { - color: transparent; -} -.two-args { - color: blue; - width: 10px; - height: 99%; - border: 2px dotted #000000; -} -.one-arg { - width: 15px; - height: 49%; -} -.no-parens { - width: 5px; - height: 49%; -} -.no-args { - width: 5px; - height: 49%; -} -.var-args { - width: 45; - height: 17%; -} -.multi-mix { - width: 10px; - height: 29%; - margin: 4; - padding: 5; -} -body { - padding: 30px; - color: #ff0000; -} -.scope-mix { - width: 8; -} -.content { - width: 600px; -} -.content .column { - margin: 600px; -} -#same-var-name { - radius: 5px; -} -#var-inside { - width: 10px; -} -.arguments { - border: 1px solid #000000; - width: 1px; -} -.arguments2 { - border: 0px; - width: 0px; -} -.arguments3 { - border: 0px; - width: 0px; -} -.arguments4 { - border: 0 1 2 3 4; - rest: 1 2 3 4; - width: 0; -} -.edge-case { - border: "{"; - width: "{"; -} -.slash-vs-math { - border-radius: 2px/5px; - border-radius: 5px/10px; - border-radius: 6px; -} -.comma-vs-semi-colon { - one: a; - two: b, c; - one: d, e; - two: f; - one: g; - one: h; - one: i; - one: j; - one: k; - two: l; - one: m, n; - one: o, p; - two: q; - one: r, s; - two: t; -} -#named-conflict { - four: a, 11, 12, 13; - four: a, 21, 22, 23; -} -.test-mixin-default-arg { - defaults: 1px 1px 1px; - defaults: 2px 2px 2px; -} -.selector { - margin: 2, 2, 2, 2; -} -.selector2 { - margin: 2, 2, 2, 2; -} -.selector3 { - margin: 4; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-closure.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-closure.css deleted file mode 100644 index b1021b6f..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-closure.css +++ /dev/null @@ -1,9 +0,0 @@ -.class { - width: 99px; -} -.overwrite { - width: 99px; -} -.nested .class { - width: 5px; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-guards.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-guards.css deleted file mode 100644 index 25e6f287..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-guards.css +++ /dev/null @@ -1,82 +0,0 @@ -.light1 { - color: white; - margin: 1px; -} -.light2 { - color: black; - margin: 1px; -} -.max1 { - width: 6; -} -.max2 { - width: 8; -} -.glob1 { - margin: auto auto; -} -.ops1 { - height: gt-or-eq; - height: lt-or-eq; - height: lt-or-eq-alias; -} -.ops2 { - height: gt-or-eq; - height: not-eq; -} -.ops3 { - height: lt-or-eq; - height: lt-or-eq-alias; - height: not-eq; -} -.default1 { - content: default; -} -.test1 { - content: "true."; -} -.test2 { - content: "false."; -} -.test3 { - content: "false."; -} -.test4 { - content: "false."; -} -.test5 { - content: "false."; -} -.bool1 { - content: true and true; - content: true; - content: false, true; - content: false and true and true, true; - content: false, true and true; - content: false, false, true; - content: false, true and true and true, false; - content: not false; - content: not false and false, not false; -} -.equality-units { - test: pass; -} -.colorguardtest { - content: is #ff0000; - content: is not #0000ff its #ff0000; - content: is not #0000ff its #800080; -} -.stringguardtest { - content: is theme1; - content: is not theme2; - content: is theme1 no quotes; -} -#tryNumberPx { - catch: all; - declare: 4; - declare: 4px; -} -.call-lock-mixin .call-inner-lock-mixin { - a: 1; - x: 1; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-important.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-important.css deleted file mode 100644 index b100af7f..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-important.css +++ /dev/null @@ -1,45 +0,0 @@ -.class { - border: 1; - boxer: 1; - border-width: 1; - border: 2 !important; - boxer: 2 !important; - border-width: 2 !important; - border: 3; - boxer: 3; - border-width: 3; - border: 4 !important; - boxer: 4 !important; - border-width: 4 !important; - border: 5; - boxer: 5; - border-width: 5; - border: 0 !important; - boxer: 0 !important; - border-width: 0 !important; - border: 9 !important; - border: 9; - boxer: 9; - border-width: 9; -} -.class .inner { - test: 1; -} -.class .inner { - test: 2 !important; -} -.class .inner { - test: 3; -} -.class .inner { - test: 4 !important; -} -.class .inner { - test: 5; -} -.class .inner { - test: 0 !important; -} -.class .inner { - test: 9; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-named-args.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-named-args.css deleted file mode 100644 index e460aa10..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-named-args.css +++ /dev/null @@ -1,27 +0,0 @@ -.named-arg { - color: blue; - width: 5px; - height: 99%; - args: 1px 100%; - text-align: center; -} -.class { - width: 5px; - height: 19%; - args: 1px 20%; -} -.all-args-wrong-args { - width: 10px; - height: 9%; - args: 2px 10%; -} -.named-args2 { - width: 15px; - height: 49%; - color: #646464; -} -.named-args3 { - width: 5px; - height: 29%; - color: #123456; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-nested.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-nested.css deleted file mode 100644 index 6378c475..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-nested.css +++ /dev/null @@ -1,14 +0,0 @@ -.class .inner { - height: 300; -} -.class .inner .innest { - width: 30; - border-width: 60; -} -.class2 .inner { - height: 600; -} -.class2 .inner .innest { - width: 60; - border-width: 120; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-pattern.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-pattern.css deleted file mode 100644 index 8b828335..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins-pattern.css +++ /dev/null @@ -1,47 +0,0 @@ -.zero { - variadic: true; - zero: 0; - one: 1; - two: 2; - three: 3; -} -.one { - variadic: true; - one: 1; - one-req: 1; - two: 2; - three: 3; -} -.two { - variadic: true; - two: 2; - three: 3; -} -.three { - variadic: true; - three-req: 3; - three: 3; -} -.left { - left: 1; -} -.right { - right: 1; -} -.border-right { - color: black; - border-right: 4px; -} -.border-left { - color: black; - border-left: 4px; -} -.only-right { - right: 33; -} -.only-left { - left: 33; -} -.left-right { - both: 330; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins.css deleted file mode 100644 index 32097f97..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/mixins.css +++ /dev/null @@ -1,141 +0,0 @@ -.mixin { - border: 1px solid black; -} -.mixout { - border-color: orange; -} -.borders { - border-style: dashed; -} -#namespace .borders { - border-style: dotted; -} -#namespace .biohazard { - content: "death"; -} -#namespace .biohazard .man { - color: transparent; -} -#theme > .mixin { - background-color: grey; -} -#container { - color: black; - border: 1px solid black; - border-color: orange; - background-color: grey; -} -#header .milk { - color: white; - border: 1px solid black; - background-color: grey; -} -#header #cookie { - border-style: dashed; -} -#header #cookie .chips { - border-style: dotted; -} -#header #cookie .chips .calories { - color: black; - border: 1px solid black; - border-color: orange; - background-color: grey; -} -.secure-zone { - color: transparent; -} -.direct { - border-style: dotted; -} -.bo, -.bar { - width: 100%; -} -.bo { - border: 1px; -} -.ar.bo.ca { - color: black; -} -.jo.ki { - background: none; -} -.amp.support { - color: orange; -} -.amp.support .higher { - top: 0px; -} -.amp.support.deeper { - height: auto; -} -.extended { - width: 100%; - border: 1px; - background: none; - color: orange; - top: 0px; - height: auto; -} -.extended .higher { - top: 0px; -} -.extended.deeper { - height: auto; -} -.do .re .mi .fa .sol .la .si { - color: cyan; -} -.mutli-selector-parents { - color: cyan; -} -.foo .bar { - width: 100%; -} -.underParents { - color: red; -} -.parent .underParents { - color: red; -} -* + h1 { - margin-top: 25px; -} -legend + h1 { - margin-top: 0; -} -h1 + * { - margin-top: 10px; -} -* + h2 { - margin-top: 20px; -} -legend + h2 { - margin-top: 0; -} -h2 + * { - margin-top: 8px; -} -* + h3 { - margin-top: 15px; -} -legend + h3 { - margin-top: 0; -} -h3 + * { - margin-top: 5px; -} -.error { - background-image: "/a.png"; - background-position: center center; -} -.test-rec .recursion { - color: black; -} -.button { - padding-left: 44px; -} -.button.large { - padding-left: 40em; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/no-output.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/no-output.css deleted file mode 100644 index e69de29b..00000000 diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/operations.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/operations.css deleted file mode 100644 index fb9e0aff..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/operations.css +++ /dev/null @@ -1,49 +0,0 @@ -#operations { - color: #111111; - height: 9px; - width: 3em; - substraction: 0; - division: 1; -} -#operations .spacing { - height: 9px; - width: 3em; -} -.with-variables { - height: 16em; - width: 24em; - size: 1cm; -} -.with-functions { - color: #646464; - color: #ff8080; - color: #c94a4a; -} -.negative { - height: 0px; - width: 4px; -} -.shorthands { - padding: -1px 2px 0 -4px; -} -.rem-dimensions { - font-size: 5.5rem; -} -.colors { - color: #123; - border-color: #334455; - background-color: #000000; -} -.colors .other { - color: #222222; - border-color: #222222; -} -.negations { - variable: -4px; - variable1: 0px; - variable2: 0px; - variable3: 8px; - variable4: 0px; - paren: -4px; - paren2: 16px; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/parens.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/parens.css deleted file mode 100644 index 412823fb..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/parens.css +++ /dev/null @@ -1,33 +0,0 @@ -.parens { - border: 2px solid #000000; - margin: 1px 3px 16 3; - width: 36; - padding: 2px 36px; -} -.more-parens { - padding: 8 4 4 4px; - width-all: 96; - width-first: 16 * 6; - width-keep: (4 * 4) * 6; - height-keep: (7 * 7) + (8 * 8); - height-all: 113; - height-parts: 49 + 64; - margin-keep: (4 * (5 + 5) / 2) - (4 * 2); - margin-parts: 20 - 8; - margin-all: 12; - border-radius-keep: 4px * (1 + 1) / 4 + 3px; - border-radius-parts: 8px / 7px; - border-radius-all: 5px; -} -.negative { - neg-var: -1; - neg-var-paren: -(1); -} -.nested-parens { - width: 2 * (4 * (2 + (1 + 6))) - 1; - height: ((2 + 3) * (2 + 3) / (9 - 4)) + 1; -} -.mixed-units { - margin: 2px 4em 1 5pc; - padding: 6px 1em 2px 2; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/rulesets.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/rulesets.css deleted file mode 100644 index 408c76aa..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/rulesets.css +++ /dev/null @@ -1,33 +0,0 @@ -#first > .one { - font-size: 2em; -} -#first > .one > #second .two > #deux { - width: 50%; -} -#first > .one > #second .two > #deux #third { - height: 100%; -} -#first > .one > #second .two > #deux #third:focus { - color: black; -} -#first > .one > #second .two > #deux #third:focus #fifth > #sixth .seventh #eighth + #ninth { - color: purple; -} -#first > .one > #second .two > #deux #fourth, -#first > .one > #second .two > #deux #five, -#first > .one > #second .two > #deux #six { - color: #110000; -} -#first > .one > #second .two > #deux #fourth .seven, -#first > .one > #second .two > #deux #five .seven, -#first > .one > #second .two > #deux #six .seven, -#first > .one > #second .two > #deux #fourth .eight > #nine, -#first > .one > #second .two > #deux #five .eight > #nine, -#first > .one > #second .two > #deux #six .eight > #nine { - border: 1px solid black; -} -#first > .one > #second .two > #deux #fourth #ten, -#first > .one > #second .two > #deux #five #ten, -#first > .one > #second .two > #deux #six #ten { - color: red; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/scope.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/scope.css deleted file mode 100644 index baa05523..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/scope.css +++ /dev/null @@ -1,35 +0,0 @@ -.tiny-scope { - color: #998899; -} -.scope1 { - color: #0000ff; - border-color: #000000; -} -.scope1 .scope2 { - color: #0000ff; -} -.scope1 .scope2 .scope3 { - color: #ff0000; - border-color: #000000; - background-color: #ffffff; -} -.scope { - scoped-val: #008000; -} -.heightIsSet { - height: 1024px; -} -.useHeightInMixinCall { - mixin-height: 1024px; -} -.imported { - exists: true; -} -.testImported { - exists: true; -} -#allAreUsedHere { - default: 'top level'; - scope: 'top level'; - sub-scope-only: 'inside'; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/selectors.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/selectors.css deleted file mode 100644 index 51055047..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/selectors.css +++ /dev/null @@ -1,142 +0,0 @@ -h1 a:hover, -h2 a:hover, -h3 a:hover, -h1 p:hover, -h2 p:hover, -h3 p:hover { - color: red; -} -#all { - color: blue; -} -#the { - color: blue; -} -#same { - color: blue; -} -ul, -li, -div, -q, -blockquote, -textarea { - margin: 0; -} -td { - margin: 0; - padding: 0; -} -td, -input { - line-height: 1em; -} -a { - color: red; -} -a:hover { - color: blue; -} -div a { - color: green; -} -p a span { - color: yellow; -} -.foo .bar .qux, -.foo .baz .qux { - display: block; -} -.qux .foo .bar, -.qux .foo .baz { - display: inline; -} -.qux.foo .bar, -.qux.foo .baz { - display: inline-block; -} -.qux .foo .bar .biz, -.qux .foo .baz .biz { - display: none; -} -.a.b.c { - color: red; -} -.c .b.a { - color: red; -} -.foo .p.bar { - color: red; -} -.foo.p.bar { - color: red; -} -.foo + .foo { - background: amber; -} -.foo + .foo { - background: amber; -} -.foo + .foo, -.foo + .bar, -.bar + .foo, -.bar + .bar { - background: amber; -} -.foo a > .foo a, -.foo a > .bar a, -.foo a > .foo b, -.foo a > .bar b, -.bar a > .foo a, -.bar a > .bar a, -.bar a > .foo b, -.bar a > .bar b, -.foo b > .foo a, -.foo b > .bar a, -.foo b > .foo b, -.foo b > .bar b, -.bar b > .foo a, -.bar b > .bar a, -.bar b > .foo b, -.bar b > .bar b { - background: amber; -} -.other ::fnord { - color: #ff0000; -} -.other::fnord { - color: #ff0000; -} -.other ::bnord { - color: #ff0000; -} -.other::bnord { - color: #ff0000; -} -.blood { - color: red; -} -.bloodred { - color: green; -} -#blood.blood.red.black { - color: black; -} -:nth-child(3) { - selector: interpolated; -} -.test:nth-child(odd):not(:nth-child(3)) { - color: #ff0000; -} -[prop], -[prop=10%], -[prop="value3"], -[prop*="val3"], -[|prop~="val3"], -[*|prop$="val3"], -[ns|prop^="val3"], -[3^="val3"], -[3=3], -[3] { - attributes: yes; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/static-urls/urls.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/static-urls/urls.css deleted file mode 100644 index 03ec2576..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/static-urls/urls.css +++ /dev/null @@ -1,40 +0,0 @@ -@import "css/background.css"; -/*@import "folder (1)/import-test-d.css";*/ -/*@font-face { - src: local(Futura-Medium), url(folder\ \(1\)/fonts.svg#MyGeometricModern) format("svg"); -}*/ -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -/*#misc { - background-image: url(folder\ \(1\)/images/image.jpg); -}*/ -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} -#svg-data-uri { - background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>'); -} -/*.comma-delimited { - background: url(folder\ \(1\)/bg.jpg) no-repeat, url(folder\ \(1\)/bg.png) repeat-x top left, url(folder\ \(1\)/bg); -} -.values { - url: url('folder (1)/Trebuchet'); -}*/ -#logo { - width: 100px; - height: 100px; - background: url('assets/logo.png'); -} -@font-face { - font-family: xecret; - src: url('assets/xecret.ttf'); -} -#secret { - font-family: xecret, sans-serif; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/strings.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/strings.css deleted file mode 100644 index cd6d6020..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/strings.css +++ /dev/null @@ -1,43 +0,0 @@ -#strings { - background-image: url("http://son-of-a-banana.com"); - quotes: "~" "~"; - content: "#*%:&^,)!.(~*})"; - empty: ""; - brackets: "{" "}"; - escapes: "\"hello\" \\world"; - escapes2: "\"llo"; -} -#comments { - content: "/* hello */ // not-so-secret"; -} -#single-quote { - quotes: "'" "'"; - content: '""#!&""'; - empty: ''; - semi-colon: ';'; -} -#escaped { - filter: DX.Transform.MS.BS.filter(opacity=50); -} -#one-line { - image: url(http://tooks.com); -} -#crazy { - image: url(http://), "}", url("http://}"); -} -#interpolation { - url: "http://lesscss.org/dev/image.jpg"; - url2: "http://lesscss.org/image-256.jpg"; - url3: "http://lesscss.org#445566"; - url4: "http://lesscss.org/hello"; - url5: "http://lesscss.org/54.4px"; -} -.mix-mul-class { - color: #0000ff; - color: #ff0000; - color: #000000; - color: #ffa500; -} -.watermark { - family: Univers, Arial, Verdana, San-Serif; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/urls.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/urls.css deleted file mode 100644 index a377d293..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/urls.css +++ /dev/null @@ -1,62 +0,0 @@ -@import "css/background.css"; -@import "import/import-test-d.css"; -@import "file.css"; -@font-face { - src: local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; - background: url("img.jpg") center / 100px; - background: #ffffff url(image.png) center / 1px 100px repeat-x scroll content-box padding-box; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); - background-image: url("http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700"); -} -#svg-data-uri { - background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>'); -} -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - url: url('Trebuchet'); -} -#logo { - width: 100px; - height: 100px; - background: url('import/assets/logo.png'); -} -@font-face { - font-family: xecret; - src: url('import/assets/xecret.ttf'); -} -#secret { - font-family: xecret, sans-serif; -} -#data-uri { - uri: url('data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg=='); -} -#data-uri-guess { - uri: url('data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg=='); -} -#data-uri-ascii { - uri-1: url('data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A'); - uri-2: url('data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A'); -} -#data-uri-toobig { - uri: url('../data/data-uri-fail.png'); -} -#svg-functions { - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkaWVudCkiIC8+PC9zdmc+'); - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIvPjxzdG9wIG9mZnNldD0iMyUiIHN0b3AtY29sb3I9IiNmZmE1MDAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZGllbnQpIiAvPjwvc3ZnPg=='); - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIxJSIgc3RvcC1jb2xvcj0iI2M0YzRjNCIvPjxzdG9wIG9mZnNldD0iMyUiIHN0b3AtY29sb3I9IiNmZmE1MDAiLz48c3RvcCBvZmZzZXQ9IjUlIiBzdG9wLWNvbG9yPSIjMDA4MDAwIi8+PHN0b3Agb2Zmc2V0PSI5NSUiIHN0b3AtY29sb3I9IiNmZmZmZmYiLz48L2xpbmVhckdyYWRpZW50PjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZGllbnQpIiAvPjwvc3ZnPg=='); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/variables.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/variables.css deleted file mode 100644 index f8d8518b..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/variables.css +++ /dev/null @@ -1,45 +0,0 @@ -.variables { - width: 14cm; -} -.variables { - height: 24px; - color: #888888; - font-family: "Trebuchet MS", Verdana, sans-serif; - quotes: "~" "~"; -} -.redef { - zero: 0; -} -.redef .inition { - three: 3; -} -.values { - minus-one: -1; - font-family: 'Trebuchet', 'Trebuchet', 'Trebuchet'; - color: #888888 !important; - multi: something 'A', B, C, 'Trebuchet'; -} -.variable-names { - name: 'hello'; -} -.alpha { - filter: alpha(opacity=42); -} -.testPollution { - a: 'no-pollution'; -} -.units { - width: 1px; - same-unit-as-previously: 1px; - square-pixel-divided: 1px; - odd-unit: 2; - percentage: 500%; - pixels: 500px; - conversion-metric-a: 30mm; - conversion-metric-b: 3cm; - conversion-imperial: 3in; - custom-unit: 420octocats; - custom-unit-cancelling: 18dogs; - mix-units: 2px; - invalid-units: 1px; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/whitespace.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/whitespace.css deleted file mode 100644 index 74c9b65e..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/css/whitespace.css +++ /dev/null @@ -1,42 +0,0 @@ -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white; -} -.whitespace { - color: white ; -} -.white, -.space, -.mania { - color: white; -} -.no-semi-column { - color: #ffffff; -} -.no-semi-column { - color: white; - white-space: pre; -} -.no-semi-column { - border: 2px solid #ffffff; -} -.newlines { - background: the, - great, - wall; - border: 2px - solid - black; -} -.sel .newline_ws .tab_ws { - color: white; - background-position: 45 -23; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/data/data-uri-fail.png b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/data/data-uri-fail.png deleted file mode 100644 index f91b59fb314c105c5d290775cd5395bc6140caf7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52420 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 N002ovPDHLkV1gWiucQC~ diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/data/image.jpg b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/data/image.jpg deleted file mode 100644 index 83f77790..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/data/image.jpg +++ /dev/null @@ -1 +0,0 @@ -not actually a jpeg file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/data/page.html b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/data/page.html deleted file mode 100644 index ccdfe565..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/data/page.html +++ /dev/null @@ -1 +0,0 @@ -<h1>This page is 100% Awesome.</h1> diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less-test.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less-test.js deleted file mode 100644 index 331cf761..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less-test.js +++ /dev/null @@ -1,260 +0,0 @@ -/*jshint latedef: nofunc */ -var path = require('path'), - fs = require('fs'), - sys = require('util'); - -var less = require('../lib/less'); -var stylize = require('../lib/less/lessc_helper').stylize; - -var globals = Object.keys(global); - -var oneTestOnly = process.argv[2]; - -var isVerbose = process.env.npm_config_loglevel === 'verbose'; - -var totalTests = 0, - failedTests = 0, - passedTests = 0; - -less.tree.functions.add = function (a, b) { - return new(less.tree.Dimension)(a.value + b.value); -}; -less.tree.functions.increment = function (a) { - return new(less.tree.Dimension)(a.value + 1); -}; -less.tree.functions._color = function (str) { - if (str.value === "evil red") { return new(less.tree.Color)("600"); } -}; - -console.log("\n" + stylize("LESS", 'underline') + "\n"); - -runTestSet({strictMath: true, relativeUrls: true, silent: true}); -runTestSet({strictMath: true, strictUnits: true}, "errors/", - testErrors, null, getErrorPathReplacementFunction("errors")); -runTestSet({strictMath: true, strictUnits: true, javascriptEnabled: false}, "no-js-errors/", - testErrors, null, getErrorPathReplacementFunction("no-js-errors")); -runTestSet({strictMath: true, dumpLineNumbers: 'comments'}, "debug/", null, - function(name) { return name + '-comments'; }); -runTestSet({strictMath: true, dumpLineNumbers: 'mediaquery'}, "debug/", null, - function(name) { return name + '-mediaquery'; }); -runTestSet({strictMath: true, dumpLineNumbers: 'all'}, "debug/", null, - function(name) { return name + '-all'; }); -runTestSet({strictMath: true, relativeUrls: false, rootpath: "folder (1)/"}, "static-urls/"); -runTestSet({strictMath: true, compress: true}, "compression/"); -runTestSet({}, "legacy/"); -runTestSet({strictMath: true, strictUnits: true, sourceMap: true }, "sourcemaps/", - testSourcemap, null, null, function(filename) { return path.join('test/sourcemaps', filename) + '.json'; }); - -testNoOptions(); - -function getErrorPathReplacementFunction(dir) { - return function(input) { - return input.replace( - "{path}", path.join(process.cwd(), "/test/less/" + dir + "/")) - .replace("{pathrel}", path.join("test", "less", dir + "/")) - .replace("{pathhref}", "") - .replace("{404status}", "") - .replace(/\r\n/g, '\n'); - }; -} - -function testSourcemap(name, err, compiledLess, doReplacements, sourcemap) { - fs.readFile(path.join('test/', name) + '.json', 'utf8', function (e, expectedSourcemap) { - sys.print("- " + name + ": "); - if (sourcemap === expectedSourcemap) { - ok('OK'); - } else if (err) { - fail("ERROR: " + (err && err.message)); - if (isVerbose) { - console.error(); - console.error(err.stack); - } - } else { - difference("FAIL", expectedSourcemap, sourcemap); - } - }); -} - -function testErrors(name, err, compiledLess, doReplacements) { - fs.readFile(path.join('test/less/', name) + '.txt', 'utf8', function (e, expectedErr) { - sys.print("- " + name + ": "); - expectedErr = doReplacements(expectedErr, 'test/less/errors/'); - if (!err) { - if (compiledLess) { - fail("No Error", 'red'); - } else { - fail("No Error, No Output"); - } - } else { - var errMessage = less.formatError(err); - if (errMessage === expectedErr) { - ok('OK'); - } else { - difference("FAIL", expectedErr, errMessage); - } - } - }); -} - -function globalReplacements(input, directory) { - var p = path.join(process.cwd(), directory), - pathimport = path.join(process.cwd(), directory + "import/"), - pathesc = p.replace(/[.:/\\]/g, function(a) { return '\\' + (a=='\\' ? '\/' : a); }), - pathimportesc = pathimport.replace(/[.:/\\]/g, function(a) { return '\\' + (a=='\\' ? '\/' : a); }); - - return input.replace(/\{path\}/g, p) - .replace(/\{pathesc\}/g, pathesc) - .replace(/\{pathimport\}/g, pathimport) - .replace(/\{pathimportesc\}/g, pathimportesc) - .replace(/\r\n/g, '\n'); -} - -function checkGlobalLeaks() { - return Object.keys(global).filter(function(v) { - return globals.indexOf(v) < 0; - }); -} - -function runTestSet(options, foldername, verifyFunction, nameModifier, doReplacements, getFilename) { - foldername = foldername || ""; - - if(!doReplacements) { - doReplacements = globalReplacements; - } - - fs.readdirSync(path.join('test/less/', foldername)).forEach(function (file) { - if (! /\.less/.test(file)) { return; } - - var name = foldername + path.basename(file, '.less'); - - if (oneTestOnly && name !== oneTestOnly) { - return; - } - - totalTests++; - - if (options.sourceMap) { - var sourceMapOutput; - options.writeSourceMap = function(output) { - sourceMapOutput = output; - }; - options.sourceMapOutputFilename = name + ".css"; - options.sourceMapBasepath = path.join(process.cwd(), "test/less"); - options.sourceMapRootpath = "testweb/"; - } - - toCSS(options, path.join('test/less/', foldername + file), function (err, less) { - - if (verifyFunction) { - return verifyFunction(name, err, less, doReplacements, sourceMapOutput); - } - var css_name = name; - if(nameModifier) { css_name = nameModifier(name); } - fs.readFile(path.join('test/css', css_name) + '.css', 'utf8', function (e, css) { - sys.print("- " + css_name + ": "); - - css = css && doReplacements(css, 'test/less/' + foldername); - if (less === css) { ok('OK'); } - else if (err) { - fail("ERROR: " + (err && err.message)); - if (isVerbose) { - console.error(); - console.error(err.stack); - } - } else { - difference("FAIL", css, less); - } - }); - }); - }); -} - -function diff(left, right) { - require('diff').diffLines(left, right).forEach(function(item) { - if(item.added || item.removed) { - var text = item.value.replace("\n", String.fromCharCode(182) + "\n"); - sys.print(stylize(text, item.added ? 'green' : 'red')); - } else { - sys.print(item.value); - } - }); - console.log(""); -} - -function fail(msg) { - console.error(stylize(msg, 'red')); - failedTests++; - endTest(); -} - -function difference(msg, left, right) { - console.warn(stylize(msg, 'yellow')); - failedTests++; - - diff(left, right); - endTest(); -} - -function ok(msg) { - console.log(stylize(msg, 'green')); - passedTests++; - endTest(); -} - -function endTest() { - var leaked = checkGlobalLeaks(); - if (failedTests + passedTests === totalTests) { - console.log(""); - if (failedTests > 0) { - console.error(failedTests + stylize(" Failed", "red") + ", " + passedTests + " passed"); - } else { - console.log(stylize("All Passed ", "green") + passedTests + " run"); - } - if (leaked.length > 0) { - console.log(""); - console.warn(stylize("Global leak detected: ", "red") + leaked.join(', ')); - } - - if (leaked.length || failedTests) { - //process.exit(1); - process.on('exit', function() { process.reallyExit(1) }); - } - } -} - -function toCSS(options, path, callback) { - var css; - options = options || {}; - fs.readFile(path, 'utf8', function (e, str) { - if (e) { return callback(e); } - - options.paths = [require('path').dirname(path)]; - options.filename = require('path').resolve(process.cwd(), path); - options.optimization = options.optimization || 0; - - new(less.Parser)(options).parse(str, function (err, tree) { - if (err) { - callback(err); - } else { - try { - css = tree.toCSS(options); - callback(null, css); - } catch (e) { - callback(e); - } - } - }); - }); -} - -function testNoOptions() { - totalTests++; - try { - sys.print("- Integration - creating parser without options: "); - new(less.Parser)(); - } catch(e) { - fail(stylize("FAIL\n", "red")); - return; - } - ok(stylize("OK\n", "green")); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/charsets.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/charsets.less deleted file mode 100644 index 550d40e9..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/charsets.less +++ /dev/null @@ -1,3 +0,0 @@ -@charset "UTF-8"; - -@import "import/import-charset-test"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/colors.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/colors.less deleted file mode 100644 index 656ca636..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/colors.less +++ /dev/null @@ -1,92 +0,0 @@ -#yelow { - #short { - color: #fea; - } - #long { - color: #ffeeaa; - } - #rgba { - color: rgba(255, 238, 170, 0.1); - } - #argb { - color: argb(rgba(255, 238, 170, 0.1)); - } -} - -#blue { - #short { - color: #00f; - } - #long { - color: #0000ff; - } - #rgba { - color: rgba(0, 0, 255, 0.1); - } - #argb { - color: argb(rgba(0, 0, 255, 0.1)); - } -} - -#alpha #hsla { - color: hsla(11, 20%, 20%, 0.6); -} - -#overflow { - .a { color: (#111111 - #444444); } // #000000 - .b { color: (#eee + #fff); } // #ffffff - .c { color: (#aaa * 3); } // #ffffff - .d { color: (#00ee00 + #009900); } // #00ff00 -} - -#grey { - color: rgb(200, 200, 200); -} - -#333333 { - color: rgb(20%, 20%, 20%); -} - -#808080 { - color: hsl(50, 0%, 50%); -} - -#00ff00 { - color: hsl(120, 100%, 50%); -} - -.lightenblue { - color: lighten(blue, 10%); -} - -.darkenblue { - color: darken(blue, 10%); -} - -.unknowncolors { - color: blue2; - border: 2px solid superred; -} - -.transparent { - color: transparent; - background-color: rgba(0, 0, 0, 0); -} -#alpha { - @colorvar: rgba(150, 200, 150, 0.7); - #fromvar { - opacity: alpha(@colorvar); - } - #short { - opacity: alpha(#aaa); - } - #long { - opacity: alpha(#bababa); - } - #rgba { - opacity: alpha(rgba(50, 120, 95, 0.2)); - } - #hsl { - opacity: alpha(hsl(120, 100%, 50%)); - } -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/comments.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/comments.less deleted file mode 100644 index 7859911e..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/comments.less +++ /dev/null @@ -1,83 +0,0 @@ -/******************\ -* * -* Comment Header * -* * -\******************/ - -/* - - Comment - -*/ - -/* - * Comment Test - * - * - cloudhead (http://cloudhead.net) - * - */ - -//////////////// -@var: "content"; -//////////////// - -/* Colors - * ------ - * #EDF8FC (background blue) - * #166C89 (darkest blue) - * - * Text: - * #333 (standard text) // A comment within a comment! - * #1F9EC9 (standard link) - * - */ - -/* @group Variables -------------------- */ -#comments /* boo *//* boo again*/, -//.commented_out1 -//.commented_out2 -//.commented_out3 -.comments //end of comments1 -//end of comments2 -{ - /**/ // An empty comment - color: red; /* A C-style comment */ /* A C-style comment */ - background-color: orange; // A little comment - font-size: 12px; - - /* lost comment */ content: @var; - - border: 1px solid black; - - // padding & margin // - padding: 0; // }{ '" - margin: 2em; -} // - -/* commented out - #more-comments { - color: grey; - } -*/ - -.selector /* .with */, .lots, /* of */ .comments { - color: grey, /* blue */ orange; - -webkit-border-radius: 2px /* webkit only */; - -moz-border-radius: (2px * 4) /* moz only with operation */; -} - -.mixin_def_with_colors(@a: white, // in - @b: 1px //put in @b - causes problems! ---> - ) // the - when (@a = white) { - .test { - color: @b; - } -} -.mixin_def_with_colors(); - -#last { color: blue } -// - -/* *//* { *//* *//* *//* */#div { color:#A33; }/* } */ diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/compression/compression.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/compression/compression.less deleted file mode 100644 index e6a0fe79..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/compression/compression.less +++ /dev/null @@ -1,32 +0,0 @@ -#colours { - color1: #fea; - color2: #ffeeaa; - color3: rgba(255, 238, 170, 0.1); - @color1: #fea; - string: "@{color1}"; - /* comments are stripped */ - // both types! - /*! but not this type - Note preserved whitespace - */ -} -dimensions { - val: 0.1px; - val: 0em; - val: 4cm; - val: 0.2; - val: 5; - angles-must-have-unit: 0deg; - durations-must-have-unit: 0s; - length-doesnt-have-unit: 0px; - width: auto\9; -} -@page { - marks: none; -@top-left-corner { - vertical-align: top; -} -@top-left { - vertical-align: top; -} -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css-3.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css-3.less deleted file mode 100644 index c31a6eb2..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css-3.less +++ /dev/null @@ -1,125 +0,0 @@ -.comma-delimited { - text-shadow: -1px -1px 1px red, 6px 5px 5px yellow; - -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, - 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; - -webkit-transform: rotate(-0.0000000001deg); -} -@font-face { - font-family: Headline; - unicode-range: U+??????, U+0???, U+0-7F, U+A5; -} -.other { - -moz-transform: translate(0, 11em) rotate(-90deg); - transform: rotateX(45deg); -} -.item[data-cra_zy-attr1b-ut3=bold] { - font-weight: bold; -} -p:not([class*="lead"]) { - color: black; -} - -input[type="text"].class#id[attr=32]:not(1) { - color: white; -} - -div#id.class[a=1][b=2].class:not(1) { - color: white; -} - -ul.comma > li:not(:only-child)::after { - color: white; -} - -ol.comma > li:nth-last-child(2)::after { - color: white; -} - -li:nth-child(4n+1), -li:nth-child(-5n), -li:nth-child(-n+2) { - color: white; -} - -a[href^="http://"] { - color: black; -} - -a[href$="http://"] { - color: black; -} - -form[data-disabled] { - color: black; -} - -p::before { - color: black; -} - -#issue322 { - -webkit-animation: anim2 7s infinite ease-in-out; -} - -@-webkit-keyframes frames { - 0% { border: 1px } - 5.5% { border: 2px } - 100% { border: 3px } -} - -@keyframes fontbulger1 { - to { - font-size: 15px; - } - from,to { - font-size: 12px; - } - 0%,100% { - font-size: 12px; - } -} - -.units { - font: 1.2rem/2rem; - font: 8vw/9vw; - font: 10vh/12vh; - font: 12vm/15vm; - font: 12vmin/15vmin; - font: 1.2ch/1.5ch; -} - -@supports ( box-shadow: 2px 2px 2px black ) or - ( -moz-box-shadow: 2px 2px 2px black ) { - .outline { - box-shadow: 2px 2px 2px black; - -moz-box-shadow: 2px 2px 2px black; - } -} - -@-x-document url-prefix(""github.com"") { - h1 { - color: red; - } -} - -@viewport { - font-size: 10px; -} -@namespace foo url(http://www.example.com); - -foo|h1 { color: blue; } -foo|* { color: yellow; } -|h1 { color: red; } -*|h1 { color: green; } -h1 { color: green; } -.upper-test { - UpperCaseProperties: allowed; -} -@host { - div { - display: block; - } -} -::distributed(input::placeholder) { - color: #b3b3b3; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css-escapes.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css-escapes.less deleted file mode 100644 index 6a4b2830..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css-escapes.less +++ /dev/null @@ -1,33 +0,0 @@ -@ugly: fuchsia; - -.escape\|random\|char { - color: red; -} - -.mixin\!tUp { - font-weight: bold; -} - -// class="404" -.\34 04 { - background: red; - - strong { - color: @ugly; - .mixin\!tUp; - } -} - -.trailingTest\+ { - color: red; -} - -/* This hideous test of hideousness checks for the selector "blockquote" with various permutations of hex escapes */ -\62\6c\6f \63 \6B \0071 \000075o\74 e { - color: silver; -} - -[ng\:cloak], -ng\:form { - display: none; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css-guards.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css-guards.less deleted file mode 100644 index 41fbfbf5..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css-guards.less +++ /dev/null @@ -1,64 +0,0 @@ - -.light when (lightness(@a) > 50%) { - color: green; -} -.dark when (lightness(@a) < 50%) { - color: orange; -} -@a: #ddd; - -.see-the { - @a: #444; // this mirrors what mixins do - they evaluate guards at the point of execution - .light(); - .dark(); -} - -.hide-the { - .light(); - .dark(); -} - -.multiple-conditions-1 when (@b = 1), (@c = 2), (@d = 3) { - color: red; -} - -.multiple-conditions-2 when (@b = 1), (@c = 2), (@d = 2) { - color: blue; -} - -@b: 2; -@c: 3; -@d: 3; - -.inheritance when (@b = 2) { - .test { - color: black; - } - &:hover { - color: pink; - } - .hideme when (@b = 1) { - color: green; - } - & when (@b = 1) { - hideme: green; - } -} - -.hideme when (@b = 1) { - .test { - color: black; - } - &:hover { - color: pink; - } - .hideme when (@b = 1) { - color: green; - } -} - -& when (@b = 1) { - .hideme { - color: red; - } -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css.less deleted file mode 100644 index 90b354c4..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/css.less +++ /dev/null @@ -1,107 +0,0 @@ -@charset "utf-8"; -div { color: black; } -div { width: 99%; } - -* { - min-width: 45em; -} - -h1, h2 > a > p, h3 { - color: unset; -} - -div.class { - color: blue; -} - -div#id { - color: green; -} - -.class#id { - color: purple; -} - -.one.two.three { - color: grey; -} - -@media print { - * { - font-size: 3em; - } -} - -@media screen { - * { - font-size: 10px; - } -} - -@font-face { - font-family: 'Garamond Pro'; -} - -a:hover, a:link { - color: #999; -} - -p, p:first-child { - text-transform: none; -} - -q:lang(no) { - quotes: none; -} - -p + h1 { - font-size: +2.2em; -} - -#shorthands { - border: 1px solid #000; - font: 12px/16px Arial; - font: 100%/16px Arial; - margin: 1px 0; - padding: 0 auto; -} - -#more-shorthands { - margin: 0.1%; - padding: 1px 0 2px 0; - font: normal small/20px 'Trebuchet MS', Verdana, sans-serif; - font: 0/0 a; - border-radius: 5px / 10px; -} - -.misc { - -moz-border-radius: 2px; - display: -moz-inline-stack; - width: .1em; - background-color: #009998; - background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue)); - .nested-multiple { - multiple-semi-colons: yes;;;;;; - }; - filter: alpha(opacity=100); - width: auto\9; -} - -#important { - color: red !important; - width: 100%!important; - height: 20px ! important; -} - -.def-font(@name) { - @font-face { - font-family: @name - } -} - -.def-font(font-a); -.def-font(font-b); - -.æøå { - margin: 0; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/debug/import/test.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/debug/import/test.less deleted file mode 100644 index 795082f5..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/debug/import/test.less +++ /dev/null @@ -1,25 +0,0 @@ -@charset "ISO-8859-1"; - -.mixin_import1() { - @media all { - .tst { - color: black; - @media screen { - color: red; - .tst3 { - color: white; - } - } - } - } -} - -.mixin_import2() { - .tst2 { - color: white; - } -} - -.tst3 { - color: grey; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/debug/linenumbers.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/debug/linenumbers.less deleted file mode 100644 index 172ba028..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/debug/linenumbers.less +++ /dev/null @@ -1,23 +0,0 @@ -@charset "UTF-8"; - -@import "import/test.less"; - -.start() { - .test2 { - color: red; - } -} - -.mix() { - color: black; -} - -.test1 { - .mix(); -} - -.start(); - -.mixin_import1(); - -.mixin_import2(); \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units.less deleted file mode 100644 index 9b708de9..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - error: (1px + 3em); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units.txt deleted file mode 100644 index b5553618..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units.txt +++ /dev/null @@ -1,2 +0,0 @@ -SyntaxError: Incompatible units. Change the units or use the unit function. Bad units: 'px' and 'em'. in {path}add-mixed-units.less on line null, column 0: -1 error: (1px + 3em); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units2.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units2.less deleted file mode 100644 index 26631160..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units2.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - error: ((1px * 2px) + (3em * 3px)); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units2.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units2.txt deleted file mode 100644 index cc65a760..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/add-mixed-units2.txt +++ /dev/null @@ -1,2 +0,0 @@ -SyntaxError: Incompatible units. Change the units or use the unit function. Bad units: 'px*px' and 'em*px'. in {path}add-mixed-units2.less on line null, column 0: -1 error: ((1px * 2px) + (3em * 3px)); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/bad-variable-declaration1.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/bad-variable-declaration1.less deleted file mode 100644 index c2dc6ac0..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/bad-variable-declaration1.less +++ /dev/null @@ -1 +0,0 @@ -@@demo: "hi"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/bad-variable-declaration1.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/bad-variable-declaration1.txt deleted file mode 100644 index 5ae9d4a4..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/bad-variable-declaration1.txt +++ /dev/null @@ -1,2 +0,0 @@ -ParseError: Unrecognised input in {path}bad-variable-declaration1.less on line 1, column 1: -1 @@demo: "hi"; diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-func-invalid-color.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-func-invalid-color.less deleted file mode 100644 index 5a1edd01..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-func-invalid-color.less +++ /dev/null @@ -1,3 +0,0 @@ -.test { - color: color("NOT A COLOR"); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-func-invalid-color.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-func-invalid-color.txt deleted file mode 100644 index 08990c30..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-func-invalid-color.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `color`: argument must be a color keyword or 3/6 digit hex e.g. #FFF in {path}color-func-invalid-color.less on line 2, column 10: -1 .test { -2 color: color("NOT A COLOR"); -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-operation-error.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-operation-error.less deleted file mode 100644 index 7c60c004..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-operation-error.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - prop: (3 / #fff); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-operation-error.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-operation-error.txt deleted file mode 100644 index 1b3f889f..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/color-operation-error.txt +++ /dev/null @@ -1,2 +0,0 @@ -OperationError: Can't substract or divide a color from a number in {path}color-operation-error.less on line null, column 0: -1 prop: (3 / #fff); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/comment-in-selector.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/comment-in-selector.less deleted file mode 100644 index a7d26396..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/comment-in-selector.less +++ /dev/null @@ -1 +0,0 @@ -#gaga /* Comment */ span { color: red } \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/comment-in-selector.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/comment-in-selector.txt deleted file mode 100644 index e48f878c..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/comment-in-selector.txt +++ /dev/null @@ -1,2 +0,0 @@ -ParseError: Unrecognised input in {path}comment-in-selector.less on line 1, column 21: -1 #gaga /* Comment */ span { color: red } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/divide-mixed-units.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/divide-mixed-units.less deleted file mode 100644 index d228b7c4..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/divide-mixed-units.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - error: (1px / 3em); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/divide-mixed-units.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/divide-mixed-units.txt deleted file mode 100644 index c189d2aa..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/divide-mixed-units.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Multiple units in dimension. Correct the units or use the unit function. Bad unit: px/em in {path}divide-mixed-units.less on line 2, column 3: -1 .a { -2 error: (1px / 3em); -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-no-selector.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-no-selector.less deleted file mode 100644 index 84689ef3..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-no-selector.less +++ /dev/null @@ -1,3 +0,0 @@ -:extend(.a all) { - property: red; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-no-selector.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-no-selector.txt deleted file mode 100644 index bd2e3cd7..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-no-selector.txt +++ /dev/null @@ -1,3 +0,0 @@ -SyntaxError: Extend must be used to extend a selector, it cannot be used on its own in {path}extend-no-selector.less on line 1, column 17: -1 :extend(.a all) { -2 property: red; diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-not-at-end.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-not-at-end.less deleted file mode 100644 index 90ee512c..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-not-at-end.less +++ /dev/null @@ -1,3 +0,0 @@ -.a:extend(.b all).c { - property: red; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-not-at-end.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-not-at-end.txt deleted file mode 100644 index 32ebedfc..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/extend-not-at-end.txt +++ /dev/null @@ -1,3 +0,0 @@ -SyntaxError: Extend can only be used at the end of selector in {path}extend-not-at-end.less on line 1, column 21: -1 .a:extend(.b all).c { -2 property: red; diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-missing.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-missing.less deleted file mode 100644 index 5ce8e4d9..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-missing.less +++ /dev/null @@ -1,6 +0,0 @@ -.a { - color: green; - // tests line number for import reference is correct -} - -@import "file-does-not-exist.less"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-missing.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-missing.txt deleted file mode 100644 index 488d154a..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-missing.txt +++ /dev/null @@ -1,3 +0,0 @@ -FileError: '{pathhref}file-does-not-exist.less' wasn't found{404status} in {path}import-missing.less on line 6, column 1: -5 -6 @import "file-does-not-exist.less"; diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-no-semi.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-no-semi.less deleted file mode 100644 index bf2c7f65..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-no-semi.less +++ /dev/null @@ -1 +0,0 @@ -@import "this-statement-is-invalid.less" \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-no-semi.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-no-semi.txt deleted file mode 100644 index 8b3f795c..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-no-semi.txt +++ /dev/null @@ -1,2 +0,0 @@ -ParseError: Unrecognised input in {path}import-no-semi.less on line 1, column 1: -1 @import "this-statement-is-invalid.less" diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder1.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder1.less deleted file mode 100644 index 4280673b..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder1.less +++ /dev/null @@ -1 +0,0 @@ -@import "imports/import-subfolder1.less"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder1.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder1.txt deleted file mode 100644 index 97629276..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder1.txt +++ /dev/null @@ -1,3 +0,0 @@ -NameError: .mixin-not-defined is undefined in {path}mixin-not-defined.less on line 11, column 1: -10 -11 .mixin-not-defined(); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder2.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder2.less deleted file mode 100644 index a6b9b9ce..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder2.less +++ /dev/null @@ -1 +0,0 @@ -@import "imports/import-subfolder2.less"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder2.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder2.txt deleted file mode 100644 index 7d514efc..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/import-subfolder2.txt +++ /dev/null @@ -1,2 +0,0 @@ -ParseError: missing opening `{` in {path}parse-error-curly-bracket.less on line 1, column 2: -1 }} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/import-subfolder1.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/import-subfolder1.less deleted file mode 100644 index 24ec0532..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/import-subfolder1.less +++ /dev/null @@ -1 +0,0 @@ -@import "subfolder/mixin-not-defined.less"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/import-subfolder2.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/import-subfolder2.less deleted file mode 100644 index 6058ad14..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/import-subfolder2.less +++ /dev/null @@ -1 +0,0 @@ -@import "subfolder/parse-error-curly-bracket.less"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/import-test.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/import-test.less deleted file mode 100644 index a91ae054..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/import-test.less +++ /dev/null @@ -1,4 +0,0 @@ -.someclass -{ - font-weight: bold; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/subfolder/mixin-not-defined.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/subfolder/mixin-not-defined.less deleted file mode 100644 index 2bb2d091..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/subfolder/mixin-not-defined.less +++ /dev/null @@ -1 +0,0 @@ -@import "../../mixin-not-defined.less"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/subfolder/parse-error-curly-bracket.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/subfolder/parse-error-curly-bracket.less deleted file mode 100644 index f37fa9d0..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/imports/subfolder/parse-error-curly-bracket.less +++ /dev/null @@ -1 +0,0 @@ -@import "../../parse-error-curly-bracket.less"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/javascript-error.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/javascript-error.less deleted file mode 100644 index 9cffb9ff..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/javascript-error.less +++ /dev/null @@ -1,3 +0,0 @@ -.scope { - var: `this.foo.toJS()`; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/javascript-error.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/javascript-error.txt deleted file mode 100644 index 3c83a966..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/javascript-error.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: JavaScript evaluation error: 'TypeError: Cannot call method 'toJS' of undefined' in {path}javascript-error.less on line 2, column 27: -1 .scope { -2 var: `this.foo.toJS()`; -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-1.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-1.less deleted file mode 100644 index 9b0e23af..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-1.less +++ /dev/null @@ -1,6 +0,0 @@ -.mixin(@a : 4, @b : 3, @c: 2) { - will: fail; -} -.mixin-test { - .mixin(@a: 5; @b: 6, @c: 7); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-1.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-1.txt deleted file mode 100644 index a07f5e9d..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-1.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Cannot mix ; and , as delimiter types in {path}mixed-mixin-definition-args-1.less on line 5, column 30: -4 .mixin-test { -5 .mixin(@a: 5; @b: 6, @c: 7); -6 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-2.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-2.less deleted file mode 100644 index c9709427..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-2.less +++ /dev/null @@ -1,6 +0,0 @@ -.mixin(@a : 4, @b : 3, @c: 2) { - will: fail; -} -.mixin-test { - .mixin(@a: 5, @b: 6; @c: 7); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-2.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-2.txt deleted file mode 100644 index fa00183b..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixed-mixin-definition-args-2.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Cannot mix ; and , as delimiter types in {path}mixed-mixin-definition-args-2.less on line 5, column 26: -4 .mixin-test { -5 .mixin(@a: 5, @b: 6; @c: 7); -6 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-defined.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-defined.less deleted file mode 100644 index e2dad5ce..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-defined.less +++ /dev/null @@ -1,11 +0,0 @@ - -.error-is-further-on() { -} - -.pad-here-to-reproduce-error-in() { -} - -.the-import-subfolder-test() { -} - -.mixin-not-defined(); \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-defined.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-defined.txt deleted file mode 100644 index 97629276..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-defined.txt +++ /dev/null @@ -1,3 +0,0 @@ -NameError: .mixin-not-defined is undefined in {path}mixin-not-defined.less on line 11, column 1: -10 -11 .mixin-not-defined(); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched.less deleted file mode 100644 index be0d6b1a..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched.less +++ /dev/null @@ -1,6 +0,0 @@ -@saxofon:trumpete; - -.mixin(saxofon) { -} - -.mixin(@saxofon); \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched.txt deleted file mode 100644 index 57df9772..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched.txt +++ /dev/null @@ -1,3 +0,0 @@ -RuntimeError: No matching definition was found for `.mixin(trumpete)` in {path}mixin-not-matched.less on line 6, column 1: -5 -6 .mixin(@saxofon); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched2.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched2.less deleted file mode 100644 index 14f44bf3..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched2.less +++ /dev/null @@ -1,6 +0,0 @@ -@saxofon:trumpete; - -.mixin(@a, @b) { -} - -.mixin(@a: @saxofon); \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched2.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched2.txt deleted file mode 100644 index dceedaf0..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/mixin-not-matched2.txt +++ /dev/null @@ -1,3 +0,0 @@ -RuntimeError: No matching definition was found for `.mixin(@a:trumpete)` in {path}mixin-not-matched2.less on line 6, column 1: -5 -6 .mixin(@a: @saxofon); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiple-guards-on-css-selectors.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiple-guards-on-css-selectors.less deleted file mode 100644 index 4eabb60a..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiple-guards-on-css-selectors.less +++ /dev/null @@ -1,4 +0,0 @@ -@ie8: true; -.a when (@ie8 = true), -.b { -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiple-guards-on-css-selectors.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiple-guards-on-css-selectors.txt deleted file mode 100644 index 3d23e26b..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiple-guards-on-css-selectors.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Guards are only currently allowed on a single selector. in {path}multiple-guards-on-css-selectors.less on line 3, column 1: -2 .a when (@ie8 = true), -3 .b { -4 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiply-mixed-units.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiply-mixed-units.less deleted file mode 100644 index ff983a85..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiply-mixed-units.less +++ /dev/null @@ -1,7 +0,0 @@ -/* Test */ -#blah { - // blah -} -.a { - error: (1px * 1em); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiply-mixed-units.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiply-mixed-units.txt deleted file mode 100644 index 9ed834f1..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/multiply-mixed-units.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: Multiple units in dimension. Correct the units or use the unit function. Bad unit: em*px in {path}multiply-mixed-units.less on line 6, column 3: -5 .a { -6 error: (1px * 1em); -7 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-1.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-1.less deleted file mode 100644 index 7c8ec10e..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-1.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - something: (12 (13 + 5 -23) + 5); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-1.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-1.txt deleted file mode 100644 index 6fc40ac0..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-1.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: expected ')' got '(' in {path}parens-error-1.less on line 2, column 18: -1 .a { -2 something: (12 (13 + 5 -23) + 5); -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-2.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-2.less deleted file mode 100644 index 4a392b8e..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-2.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - something: (12 * (13 + 5 -23)); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-2.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-2.txt deleted file mode 100644 index cee5c52d..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-2.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: expected ')' got '-' in {path}parens-error-2.less on line 2, column 28: -1 .a { -2 something: (12 * (13 + 5 -23)); -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-3.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-3.less deleted file mode 100644 index 9e6d5405..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-3.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - something: (12 + (13 + 10 -23)); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-3.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-3.txt deleted file mode 100644 index 3280ef04..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parens-error-3.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: expected ')' got '-' in {path}parens-error-3.less on line 2, column 29: -1 .a { -2 something: (12 + (13 + 10 -23)); -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-curly-bracket.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-curly-bracket.less deleted file mode 100644 index a2950a11..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-curly-bracket.less +++ /dev/null @@ -1 +0,0 @@ -}} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-curly-bracket.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-curly-bracket.txt deleted file mode 100644 index 7d514efc..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-curly-bracket.txt +++ /dev/null @@ -1,2 +0,0 @@ -ParseError: missing opening `{` in {path}parse-error-curly-bracket.less on line 1, column 2: -1 }} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-missing-bracket.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-missing-bracket.less deleted file mode 100644 index 144a6edf..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-missing-bracket.less +++ /dev/null @@ -1,2 +0,0 @@ -body { - background-color: #fff; diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-missing-bracket.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-missing-bracket.txt deleted file mode 100644 index 0005f464..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-missing-bracket.txt +++ /dev/null @@ -1,3 +0,0 @@ -ParseError: missing closing `}` in {path}parse-error-missing-bracket.less on line 3, column 1: -2 background-color: #fff; -3 diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-with-import.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-with-import.less deleted file mode 100644 index 6be3de85..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-with-import.less +++ /dev/null @@ -1,13 +0,0 @@ -@import 'import/import-test.less'; - -body -{ - font-family: arial, sans-serif; -} - -nonsense; - -.clickable -{ - cursor: pointer; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-with-import.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-with-import.txt deleted file mode 100644 index 07732c92..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/parse-error-with-import.txt +++ /dev/null @@ -1,4 +0,0 @@ -ParseError: Unrecognised input in {path}parse-error-with-import.less on line 8, column 9: -7 -8 nonsense; -9 diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-ie5-hack.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-ie5-hack.less deleted file mode 100644 index 51bf6e39..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-ie5-hack.less +++ /dev/null @@ -1,3 +0,0 @@ -.test { - display/*/: block; /*sorry for IE5*/ -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-ie5-hack.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-ie5-hack.txt deleted file mode 100644 index e42ef90e..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-ie5-hack.txt +++ /dev/null @@ -1,4 +0,0 @@ -ParseError: Unrecognised input in {path}property-ie5-hack.less on line 2, column 3: -1 .test { -2 display/*/: block; /*sorry for IE5*/ -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root.less deleted file mode 100644 index 8fed4be3..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root.less +++ /dev/null @@ -1,4 +0,0 @@ -.a() { - prop:1; -} -.a(); \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root.txt deleted file mode 100644 index 04b27766..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: properties must be inside selector blocks, they cannot be in the root. in {path}property-in-root.less on line 2, column 3: -1 .a() { -2 prop:1; -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root2.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root2.less deleted file mode 100644 index ce8656d1..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root2.less +++ /dev/null @@ -1 +0,0 @@ -@import "property-in-root"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root2.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root2.txt deleted file mode 100644 index 04b27766..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root2.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: properties must be inside selector blocks, they cannot be in the root. in {path}property-in-root.less on line 2, column 3: -1 .a() { -2 prop:1; -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root3.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root3.less deleted file mode 100644 index 056c2f72..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root3.less +++ /dev/null @@ -1,4 +0,0 @@ -prop:1; -.a { - prop:1; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root3.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root3.txt deleted file mode 100644 index 68ef9454..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/property-in-root3.txt +++ /dev/null @@ -1,3 +0,0 @@ -SyntaxError: properties must be inside selector blocks, they cannot be in the root. in {path}property-in-root3.less on line 1, column 1: -1 prop:1; -2 .a { diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/recursive-variable.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/recursive-variable.less deleted file mode 100644 index c1ca75f1..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/recursive-variable.less +++ /dev/null @@ -1 +0,0 @@ -@bodyColor: darken(@bodyColor, 30%); \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/recursive-variable.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/recursive-variable.txt deleted file mode 100644 index eb616e7d..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/recursive-variable.txt +++ /dev/null @@ -1,2 +0,0 @@ -NameError: Recursive variable definition for @bodyColor in {path}recursive-variable.less on line 1, column 20: -1 @bodyColor: darken(@bodyColor, 30%); diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient1.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient1.less deleted file mode 100644 index c069ff72..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient1.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - a: svg-gradient(horizontal, black, white); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient1.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient1.txt deleted file mode 100644 index ec662fe6..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient1.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `svg-gradient`: svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center' in {path}svg-gradient1.less on line 2, column 6: -1 .a { -2 a: svg-gradient(horizontal, black, white); -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient2.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient2.less deleted file mode 100644 index ff14ef11..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient2.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - a: svg-gradient(to bottom, black, orange, 45%, white); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient2.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient2.txt deleted file mode 100644 index 7004115f..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient2.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `svg-gradient`: svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position] in {path}svg-gradient2.less on line 2, column 6: -1 .a { -2 a: svg-gradient(to bottom, black, orange, 45%, white); -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient3.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient3.less deleted file mode 100644 index 8f185246..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient3.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - a: svg-gradient(black, orange); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient3.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient3.txt deleted file mode 100644 index eb0b483e..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/svg-gradient3.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `svg-gradient`: svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position] in {path}svg-gradient3.less on line 2, column 6: -1 .a { -2 a: svg-gradient(black, orange); -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/unit-function.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/unit-function.less deleted file mode 100644 index 119e9818..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/unit-function.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - font-size: unit(80/16,rem); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/unit-function.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/unit-function.txt deleted file mode 100644 index baf90f42..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/errors/unit-function.txt +++ /dev/null @@ -1,4 +0,0 @@ -ArgumentError: error evaluating function `unit`: the first argument to unit must be a number. Have you forgotten parenthesis? in {path}unit-function.less on line 2, column 14: -1 .a { -2 font-size: unit(80/16,rem); -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-chaining.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-chaining.less deleted file mode 100644 index aad221ea..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-chaining.less +++ /dev/null @@ -1,91 +0,0 @@ -//very simple chaining -.a { - color: black; -} -.b:extend(.a) {} -.c:extend(.b) {} - -//very simple chaining, ordering not important - -.d:extend(.e) {} -.e:extend(.f) {} -.f { - color: black; -} - -//extend with all - -.g.h { - color: black; -} -.i.j:extend(.g all) { - color: white; -} -.k:extend(.i all) {} - -//extend multi-chaining - -.l { - color: black; -} -.m:extend(.l){} -.n:extend(.m){} -.o:extend(.n){} -.p:extend(.o){} -.q:extend(.p){} -.r:extend(.q){} -.s:extend(.r){} -.t:extend(.s){} - -// self referencing is ignored - -.u {color: black;} -.v.u.v:extend(.u all){} - -// circular reference because the new extend product will match the existing extend - -.w:extend(.w) {color: black;} -.v.w.v:extend(.w all){} - -// classic circular references - -.x:extend(.z) { - color: x; -} -.y:extend(.x) { - color: y; -} -.z:extend(.y) { - color: z; -} - -//very simple chaining, but with the extend inside the ruleset -.va { - color: black; -} -.vb { - &:extend(.va); - color: white; -} -.vc { - &:extend(.vb); -} - -// media queries - dont extend outside, do extend inside - -@media tv { - .ma:extend(.a,.b,.c,.d,.e,.f,.g,.h,.i,.j,.k,.l,.m,.n,.o,.p,.q,.r,.s,.t,.u,.v,.w,.x,.y,.z,.md) { - color: black; - } - .md { - color: white; - } - @media plasma { - .me, .mf { - &:extend(.mb,.md); - background: red; - } - } -} -.mb:extend(.ma) {}; -.mc:extend(.mb) {}; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-clearfix.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-clearfix.less deleted file mode 100644 index 82445dfa..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-clearfix.less +++ /dev/null @@ -1,19 +0,0 @@ -.clearfix { - *zoom: 1; - &:after { - content: ''; - display: block; - clear: both; - height: 0; - } -} - -.foo { - &:extend(.clearfix all); - color: red; -} - -.bar { - &:extend(.clearfix all); - color: blue; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-exact.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-exact.less deleted file mode 100644 index 41dc4130..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-exact.less +++ /dev/null @@ -1,46 +0,0 @@ -.replace.replace, -.c.replace + .replace { - .replace, - .c { - prop: copy-paste-replace; - } -} -.rep_ace:extend(.replace.replace .replace) {} - -.a .b .c { - prop: not_effected; -} - -.a { - prop: is_effected; - .b { - prop: not_effected; - } - .b.c { - prop: not_effected; - } -} - -.c, .a { - .b, .a { - .a, .c { - prop: not_effected; - } - } -} - -.effected { - &:extend(.a); - &:extend(.b); - &:extend(.c); -} - -.e { - && { - prop: extend-double; - &:hover { - hover: not-extended; - } - } -} -.dbl:extend(.e.e) {} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-media.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-media.less deleted file mode 100644 index 1b22c3fa..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-media.less +++ /dev/null @@ -1,24 +0,0 @@ -.ext1 .ext2 { - background: black; -} - -@media tv { - .ext1 .ext3 { - color: white; - } - .tv-lowres :extend(.ext1 all) { - background: blue; - } - @media hires { - .ext1 .ext4 { - color: green; - } - .tv-hires :extend(.ext1 all) { - background: red; - } - } -} - -.all:extend(.ext1 all) { - -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-nest.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-nest.less deleted file mode 100644 index 9d4d27bb..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-nest.less +++ /dev/null @@ -1,65 +0,0 @@ -.sidebar { - width: 300px; - background: red; - - .box { - background: #FFF; - border: 1px solid #000; - margin: 10px 0; - } -} - -.sidebar2 { - &:extend(.sidebar all); - background: blue; -} - -.type1 { - .sidebar3 { - &:extend(.sidebar all); - background: green; - } -} - -.type2 { - &.sidebar4 { - &:extend(.sidebar all); - background: red; - } -} - -.button { - color: black; - &:hover { - color: white; - } -} -.submit { - &:extend(.button); - &:hover:extend(.button:hover) {} -} - -.nomatch { - &:hover:extend(.button :hover) {} -} - -.button2 { - :hover { - nested: white; - } -} -.button2 :hover { - notnested: black; -} - -.nomatch :extend(.button2:hover) {} - -.amp-test-a, -.amp-test-b { - .amp-test-c &.amp-test-d&.amp-test-e { - .amp-test-f&+&.amp-test-g:extend(.amp-test-h) {} - } -} -.amp-test-h { - test: extended by masses of selectors; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-selector.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-selector.less deleted file mode 100644 index c7588ee0..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend-selector.less +++ /dev/null @@ -1,99 +0,0 @@ -.error { - border: 1px #f00; - background: #fdd; -} -.error.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error { - display: none; -} -.badError:extend(.error all) { - border-width: 3px; -} - -.foo .bar, .foo .baz { - display: none; -} - -.ext1 .ext2 - :extend(.foo all) { -} - -.ext3:extend(.foo all), -.ext4:extend(.foo all) { -} - -div.ext5, -.ext6 > .ext5 { - width: 100px; -} - -.should-not-exist-in-output, -.ext7:extend(.ext5 all) { -} - -.ext { - test: 1; -} -// same as -// .a .c:extend(.ext all) -// .b .c:extend(.ext all) -// .a .c .d -// .b .c .d -.a, .b { - test: 2; - .c:extend(.ext all) { - test: 3; - .d { - test: 4; - } - } -} - -.replace.replace, -.c.replace + .replace { - .replace, - .c { - prop: copy-paste-replace; - } -} -.rep_ace:extend(.replace all) {} - -.attributes { - [data="test"] { - extend: attributes; - } - .attribute-test { - &:extend([data="test"] all); - } - [data] { - extend: attributes2; - } - .attribute-test2 { - &:extend([data] all); //you could argue it should match [data="test"]... not for now though... - } - @attr-data: "test3"; - [data=@{attr-data}] { - extend: attributes2; - } - .attribute-test { - &:extend([data="test3"] all); - } -} - -.header { - .header-nav { - background: red; - &:before { - background: blue; - } - } -} - -.footer { - .footer-nav { - &:extend( .header .header-nav all ); - } -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend.less deleted file mode 100644 index 1db5d431..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extend.less +++ /dev/null @@ -1,81 +0,0 @@ -.error { - border: 1px #f00; - background: #fdd; -} -.error.intrusion { - font-size: 1.3em; - font-weight: bold; -} -.intrusion .error { - display: none; -} -.badError { - &:extend(.error all); - border-width: 3px; -} - -.foo .bar, .foo .baz { - display: none; -} - -.ext1 .ext2 { - &:extend(.foo all); -} - -.ext3, -.ext4 { - &:extend(.foo all); - &:extend(.bar all); -} - -div.ext5, -.ext6 > .ext5 { - width: 100px; -} - -.ext7 { - &:extend(.ext5 all); -} - -.ext8.ext9 { - result: add-foo; -} -.ext8 .ext9, -.ext8 + .ext9, -.ext8 > .ext9 { - result: bar-matched; -} -.ext8.nomatch { - result: none; -} -.ext8 { - .ext9 { - result: match-nested-bar; - } -} -.ext8 { - &.ext9 { - result: match-nested-foo; - } -} - -.fuu:extend(.ext8.ext9 all) {} -.buu:extend(.ext8 .ext9 all) {} -.zap:extend(.ext8 + .ext9 all) {} -.zoo:extend(.ext8 > .ext9 all) {} - -.aa { - color: black; - .dd { - background: red; - } -} -.bb { - background: red; - .bb { - color: black; - } -} -.cc:extend(.aa,.bb) {} -.ee:extend(.dd all,.bb) {} -.ff:extend(.dd,.bb all) {} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extract-and-length.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extract-and-length.less deleted file mode 100644 index d81e118f..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/extract-and-length.less +++ /dev/null @@ -1,133 +0,0 @@ - -// simple array/list: - -.multiunit { - @v: abc "abc" 1 1px 1% #123; - length: length(@v); - extract: extract(@v, 1) extract(@v, 2) extract(@v, 3) extract(@v, 4) extract(@v, 5) extract(@v, 6); -} - -.incorrect-index { - @v1: a b c; - @v2: a, b, c; - v1: extract(@v1, 5); - v2: extract(@v2, -2); -} - -.scalar { - @var: variable; - var-value: extract(@var, 1); - var-length: length(@var); - ill-index: extract(@var, 2); - - name-value: extract(name, 1); - string-value: extract("string", 1); - number-value: extract(12345678, 1); - color-value: extract(blue, 1); - rgba-value: extract(rgba(80, 160, 240, 0.67), 1); - empty-value: extract(~'', 1); - - name-length: length(name); - string-length: length("string"); - number-length: length(12345678); - color-length: length(blue); - rgba-length: length(rgba(80, 160, 240, 0.67)); - empty-length: length(~''); -} - -.mixin-arguments { - .mixin-args(a b c d); - .mixin-args(a, b, c, d); - .mixin-args(1; 2; 3; 4); -} - -.mixin-args(@value) { - &-1 { - length: length(@value); - extract: extract(@value, 3) ~"|" extract(@value, 2) ~"|" extract(@value, 1); - } -} - -.mixin-args(...) { - &-2 { - length: length(@arguments); - extract: extract(@arguments, 3) ~"|" extract(@arguments, 2) ~"|" extract(@arguments, 1); - } -} - -.mixin-args(@values...) { - &-3 { - length: length(@values); - extract: extract(@values, 3) ~"|" extract(@values, 2) ~"|" extract(@values, 1); - } -} - -.mixin-args(@head, @tail...) { - &-4 { - length: length(@tail); - extract: extract(@tail, 2) ~"|" extract(@tail, 1); - } -} - -// "multidimensional" array/list - -.md-space-comma { - @v: a b c, 1 2 3, "x" "y" "z"; - length-1: length(@v); - extract-1: extract(@v, 2); - length-2: length(extract(@v, 2)); - extract-2: extract(extract(@v, 2), 2); - - &-as-args {.mixin-args(a b c, 1 2 3, "x" "y" "z")} -} - -.md-cat-space-comma { - @a: a b c; - @b: 1 2 3; - @c: "x" "y" "z"; - @v: @a, @b, @c; - length-1: length(@v); - extract-1: extract(@v, 2); - length-2: length(extract(@v, 2)); - extract-2: extract(extract(@v, 2), 2); - - &-as-args {.mixin-args(@a, @b, @c)} -} - -.md-cat-comma-space { - @a: a, b, c; - @b: 1, 2, 3; - @c: "x", "y", "z"; - @v: @a @b @c; - length-1: length(@v); - extract-1: extract(@v, 2); - length-2: length(extract(@v, 2)); - extract-2: extract(extract(@v, 2), 2); - - &-as-args {.mixin-args(@a @b @c)} -} - -.md-3D { - @a: a b c d, 1 2 3 4; - @b: 5 6 7 8, e f g h; - .3D(@a, @b); - - .3D(...) { - - @v1: @arguments; - length-1: length(@v1); - extract-1: extract(@v1, 1); - - @v2: extract(@v1, 2); - length-2: length(@v2); - extract-2: extract(@v2, 1); - - @v3: extract(@v2, 1); - length-3: length(@v3); - extract-3: extract(@v3, 3); - - @v4: extract(@v3, 4); - length-4: length(@v4); - extract-4: extract(@v4, 1); - } -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/functions.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/functions.less deleted file mode 100644 index b50a0da5..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/functions.less +++ /dev/null @@ -1,153 +0,0 @@ -#functions { - @var: 10; - @colors: #000, #fff; - color: _color("evil red"); // #660000 - width: increment(15); - height: undefined("self"); - border-width: add(2, 3); - variable: increment(@var); - background: linear-gradient(@colors); -} - -#built-in { - @r: 32; - escaped: e("-Some::weird(#thing, y)"); - lighten: lighten(#ff0000, 40%); - darken: darken(#ff0000, 40%); - saturate: saturate(#29332f, 20%); - desaturate: desaturate(#203c31, 20%); - greyscale: greyscale(#203c31); - hsl-clamp: hsl(380, 150%, 150%); - spin-p: spin(hsl(340, 50%, 50%), 40); - spin-n: spin(hsl(30, 50%, 50%), -40); - luma-white: luma(#fff); - luma-black: luma(#000); - luma-black-alpha: luma(rgba(0,0,0,0.5)); - luma-red: luma(#ff0000); - luma-green: luma(#00ff00); - luma-blue: luma(#0000ff); - luma-yellow: luma(#ffff00); - luma-cyan: luma(#00ffff); - luma-white-alpha: luma(rgba(255,255,255,0.5)); - contrast-filter: contrast(30%); - saturate-filter: saturate(5%); - contrast-white: contrast(#fff); - contrast-black: contrast(#000); - contrast-red: contrast(#ff0000); - contrast-green: contrast(#00ff00); - contrast-blue: contrast(#0000ff); - contrast-yellow: contrast(#ffff00); - contrast-cyan: contrast(#00ffff); - contrast-light: contrast(#fff, #111111, #eeeeee); - contrast-dark: contrast(#000, #111111, #eeeeee); - contrast-wrongorder: contrast(#fff, #eeeeee, #111111, 0.5); - contrast-light-thresh: contrast(#fff, #111111, #eeeeee, 0.5); - contrast-dark-thresh: contrast(#000, #111111, #eeeeee, 0.5); - contrast-high-thresh: contrast(#555, #111111, #eeeeee, 0.6); - contrast-low-thresh: contrast(#555, #111111, #eeeeee, 0.1); - contrast-light-thresh-per: contrast(#fff, #111111, #eeeeee, 50%); - contrast-dark-thresh-per: contrast(#000, #111111, #eeeeee, 50%); - contrast-high-thresh-per: contrast(#555, #111111, #eeeeee, 60%); - contrast-low-thresh-per: contrast(#555, #111111, #eeeeee, 10%); - format: %("rgb(%d, %d, %d)", @r, 128, 64); - format-string: %("hello %s", "world"); - format-multiple: %("hello %s %d", "earth", 2); - format-url-encode: %('red is %A', #ff0000); - eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64)); - - unitless: unit(12px); - unit: unit((13px + 1px), em); - - hue: hue(hsl(98, 12%, 95%)); - saturation: saturation(hsl(98, 12%, 95%)); - lightness: lightness(hsl(98, 12%, 95%)); - hsvhue: hsvhue(hsv(98, 12%, 95%)); - hsvsaturation: hsvsaturation(hsv(98, 12%, 95%)); - hsvvalue: hsvvalue(hsv(98, 12%, 95%)); - red: red(#f00); - green: green(#0f0); - blue: blue(#00f); - rounded: round((@r/3)); - rounded-two: round((@r/3), 2); - roundedpx: round((10px / 3)); - roundedpx-three: round((10px / 3), 3); - rounded-percentage: round(10.2%); - ceil: ceil(10.1px); - floor: floor(12.9px); - sqrt: sqrt(25px); - pi: pi(); - mod: mod(13m, 11cm); // could take into account units, doesn't at the moment - abs: abs(-4%); - tan: tan(42deg); - sin: sin(10deg); - cos: cos(12); - atan: atan(tan(0.1rad)); - atan: convert(acos(cos(34deg)), deg); - atan: convert(acos(cos(50grad)), deg); - pow: pow(8px, 2); - pow: pow(4, 3); - pow: pow(3, 3em); - min: min(0); - min: min("junk", 6, 5); - min: min(1pc, 3pt); - max: max(1, 3); - max: max(3%, 1cm, 8%, 2mm); - percentage: percentage((10px / 50)); - color: color("#ff0011"); - tint: tint(#777777, 13); - tint-full: tint(#777777, 100); - tint-percent: tint(#777777, 13%); - shade: shade(#777777, 13); - shade-full: shade(#777777, 100); - shade-percent: shade(#777777, 13%); - - fade-out: fadeOut(red, 5%); // support fadeOut and fadeout - fade-in: fadein(fadeout(red, 10%), 5%); - - hsv: hsv(5, 50%, 30%); - hsva: hsva(3, 50%, 30%, 0.2); - - mix: mix(#ff0000, #ffff00, 80); - mix-0: mix(#ff0000, #ffff00, 0); - mix-100: mix(#ff0000, #ffff00, 100); - mix-weightless: mix(#ff0000, #ffff00); - mixt: mix(#ff0000, transparent); - - .is-a { - color: iscolor(#ddd); - color1: iscolor(red); - color2: iscolor(rgb(0, 0, 0)); - color3: iscolor(transparent); - keyword: iskeyword(hello); - number: isnumber(32); - string: isstring("hello"); - pixel: ispixel(32px); - percent: ispercentage(32%); - em: isem(32em); - cat: isunit(32cat, cat); - } -} - -#alpha { - alpha: darken(hsla(25, 50%, 50%, 0.6), 10%); - alpha2: alpha(rgba(3, 4, 5, 0.5)); - alpha3: alpha(transparent); -} - -#blendmodes { - multiply: multiply(#f60000, #f60000); - screen: screen(#f60000, #0000f6); - overlay: overlay(#f60000, #0000f6); - softlight: softlight(#f60000, #ffffff); - hardlight: hardlight(#f60000, #0000f6); - difference: difference(#f60000, #0000f6); - exclusion: exclusion(#f60000, #0000f6); - average: average(#f60000, #0000f6); - negation: negation(#f60000, #313131); -} - -#extract-and-length { - @anon: A B C 1 2 3; - extract: extract(@anon, 6) extract(@anon, 5) extract(@anon, 4) extract(@anon, 3) extract(@anon, 2) extract(@anon, 1); - length: length(@anon); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/ie-filters.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/ie-filters.less deleted file mode 100644 index 3350b653..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/ie-filters.less +++ /dev/null @@ -1,15 +0,0 @@ -@fat: 0; -@cloudhead: "#000000"; - -.nav { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity = 20); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@fat); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr=@cloudhead, GradientType=@fat); -} -.evalTest(@arg) { - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@arg); -} -.evalTest1 { - .evalTest(30); - .evalTest(5); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-inline.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-inline.less deleted file mode 100644 index 95a11896..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-inline.less +++ /dev/null @@ -1,2 +0,0 @@ -@import (inline) url("import/import-test-d.css") (min-width:600px); -@import (inline, css) url("import/invalid-css.less"); \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-interpolation.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-interpolation.less deleted file mode 100644 index 21cfe086..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-interpolation.less +++ /dev/null @@ -1,8 +0,0 @@ -@my_theme: "test"; - -@import "import/import-@{my_theme}-e.less"; - -@import "import/import-@{in}@{terpolation}.less"; - -@in: "in"; -@terpolation: "terpolation"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-once.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-once.less deleted file mode 100644 index 0a4024a3..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-once.less +++ /dev/null @@ -1,6 +0,0 @@ -@import "import/import-once-test-c"; -@import "import/import-once-test-c"; -@import "import/import-once-test-c.less"; -@import "import/deeper/import-once-test-a"; -@import (multiple) "import/import-test-f.less"; -@import (multiple) "import/import-test-f.less"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-reference.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-reference.less deleted file mode 100644 index cf9da168..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import-reference.less +++ /dev/null @@ -1,18 +0,0 @@ -@import (reference) url("import-once.less"); -@import (reference) url("css-3.less"); -@import (reference) url("media.less"); -/* - The media statement above is invalid (no selector) - We should ban invalid media queries with properties and no selector? -*/ -@import (reference) url("import/import-reference.less"); - -.b { - .z(); -} - -.zz(); - -.visible:extend(.z all) { - extend: test; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import.less deleted file mode 100644 index 01689408..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import.less +++ /dev/null @@ -1,21 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Open+Sans); - -@import url(/absolute/something.css) screen and (color) and (max-width: 600px); - -@var: 100px; -@import url("//ha.com/file.css") (min-width:@var); - -#import-test { - .mixin; - width: 10px; - height: (@a + 10%); -} -@import "import/import-test-e" screen and (max-width: 600px); - -@import url("import/import-test-a.less"); - -@import (less, multiple) "import/import-test-d.css" screen and (max-width: 601px); - -@import (multiple) "import/import-test-e" screen and (max-width: 602px); - -@import (less, multiple) url("import/import-test-d.css") screen and (max-width: 603px); \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/deeper/import-once-test-a.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/deeper/import-once-test-a.less deleted file mode 100644 index 8a747fc0..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/deeper/import-once-test-a.less +++ /dev/null @@ -1 +0,0 @@ -@import "../import-once-test-c"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-and-relative-paths-test.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-and-relative-paths-test.less deleted file mode 100644 index da699989..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-and-relative-paths-test.less +++ /dev/null @@ -1,6 +0,0 @@ -@import "../css/background.css"; -@import "import-test-d.css"; - -@import "imports/logo"; -@import "imports/font"; - diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-charset-test.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-charset-test.less deleted file mode 100644 index 07a66e1a..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-charset-test.less +++ /dev/null @@ -1 +0,0 @@ -@charset "ISO-8859-1"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-interpolation.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-interpolation.less deleted file mode 100644 index aa49a702..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-interpolation.less +++ /dev/null @@ -1 +0,0 @@ -@import "import-@{in}@{terpolation}2.less"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-interpolation2.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-interpolation2.less deleted file mode 100644 index 12bfb4e1..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-interpolation2.less +++ /dev/null @@ -1,5 +0,0 @@ -.a { - var: test; -} - -@in: "redefined-does-nothing"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-once-test-c.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-once-test-c.less deleted file mode 100644 index 686747a8..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-once-test-c.less +++ /dev/null @@ -1,6 +0,0 @@ - -@c: red; - -#import { - color: @c; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-reference.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-reference.less deleted file mode 100644 index 9eac45fc..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-reference.less +++ /dev/null @@ -1,43 +0,0 @@ -.z { - color: red; - .c { - color: green; - } -} -.only-with-visible, -.z { - color: green; - &:hover { - color: green; - } - & { - color: green; - } - & + & { - color: green; - .sub { - color: green; - } - } -} - -& { - .hidden { - hidden: true; - } -} - -@media tv { - .hidden { - hidden: true; - } -} - -/* comment is not output */ - -.zz { - .y { - pulled-in: yes; - } - /* comment pulled in */ -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-a.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-a.less deleted file mode 100644 index b3b3b8fc..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-a.less +++ /dev/null @@ -1,3 +0,0 @@ -@import "import-test-b.less"; -@a: 20%; -@import "urls.less"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-b.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-b.less deleted file mode 100644 index ce2d35a8..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-b.less +++ /dev/null @@ -1,8 +0,0 @@ -@import "import-test-c"; - -@b: 100%; - -.mixin { - height: 10px; - color: @c; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-c.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-c.less deleted file mode 100644 index 686747a8..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-c.less +++ /dev/null @@ -1,6 +0,0 @@ - -@c: red; - -#import { - color: @c; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-d.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-d.css deleted file mode 100644 index 30575f01..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-d.css +++ /dev/null @@ -1 +0,0 @@ -#css { color: yellow; } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-e.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-e.less deleted file mode 100644 index 98b84b0a..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-e.less +++ /dev/null @@ -1,2 +0,0 @@ - -body { width: 100% } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-f.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-f.less deleted file mode 100644 index fad630f9..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/import-test-f.less +++ /dev/null @@ -1,5 +0,0 @@ -@import "import-test-e"; - -.test-f { - height: 10px; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/imports/font.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/imports/font.less deleted file mode 100644 index 5abb7e76..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/imports/font.less +++ /dev/null @@ -1,8 +0,0 @@ -@font-face { - font-family: xecret; - src: url('../assets/xecret.ttf'); -} - -#secret { - font-family: xecret, sans-serif; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/imports/logo.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/imports/logo.less deleted file mode 100644 index 22893a23..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/imports/logo.less +++ /dev/null @@ -1,5 +0,0 @@ -#logo { - width: 100px; - height: 100px; - background: url('../assets/logo.png'); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/invalid-css.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/invalid-css.less deleted file mode 100644 index ed585d63..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/invalid-css.less +++ /dev/null @@ -1 +0,0 @@ -this isn't very valid CSS. \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/urls.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/urls.less deleted file mode 100644 index bb48f77a..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/import/urls.less +++ /dev/null @@ -1 +0,0 @@ -// empty file showing that it loads from the relative path first diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/javascript.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/javascript.less deleted file mode 100644 index b826a787..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/javascript.less +++ /dev/null @@ -1,29 +0,0 @@ -.eval { - js: `42`; - js: `1 + 1`; - js: `"hello world"`; - js: `[1, 2, 3]`; - title: `typeof process.title`; - ternary: `(1 + 1 == 2 ? true : false)`; - multiline: `(function(){var x = 1 + 1; - return x})()`; -} -.scope { - @foo: 42; - var: `parseInt(this.foo.toJS())`; - escaped: ~`2 + 5 + 'px'`; -} -.vars { - @var: `4 + 4`; - width: @var; -} -.escape-interpol { - @world: "world"; - width: ~`"hello" + " " + @{world}`; -} -.arrays { - @ary: 1, 2, 3; - @ary2: 1 2 3; - ary: `@{ary}.join(', ')`; - ary1: `@{ary2}.join(', ')`; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/lazy-eval.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/lazy-eval.less deleted file mode 100644 index 72b3fd46..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/lazy-eval.less +++ /dev/null @@ -1,6 +0,0 @@ -@var: @a; -@a: 100%; - -.lazy-eval { - width: @var; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/legacy/legacy.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/legacy/legacy.less deleted file mode 100644 index 92d00088..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/legacy/legacy.less +++ /dev/null @@ -1,7 +0,0 @@ -@media (-o-min-device-pixel-ratio: 2/1) { - .test-math-and-units { - font: ignores 0/0 rules; - test-division: 4 / 2 + 5em; - simple: 1px + 1px; - } -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/media.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/media.less deleted file mode 100644 index 01a6a020..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/media.less +++ /dev/null @@ -1,234 +0,0 @@ - -// For now, variables can't be declared inside @media blocks. - -@var: 42; - -@media print { - .class { - color: blue; - .sub { - width: @var; - } - } - .top, header > h1 { - color: (#222 * 2); - } -} - -@media screen { - @base: 8; - body { max-width: (@base * 60); } -} - -@ratio_large: 16; -@ratio_small: 9; - -@media all and (device-aspect-ratio: @ratio_large / @ratio_small) { - body { max-width: 800px; } -} - -@media all and (orientation:portrait) { - aside { float: none; } -} - -@media handheld and (min-width: @var), screen and (min-width: 20em) { - body { - max-width: 480px; - } -} - -body { - @media print { - padding: 20px; - - header { - background-color: red; - } - - @media (orientation:landscape) { - margin-left: 20px; - } - } -} - -@media screen { - .sidebar { - width: 300px; - @media (orientation: landscape) { - width: 500px; - } - } -} - -@media a { - .first { - @media b { - .second { - .third { - width: 300px; - @media c { - width: 500px; - } - } - .fourth { - width: 3; - } - } - } - } -} - -body { - @media a, b and c { - width: 95%; - - @media x, y { - width: 100%; - } - } -} - -.mediaMixin(@fallback: 200px) { - background: black; - - @media handheld { - background: white; - - @media (max-width: @fallback) { - background: red; - } - } -} - -.a { - .mediaMixin(100px); -} - -.b { - .mediaMixin(); -} -@smartphone: ~"only screen and (max-width: 200px)"; -@media @smartphone { - body { - width: 480px; - } -} - -@media print { - @page :left { - margin: 0.5cm; - } - @page :right { - margin: 0.5cm; - } - @page Test:first { - margin: 1cm; - } - @page :first { - size: 8.5in 11in; - @top-left { - margin: 1cm; - } - @top-left-corner { - margin: 1cm; - } - @top-center { - margin: 1cm; - } - @top-right { - margin: 1cm; - } - @top-right-corner { - margin: 1cm; - } - @bottom-left { - margin: 1cm; - } - @bottom-left-corner { - margin: 1cm; - } - @bottom-center { - margin: 1cm; - } - @bottom-right { - margin: 1cm; - } - @bottom-right-corner { - margin: 1cm; - } - @left-top { - margin: 1cm; - } - @left-middle { - margin: 1cm; - } - @left-bottom { - margin: 1cm; - } - @right-top { - margin: 1cm; - } - @right-middle { - content: "Page " counter(page); - } - @right-bottom { - margin: 1cm; - } - } -} - -@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 128dpcm) { - .b { - background: red; - } -} - -.bg() { - background: red; - - @media (max-width: 500px) { - background: green; - } -} - -body { - .bg(); -} - -@bpMedium: 1000px; -@media (max-width: @bpMedium) { - body { - .bg(); - background: blue; - } -} - -@media (max-width: 1200px) { - /* a comment */ - - @media (max-width: 900px) { - body { font-size: 11px; } - } -} - -.nav-justified { - @media (min-width: 480px) { - > li { - display: table-cell; - } - } -} - -.menu -{ - @media (min-width: 768px) { - .nav-justified(); - } -} -@all: ~"all"; -@tv: ~"tv"; -@media @all and @tv { - .all-and-tv-variables { - var: all-and-tv; - } -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/merge.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/merge.less deleted file mode 100644 index 52d0796e..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/merge.less +++ /dev/null @@ -1,51 +0,0 @@ -.first-transform() { - transform+: rotate(90deg), skew(30deg); -} -.second-transform() { - transform+: scale(2,4); -} -.third-transform() { - transform: scaleX(45deg); -} -.fourth-transform() { - transform+: scaleX(45deg); -} -.fifth-transform() { - transform+: scale(2,4) !important; -} -.first-background() { - background+: url(data://img1.png); -} -.second-background() { - background+: url(data://img2.png); -} - -.test1 { - // Can merge values - .first-transform(); - .second-transform(); -} -.test2 { - // Wont merge values without +: merge directive, for backwards compatibility with css - .first-transform(); - .third-transform(); -} -.test3 { - // Wont merge values from two sources with different properties - .fourth-transform(); - .first-background(); -} -.test4 { - // Wont merge values from sources that merked as !important, for backwards compatibility with css - .first-transform(); - .fifth-transform(); -} -.test5 { - // Wont merge values from mixins that merked as !important, for backwards compatibility with css - .first-transform(); - .second-transform() !important; -} -.test6 { - // Ignores !merge if no peers found - .second-transform(); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-args.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-args.less deleted file mode 100644 index 8cdc67df..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-args.less +++ /dev/null @@ -1,215 +0,0 @@ -.mixin (@a: 1px, @b: 50%) { - width: (@a * 5); - height: (@b - 1%); -} - -.mixina (@style, @width, @color: black) { - border: @width @style @color; -} - -.mixiny -(@a: 0, @b: 0) { - margin: @a; - padding: @b; -} - -.hidden() { - color: transparent; // asd -} - -#hidden { - .hidden; -} - -#hidden1 { - .hidden(); -} - -.two-args { - color: blue; - .mixin(2px, 100%); - .mixina(dotted, 2px); -} - -.one-arg { - .mixin(3px); -} - -.no-parens { - .mixin; -} - -.no-args { - .mixin(); -} - -.var-args { - @var: 9; - .mixin(@var, (@var * 2)); -} - -.multi-mix { - .mixin(2px, 30%); - .mixiny(4, 5); -} - -.maxa(@arg1: 10, @arg2: #f00) { - padding: (@arg1 * 2px); - color: @arg2; -} - -body { - .maxa(15); -} - -@glob: 5; -.global-mixin(@a:2) { - width: (@glob + @a); -} - -.scope-mix { - .global-mixin(3); -} - -.nested-ruleset (@width: 200px) { - width: @width; - .column { margin: @width; } -} -.content { - .nested-ruleset(600px); -} - -// - -.same-var-name2(@radius) { - radius: @radius; -} -.same-var-name(@radius) { - .same-var-name2(@radius); -} -#same-var-name { - .same-var-name(5px); -} - -// - -.var-inside () { - @var: 10px; - width: @var; -} -#var-inside { .var-inside; } - -.mixin-arguments (@width: 0px, ...) { - border: @arguments; - width: @width; -} - -.arguments { - .mixin-arguments(1px, solid, black); -} -.arguments2 { - .mixin-arguments(); -} -.arguments3 { - .mixin-arguments; -} - -.mixin-arguments2 (@width, @rest...) { - border: @arguments; - rest: @rest; - width: @width; -} -.arguments4 { - .mixin-arguments2(0, 1, 2, 3, 4); -} - -// Edge cases - -.edge-case { - .mixin-arguments("{"); -} - -// Division vs. Literal Slash -.border-radius(@r: 2px/5px) { - border-radius: @r; -} -.slash-vs-math { - .border-radius(); - .border-radius(5px/10px); - .border-radius((3px * 2)); -} -// semi-colon vs comma for delimiting - -.mixin-takes-one(@a) { - one: @a; -} - -.mixin-takes-two(@a; @b) { - one: @a; - two: @b; -} - -.comma-vs-semi-colon { - .mixin-takes-two(@a : a; @b : b, c); - .mixin-takes-two(@a : d, e; @b : f); - .mixin-takes-one(@a: g); - .mixin-takes-one(@a : h;); - .mixin-takes-one(i); - .mixin-takes-one(j;); - .mixin-takes-two(k, l); - .mixin-takes-one(m, n;); - .mixin-takes-two(o, p; q); - .mixin-takes-two(r, s; t;); -} - -.mixin-conflict(@a:defA, @b:defB, @c:defC) { - three: @a, @b, @c; -} - -.mixin-conflict(@a:defA, @b:defB, @c:defC, @d:defD) { - four: @a, @b, @c, @d; -} - -#named-conflict { - .mixin-conflict(11, 12, 13, @a:a); - .mixin-conflict(@a:a, 21, 22, 23); -} -@a: 3px; -.mixin-default-arg(@a: 1px, @b: @a, @c: @b) { - defaults: 1px 1px 1px; - defaults: 2px 2px 2px; -} - -.test-mixin-default-arg { - .mixin-default-arg(); - .mixin-default-arg(2px); -} - -.mixin-comma-default1(@color; @padding; @margin: 2, 2, 2, 2) { - margin: @margin; -} -.selector { - .mixin-comma-default1(#33acfe; 4); -} -.mixin-comma-default2(@margin: 2, 2, 2, 2;) { - margin: @margin; -} -.selector2 { - .mixin-comma-default2(); -} -.mixin-comma-default3(@margin: 2, 2, 2, 2) { - margin: @margin; -} -.selector3 { - .mixin-comma-default3(4,2,2,2); -} - -.test-calling-one-arg-mixin(@a) { -} - -.test-calling-one-arg-mixin(@a, @b, @rest...) { -} - -div { - .test-calling-one-arg-mixin(1); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-closure.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-closure.less deleted file mode 100644 index 01251d2a..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-closure.less +++ /dev/null @@ -1,26 +0,0 @@ -.scope { - @var: 99px; - .mixin () { - width: @var; - } -} - -.class { - .scope > .mixin; -} - -.overwrite { - @var: 0px; - .scope > .mixin; -} - -.nested { - @var: 5px; - .mixin () { - width: @var; - } - .class { - @var: 10px; - .mixin; - } -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-guards.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-guards.less deleted file mode 100644 index 4d0774df..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-guards.less +++ /dev/null @@ -1,153 +0,0 @@ - -// Stacking, functions.. - -.light (@a) when (lightness(@a) > 50%) { - color: white; -} -.light (@a) when (lightness(@a) < 50%) { - color: black; -} -.light (@a) { - margin: 1px; -} - -.light1 { .light(#ddd) } -.light2 { .light(#444) } - -// Arguments against each other - -.max (@a, @b) when (@a > @b) { - width: @a; -} -.max (@a, @b) when (@a < @b) { - width: @b; -} - -.max1 { .max(3, 6) } -.max2 { .max(8, 1) } - -// Globals inside guards - -@g: auto; - -.glob (@a) when (@a = @g) { - margin: @a @g; -} -.glob1 { .glob(auto) } - -// Other operators - -.ops (@a) when (@a >= 0) { - height: gt-or-eq; -} -.ops (@a) when (@a =< 0) { - height: lt-or-eq; -} -.ops (@a) when (@a <= 0) { - height: lt-or-eq-alias; -} -.ops (@a) when not(@a = 0) { - height: not-eq; -} -.ops1 { .ops(0) } -.ops2 { .ops(1) } -.ops3 { .ops(-1) } - -// Scope and default values - -@a: auto; - -.default (@a: inherit) when (@a = inherit) { - content: default; -} -.default1 { .default } - -// true & false keywords -.test (@a) when (@a) { - content: "true."; -} -.test (@a) when not (@a) { - content: "false."; -} - -.test1 { .test(true) } -.test2 { .test(false) } -.test3 { .test(1) } -.test4 { .test(boo) } -.test5 { .test("true") } - -// Boolean expressions - -.bool () when (true) and (false) { content: true and false } // FALSE -.bool () when (true) and (true) { content: true and true } // TRUE -.bool () when (true) { content: true } // TRUE -.bool () when (false) and (false) { content: true } // FALSE -.bool () when (false), (true) { content: false, true } // TRUE -.bool () when (false) and (true) and (true), (true) { content: false and true and true, true } // TRUE -.bool () when (true) and (true) and (false), (false) { content: true and true and false, false } // FALSE -.bool () when (false), (true) and (true) { content: false, true and true } // TRUE -.bool () when (false), (false), (true) { content: false, false, true } // TRUE -.bool () when (false), (false) and (true), (false) { content: false, false and true, false } // FALSE -.bool () when (false), (true) and (true) and (true), (false) { content: false, true and true and true, false } // TRUE -.bool () when not (false) { content: not false } -.bool () when not (true) and not (false) { content: not true and not false } -.bool () when not (true) and not (true) { content: not true and not true } -.bool () when not (false) and (false), not (false) { content: not false and false, not false } - -.bool1 { .bool } - -.equality-unit-test(@num) when (@num = 1%) { - test: fail; -} -.equality-unit-test(@num) when (@num = 2) { - test: pass; -} -.equality-units { - .equality-unit-test(1px); - .equality-unit-test(2px); -} - -.colorguard(@col) when (@col = red) { content: is @col; } -.colorguard(@col) when not (blue = @col) { content: is not blue its @col; } -.colorguard(@col) {} -.colorguardtest { - .colorguard(red); - .colorguard(blue); - .colorguard(purple); -} - -.stringguard(@str) when (@str = "theme1") { content: is theme1; } -.stringguard(@str) when not ("theme2" = @str) { content: is not theme2; } -.stringguard(@str) when (~"theme1" = @str) { content: is theme1 no quotes; } -.stringguard(@str) {} -.stringguardtest { - .stringguard("theme1"); - .stringguard("theme2"); - .stringguard(theme1); -} - -.mixin(...) { - catch:all; -} -.mixin(@var) when (@var=4) { - declare: 4; -} -.mixin(@var) when (@var=4px) { - declare: 4px; -} -#tryNumberPx { - .mixin(4px); -} - -.lock-mixin(@a) { - .inner-locked-mixin(@x: @a) when (@a = 1) { - a: @a; - x: @x; - } -} -.call-lock-mixin { - .lock-mixin(1); - .call-inner-lock-mixin { - .inner-locked-mixin(); - } -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-important.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-important.less deleted file mode 100644 index c8cc1d5c..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-important.less +++ /dev/null @@ -1,25 +0,0 @@ -.submixin(@a) { - border-width: @a; -} -.mixin (9) { - border: 9 !important; -} -.mixin (@a: 0) { - border: @a; - boxer: @a; - .inner { - test: @a; - } - // comment - .submixin(@a); -} - -.class { - .mixin(1); - .mixin(2) !important; - .mixin(3); - .mixin(4) !important; - .mixin(5); - .mixin !important; - .mixin(9); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-named-args.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-named-args.less deleted file mode 100644 index d79e0f47..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-named-args.less +++ /dev/null @@ -1,36 +0,0 @@ -.mixin (@a: 1px, @b: 50%) { - width: (@a * 5); - height: (@b - 1%); - args: @arguments; -} -.mixin (@a: 1px, @b: 50%) when (@b > 75%){ - text-align: center; -} - -.named-arg { - color: blue; - .mixin(@b: 100%); -} - -.class { - @var: 20%; - .mixin(@b: @var); -} - -.all-args-wrong-args { - .mixin(@b: 10%, @a: 2px); -} - -.mixin2 (@a: 1px, @b: 50%, @c: 50) { - width: (@a * 5); - height: (@b - 1%); - color: (#000000 + @c); -} - -.named-args2 { - .mixin2(3px, @c: 100); -} - -.named-args3 { - .mixin2(@b: 30%, @c: #123456); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-nested.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-nested.less deleted file mode 100644 index 43443de2..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-nested.less +++ /dev/null @@ -1,22 +0,0 @@ -.mix-inner (@var) { - border-width: @var; -} - -.mix (@a: 10) { - .inner { - height: (@a * 10); - - .innest { - width: @a; - .mix-inner((@a * 2)); - } - } -} - -.class { - .mix(30); -} - -.class2 { - .mix(60); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-pattern.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-pattern.less deleted file mode 100644 index f6a12ece..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins-pattern.less +++ /dev/null @@ -1,99 +0,0 @@ -.mixin (...) { - variadic: true; -} -.mixin () { - zero: 0; -} -.mixin (@a: 1px) { - one: 1; -} -.mixin (@a) { - one-req: 1; -} -.mixin (@a: 1px, @b: 2px) { - two: 2; -} - -.mixin (@a, @b, @c) { - three-req: 3; -} - -.mixin (@a: 1px, @b: 2px, @c: 3px) { - three: 3; -} - -.zero { - .mixin(); -} - -.one { - .mixin(1); -} - -.two { - .mixin(1, 2); -} - -.three { - .mixin(1, 2, 3); -} - -// - -.mixout ('left') { - left: 1; -} - -.mixout ('right') { - right: 1; -} - -.left { - .mixout('left'); -} -.right { - .mixout('right'); -} - -// - -.border (@side, @width) { - color: black; - .border-side(@side, @width); -} -.border-side (left, @w) { - border-left: @w; -} -.border-side (right, @w) { - border-right: @w; -} - -.border-right { - .border(right, 4px); -} -.border-left { - .border(left, 4px); -} - -// - - -.border-radius (@r) { - both: (@r * 10); -} -.border-radius (@r, left) { - left: @r; -} -.border-radius (@r, right) { - right: @r; -} - -.only-right { - .border-radius(33, right); -} -.only-left { - .border-radius(33, left); -} -.left-right { - .border-radius(33); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins.less deleted file mode 100644 index be9e2bbd..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/mixins.less +++ /dev/null @@ -1,141 +0,0 @@ -.mixin { border: 1px solid black; } -.mixout { border-color: orange; } -.borders { border-style: dashed; } - -#namespace { - .borders { - border-style: dotted; - } - .biohazard { - content: "death"; - .man { - color: transparent; - } - } -} -#theme { - > .mixin { - background-color: grey; - } -} -#container { - color: black; - .mixin; - .mixout; - #theme > .mixin; -} - -#header { - .milk { - color: white; - .mixin; - #theme > .mixin; - } - #cookie { - .chips { - #namespace .borders; - .calories { - #container; - } - } - .borders; - } -} -.secure-zone { #namespace .biohazard .man; } -.direct { - #namespace > .borders; -} - -.bo, .bar { - width: 100%; -} -.bo { - border: 1px; -} -.ar.bo.ca { - color: black; -} -.jo.ki { - background: none; -} -.amp { - &.support { - color: orange; - .higher { - top: 0px; - } - &.deeper { - height: auto; - } - } -} -.extended { - .bo; - .jo.ki; - .amp.support; - .amp.support.higher; - .amp.support.deeper; -} -.do .re .mi .fa { - .sol .la { - .si { - color: cyan; - } - } -} -.mutli-selector-parents { - .do.re.mi.fa.sol.la.si; -} -.foo .bar { - .bar; -} -.has_parents() { - & .underParents { - color: red; - } -} -.has_parents(); -.parent { - .has_parents(); -} -.margin_between(@above, @below) { - * + & { margin-top: @above; } - legend + & { margin-top: 0; } - & + * { margin-top: @below; } -} -h1 { .margin_between(25px, 10px); } -h2 { .margin_between(20px, 8px); } -h3 { .margin_between(15px, 5px); } - -.mixin_def(@url, @position){ - background-image: @url; - background-position: @position; -} -.error{ - @s: "/"; - .mixin_def( "@{s}a.png", center center); -} -.recursion() { - color: black; -} -.test-rec { - .recursion { - .recursion(); - } -} -.paddingFloat(@padding) { padding-left: @padding; } - -.button { - .paddingFloat(((10px + 12) * 2)); - - &.large { .paddingFloat(((10em * 2) * 2)); } -} -.clearfix() { - // ... -} -.clearfix { - .clearfix(); -} -.foo { - .clearfix(); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/no-js-errors/no-js-errors.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/no-js-errors/no-js-errors.less deleted file mode 100644 index 15ef8a45..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/no-js-errors/no-js-errors.less +++ /dev/null @@ -1,3 +0,0 @@ -.a { - a: `1 + 1`; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/no-js-errors/no-js-errors.txt b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/no-js-errors/no-js-errors.txt deleted file mode 100644 index d81dd2bd..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/no-js-errors/no-js-errors.txt +++ /dev/null @@ -1,4 +0,0 @@ -SyntaxError: You are using JavaScript, which has been disabled. in {path}no-js-errors.less on line 2, column 6: -1 .a { -2 a: `1 + 1`; -3 } diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/no-output.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/no-output.less deleted file mode 100644 index b4e6a499..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/no-output.less +++ /dev/null @@ -1,2 +0,0 @@ -.mixin() { -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/operations.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/operations.less deleted file mode 100644 index 3e483c8b..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/operations.less +++ /dev/null @@ -1,62 +0,0 @@ -#operations { - color: (#110000 + #000011 + #001100); // #111111 - height: (10px / 2px + 6px - 1px * 2); // 9px - width: (2 * 4 - 5em); // 3em - .spacing { - height: (10px / 2px+6px-1px*2); - width: (2 * 4-5em); - } - substraction: (20 - 10 - 5 - 5); // 0 - division: (20 / 5 / 4); // 1 -} - -@x: 4; -@y: 12em; - -.with-variables { - height: (@x + @y); // 16em - width: (12 + @y); // 24em - size: (5cm - @x); // 1cm -} - -.with-functions { - color: (rgb(200, 200, 200) / 2); - color: (2 * hsl(0, 50%, 50%)); - color: (rgb(10, 10, 10) + hsl(0, 50%, 50%)); -} - -@z: -2; - -.negative { - height: (2px + @z); // 0px - width: (2px - @z); // 4px -} - -.shorthands { - padding: -1px 2px 0 -4px; // -} - -.rem-dimensions { - font-size: (20rem / 5 + 1.5rem); // 5.5rem -} - -.colors { - color: #123; // #112233 - border-color: (#234 + #111111); // #334455 - background-color: (#222222 - #fff); // #000000 - .other { - color: (2 * #111); // #222222 - border-color: (#333333 / 3 + #111); // #222222 - } -} - -.negations { - @var: 4px; - variable: (-@var); // 4 - variable1: (-@var + @var); // 0 - variable2: (@var + -@var); // 0 - variable3: (@var - -@var); // 8 - variable4: (-@var - -@var); // 0 - paren: (-(@var)); // -4px - paren2: (-(2 + 2) * -@var); // 16 -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/parens.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/parens.less deleted file mode 100644 index deb41391..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/parens.less +++ /dev/null @@ -1,41 +0,0 @@ -.parens { - @var: 1px; - border: (@var * 2) solid black; - margin: (@var * 1) (@var + 2) (4 * 4) 3; - width: (6 * 6); - padding: 2px (6 * 6px); -} - -.more-parens { - @var: (2 * 2); - padding: (2 * @var) 4 4 (@var * 1px); - width-all: ((@var * @var) * 6); - width-first: ((@var * @var)) * 6; - width-keep: (@var * @var) * 6; - height-keep: (7 * 7) + (8 * 8); - height-all: ((7 * 7) + (8 * 8)); - height-parts: ((7 * 7)) + ((8 * 8)); - margin-keep: (4 * (5 + 5) / 2) - (@var * 2); - margin-parts: ((4 * (5 + 5) / 2)) - ((@var * 2)); - margin-all: ((4 * (5 + 5) / 2) + (-(@var * 2))); - border-radius-keep: 4px * (1 + 1) / @var + 3px; - border-radius-parts: ((4px * (1 + 1))) / ((@var + 3px)); - border-radius-all: (4px * (1 + 1) / @var + 3px); - //margin: (6 * 6)px; -} - -.negative { - @var: 1; - neg-var: -@var; // -1 ? - neg-var-paren: -(@var); // -(1) ? -} - -.nested-parens { - width: 2 * (4 * (2 + (1 + 6))) - 1; - height: ((2 + 3) * (2 + 3) / (9 - 4)) + 1; -} - -.mixed-units { - margin: 2px 4em 1 5pc; - padding: (2px + 4px) 1em 2px 2; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/rulesets.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/rulesets.less deleted file mode 100644 index e81192db..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/rulesets.less +++ /dev/null @@ -1,30 +0,0 @@ -#first > .one { - > #second .two > #deux { - width: 50%; - #third { - &:focus { - color: black; - #fifth { - > #sixth { - .seventh #eighth { - + #ninth { - color: purple; - } - } - } - } - } - height: 100%; - } - #fourth, #five, #six { - color: #110000; - .seven, .eight > #nine { - border: 1px solid black; - } - #ten { - color: red; - } - } - } - font-size: 2em; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/scope.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/scope.less deleted file mode 100644 index 36d37061..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/scope.less +++ /dev/null @@ -1,79 +0,0 @@ -@x: red; -@x: blue; -@z: transparent; -@mix: none; - -.mixin { - @mix: #989; -} -@mix: blue; -.tiny-scope { - color: @mix; // #989 - .mixin; -} - -.scope1 { - @y: orange; - @z: black; - color: @x; // blue - border-color: @z; // black - .hidden { - @x: #131313; - } - .scope2 { - @y: red; - color: @x; // blue - .scope3 { - @local: white; - color: @y; // red - border-color: @z; // black - background-color: @local; // white - } - } -} - -#namespace { - .scoped_mixin() { - @local-will-be-made-global: green; - .scope { - scoped-val: @local-will-be-made-global; - } - } -} - -#namespace > .scoped_mixin(); - -.setHeight(@h) { @height: 1024px; } -.useHeightInMixinCall(@h) { .useHeightInMixinCall { mixin-height: @h; } } -@mainHeight: 50%; -.setHeight(@mainHeight); -.heightIsSet { height: @height; } -.useHeightInMixinCall(@height); - -.importRuleset() { - .imported { - exists: true; - } -} -.importRuleset(); -.testImported { - .imported; -} - -@parameterDefault: 'top level'; -@anotherVariable: 'top level'; -//mixin uses top-level variables -.mixinNoParam(@parameter: @parameterDefault) when (@parameter = 'top level') { - default: @parameter; - scope: @anotherVariable; - sub-scope-only: @subScopeOnly; -} - -#allAreUsedHere { - //redefine top-level variables in different scope - @parameterDefault: 'inside'; - @anotherVariable: 'inside'; - @subScopeOnly: 'inside'; - //use the mixin - .mixinNoParam(); -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/selectors.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/selectors.less deleted file mode 100644 index ed7db7ce..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/selectors.less +++ /dev/null @@ -1,144 +0,0 @@ -h1, h2, h3 { - a, p { - &:hover { - color: red; - } - } -} - -#all { color: blue; } -#the { color: blue; } -#same { color: blue; } - -ul, li, div, q, blockquote, textarea { - margin: 0; -} - -td { - margin: 0; - padding: 0; -} - -td, input { - line-height: 1em; -} - -a { - color: red; - - &:hover { color: blue; } - - div & { color: green; } - - p & span { color: yellow; } -} - -.foo { - .bar, .baz { - & .qux { - display: block; - } - .qux & { - display: inline; - } - .qux& { - display: inline-block; - } - .qux & .biz { - display: none; - } - } -} - -.b { - &.c { - .a& { - color: red; - } - } -} - -.b { - .c & { - &.a { - color: red; - } - } -} - -.p { - .foo &.bar { - color: red; - } -} - -.p { - .foo&.bar { - color: red; - } -} - -.foo { - .foo + & { - background: amber; - } - & + & { - background: amber; - } -} - -.foo, .bar { - & + & { - background: amber; - } -} - -.foo, .bar { - a, b { - & > & { - background: amber; - } - } -} - -.other ::fnord { color: red } -.other::fnord { color: red } -.other { - ::bnord {color: red } - &::bnord {color: red } -} -// selector interpolation -@theme: blood; -@selector: ~".@{theme}"; -@{selector} { - color:red; -} -@{selector}red { - color: green; -} -.red { - #@{theme}.@{theme}&.black { - color:black; - } -} -@num: 3; -:nth-child(@{num}) { - selector: interpolated; -} -.test { - &:nth-child(odd):not(:nth-child(3)) { - color: #ff0000; - } -} -[prop], -[prop=10%], -[prop="value@{num}"], -[prop*="val@{num}"], -[|prop~="val@{num}"], -[*|prop$="val@{num}"], -[ns|prop^="val@{num}"], -[@{num}^="val@{num}"], -[@{num}=@{num}], -[@{num}] { - attributes: yes; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/sourcemaps/basic.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/sourcemaps/basic.less deleted file mode 100644 index 4ee8b4f6..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/sourcemaps/basic.less +++ /dev/null @@ -1,27 +0,0 @@ -@var: black; - -.a() { - color: red; -} - -.b { - color: green; - .a(); - color: blue; - background: @var; -} - -.a, .b { - background: green; - .c, .d { - background: gray; - & + & { - color: red; - } - } -} - -.extend:extend(.a all) { - color: pink; -} -@import (inline) "imported.css"; \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/sourcemaps/imported.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/sourcemaps/imported.css deleted file mode 100644 index 2ee35f06..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/sourcemaps/imported.css +++ /dev/null @@ -1,7 +0,0 @@ -/*comments*/ -.unused-css { - color: white; -} -.imported { - color: black; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/static-urls/urls.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/static-urls/urls.less deleted file mode 100644 index 197c616f..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/static-urls/urls.less +++ /dev/null @@ -1,32 +0,0 @@ -@font-face { - src: local(Futura-Medium), - url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); -} - -#svg-data-uri { - background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>'); -} - -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - @a: 'Trebuchet'; - url: url(@a); -} - -@import "../import/import-and-relative-paths-test"; diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/strings.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/strings.less deleted file mode 100644 index c43e368d..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/strings.less +++ /dev/null @@ -1,57 +0,0 @@ -#strings { - background-image: url("http://son-of-a-banana.com"); - quotes: "~" "~"; - content: "#*%:&^,)!.(~*})"; - empty: ""; - brackets: "{" "}"; - escapes: "\"hello\" \\world"; - escapes2: "\"llo"; -} -#comments { - content: "/* hello */ // not-so-secret"; -} -#single-quote { - quotes: "'" "'"; - content: '""#!&""'; - empty: ''; - semi-colon: ';'; -} -#escaped { - filter: ~"DX.Transform.MS.BS.filter(opacity=50)"; -} -#one-line { image: url(http://tooks.com) } -#crazy { image: url(http://), "}", url("http://}") } -#interpolation { - @var: '/dev'; - url: "http://lesscss.org@{var}/image.jpg"; - - @var2: 256; - url2: "http://lesscss.org/image-@{var2}.jpg"; - - @var3: #456; - url3: "http://lesscss.org@{var3}"; - - @var4: hello; - url4: "http://lesscss.org/@{var4}"; - - @var5: 54.4px; - url5: "http://lesscss.org/@{var5}"; -} - -// multiple calls with string interpolation - -.mix-mul (@a: green) { - color: ~"@{a}"; -} -.mix-mul-class { - .mix-mul(blue); - .mix-mul(red); - .mix-mul(black); - .mix-mul(orange); -} - -@test: Arial, Verdana, San-Serif; -.watermark { - @family: ~"Univers, @{test}"; - family: @family; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/urls.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/urls.less deleted file mode 100644 index 0e5a41c4..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/urls.less +++ /dev/null @@ -1,66 +0,0 @@ -@font-face { - src: local(Futura-Medium), - url(fonts.svg#MyGeometricModern) format("svg"); -} -#shorthands { - background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; - background: url("img.jpg") center / 100px; - background: #fff url(image.png) center / 1px 100px repeat-x scroll content-box padding-box; -} -#misc { - background-image: url(images/image.jpg); -} -#data-uri { - background: url(data:image/png;charset=utf-8;base64, - kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/ - k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U - kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC); - background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==); - background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700); - background-image: url("http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700"); -} - -#svg-data-uri { - background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>'); -} - -.comma-delimited { - background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); -} -.values { - @a: 'Trebuchet'; - url: url(@a); -} - -@import "import/import-and-relative-paths-test"; - -#data-uri { - uri: data-uri('image/jpeg;base64', '../data/image.jpg'); -} - -#data-uri-guess { - uri: data-uri('../data/image.jpg'); -} - -#data-uri-ascii { - uri-1: data-uri('text/html', '../data/page.html'); - uri-2: data-uri('../data/page.html'); -} - -#data-uri-toobig { - uri: data-uri('../data/data-uri-fail.png'); -} -.add_an_import(@file_to_import) { -@import "@{file_to_import}"; -} - -.add_an_import("file.css"); - -#svg-functions { - background-image: svg-gradient(to bottom, black, white); - background-image: svg-gradient(to bottom, black, orange 3%, white); - @green_5: green 5%; - @orange_percentage: 3%; - @orange_color: orange; - background-image: svg-gradient(to bottom, (mix(black, white) + #444) 1%, @orange_color @orange_percentage, ((@green_5)), white 95%); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/variables.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/variables.less deleted file mode 100644 index e896f404..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/variables.less +++ /dev/null @@ -1,83 +0,0 @@ -@a: 2; -@x: (@a * @a); -@y: (@x + 1); -@z: (@x * 2 + @y); -@var: -1; - -.variables { - width: (@z + 1cm); // 14cm -} - -@b: @a * 10; -@c: #888; - -@fonts: "Trebuchet MS", Verdana, sans-serif; -@f: @fonts; - -@quotes: "~" "~"; -@q: @quotes; -@onePixel: 1px; - -.variables { - height: (@b + @x + 0px); // 24px - color: @c; - font-family: @f; - quotes: @q; -} - -.redef { - @var: 0; - .inition { - @var: 4; - @var: 2; - three: @var; - @var: 3; - } - zero: @var; -} - -.values { - minus-one: @var; - @a: 'Trebuchet'; - @multi: 'A', B, C; - font-family: @a, @a, @a; - color: @c !important; - multi: something @multi, @a; -} - -.variable-names { - @var: 'hello'; - @name: 'var'; - name: @@name; -} - -.alpha { - @var: 42; - filter: alpha(opacity=@var); -} - -.polluteMixin() { - @a: 'pollution'; -} -.testPollution { - @a: 'no-pollution'; - a: @a; - .polluteMixin(); - a: @a; -} - -.units { - width: @onePixel; - same-unit-as-previously: (@onePixel / @onePixel); - square-pixel-divided: (@onePixel * @onePixel / @onePixel); - odd-unit: unit((@onePixel * 4em / 2cm)); - percentage: (10 * 50%); - pixels: (50px * 10); - conversion-metric-a: (20mm + 1cm); - conversion-metric-b: (1cm + 20mm); - conversion-imperial: (1in + 72pt + 6pc); - custom-unit: (42octocats * 10); - custom-unit-cancelling: (8cats * 9dogs / 4cats); - mix-units: (1px + 1em); - invalid-units: (1px * 1px); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/whitespace.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/whitespace.less deleted file mode 100644 index ab4804da..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/less/whitespace.less +++ /dev/null @@ -1,44 +0,0 @@ - - -.whitespace - { color: white; } - -.whitespace -{ - color: white; -} - .whitespace -{ color: white; } - -.whitespace{color:white;} -.whitespace { color : white ; } - -.white, -.space, -.mania -{ color: white; } - -.no-semi-column { color: white } -.no-semi-column { - color: white; - white-space: pre -} -.no-semi-column {border: 2px solid white} -.newlines { - background: the, - great, - wall; - border: 2px - solid - black; -} -.empty { - -} -.sel -.newline_ws .tab_ws { -color: -white; -background-position: 45 --23; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/sourcemaps/basic.json b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/sourcemaps/basic.json deleted file mode 100644 index 9018fef9..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/sourcemaps/basic.json +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"sourcemaps/basic.css","sources":["testweb/sourcemaps/imported.css","testweb/sourcemaps/basic.less"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;ACAG;EACD,YAAA;EAJA,UAAA;EAWA,iBAAA;EALA,WAAA;EACA,mBAAA;;AAJC,EASC;AATD,EASM;EACL,gBAAA;;AACE,EAFF,GAEM,KAFN;AAEE,EAFF,GAEM,KAFD;AAEH,EAFG,GAEC,KAFN;AAEE,EAFG,GAEC,KAFD;EAGH,UAAA;;AALJ;AAAK;AAUA;EATL,iBAAA;;AADA,EAEE;AAFG,EAEH;AAFF,EAEO;AAFF,EAEE;AAQF,OARH;AAQG,OARE;EACL,gBAAA;;AACE,EAFF,GAEM,KAFN;AAEE,EAFF,GAEM,KAFN;AAEE,EAFF,GAEM,KAFD;AAEH,EAFF,GAEM,KAFD;AAEH,EAFF,GAEM,KAFN;AAEE,EAFF,GAEM,KAFN;AAEE,EAFF,GAEM,KAFD;AAEH,EAFF,GAEM,KAFD;AAEH,EAFG,GAEC,KAFN;AAEE,EAFG,GAEC,KAFN;AAEE,EAFG,GAEC,KAFD;AAEH,EAFG,GAEC,KAFD;AAEH,EAFG,GAEC,KAFN;AAEE,EAFG,GAEC,KAFN;AAEE,EAFG,GAEC,KAFD;AAEH,EAFG,GAEC,KAFD;AAQF,OARH,GAQG,UARH;AAQG,OARH,GAEM,KAFN;AAQG,OARH,GAQG,UARE;AAQF,OARH,GAEM,KAFD;AAEH,EAFF,GAQG,UARH;AAEE,EAFF,GAQG,UARE;AAQF,OARE,GAQF,UARH;AAQG,OARE,GAEC,KAFN;AAQG,OARE,GAQF,UARE;AAQF,OARE,GAEC,KAFD;AAEH,EAFG,GAQF,UARH;AAEE,EAFG,GAQF,UARE;EAGH,UAAA;;AAKC;EACL,WAAA"} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/sourcemaps/index.html b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/sourcemaps/index.html deleted file mode 100644 index 89acca77..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--node_modules--less--test/sourcemaps/index.html +++ /dev/null @@ -1,17 +0,0 @@ -<html> - <link type="text/css" rel="stylesheet" media="all" href="import.css"> - <link type="text/css" rel="stylesheet" media="all" href="basic.css"> -<head> -</head> -<body> -<div id="import-test">id import-test</div> -<div id="import">id import-test</div> -<div class="imported inline">class imported inline</div> -<div id="mixin">class mixin</div> -<div class="a">class a</div> -<div class="b">class b</div> -<div class="b">class b<div class="c">class c</div></div> -<div class="a">class a<div class="d">class d</div></div> -<div class="extend">class extend<div class="c">class c</div></div> -</body> -</html> \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/cleancss.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/cleancss.css deleted file mode 100644 index 2a6eb0de..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/cleancss.css +++ /dev/null @@ -1 +0,0 @@ -body{color:#fff} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/cleancssReport.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/cleancssReport.css deleted file mode 100644 index 4a152bd5..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/cleancssReport.css +++ /dev/null @@ -1 +0,0 @@ -body{color:#fff}#header{background:#fff}#footer{color:#377;background:#233} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/compress.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/compress.css deleted file mode 100644 index 2a6eb0de..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/compress.css +++ /dev/null @@ -1 +0,0 @@ -body{color:#fff} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/concat.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/concat.css deleted file mode 100644 index a1f1d2a7..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/concat.css +++ /dev/null @@ -1,12 +0,0 @@ -body { - color: #ffffff; -} - -#header { - background: #ffffff; -} - -#footer { - color: #377; - background: #233; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/customFunctions.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/customFunctions.css deleted file mode 100644 index cd988254..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/customFunctions.css +++ /dev/null @@ -1,5 +0,0 @@ -.myRule { - background-color: red; - width: 5px; - background: "Hello"; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/ieCompatFalse.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/ieCompatFalse.css deleted file mode 100644 index 6dfad771..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/ieCompatFalse.css +++ /dev/null @@ -1,5 +0,0 @@ -body { - width: 288px; - height: 288px; - background: transparent url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAAwADAAD/7RtYUGhvdG9zaG9wIDMuMAA4QklNBCUAAAAAABAAAAAAAAAAAAAAAAAAAAAAOEJJTQPtAAAAAAAQAAMAAAABAAEAAwAAAAEAAThCSU0EJgAAAAAADgAAAAAAAAAAAAA/gAAAOEJJTQQNAAAAAAAEAAAAHjhCSU0EGQAAAAAABAAAAB44QklNA/MAAAAAAAkAAAAAAAAAAAEAOEJJTQQKAAAAAAABAAA4QklNJxAAAAAAAAoAAQAAAAAAAAACOEJJTQP1AAAAAABIAC9mZgABAGxmZgAGAAAAAAABAC9mZgABAKGZmgAGAAAAAAABADIAAAABAFoAAAAGAAAAAAABADUAAAABAC0AAAAGAAAAAAABOEJJTQP4AAAAAABwAAD/////////////////////////////A+gAAAAA/////////////////////////////wPoAAAAAP////////////////////////////8D6AAAAAD/////////////////////////////A+gAADhCSU0ECAAAAAAAEAAAAAEAAAJAAAACQAAAAAA4QklNBB4AAAAAAAQAAAAAOEJJTQQaAAAAAANlAAAABgAAAAAAAAAAAAACKAAABAAAAAAYAEgAYQBwAHAAeQAtAEcAaQBsAG0AbwByAGUALQBCAG8AYgAtAEIAYQByAGsAZQByAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAQAAAACKAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAABAAAAABAAAAAAAAbnVsbAAAAAIAAAAGYm91bmRzT2JqYwAAAAEAAAAAAABSY3QxAAAABAAAAABUb3AgbG9uZwAAAAAAAAAATGVmdGxvbmcAAAAAAAAAAEJ0b21sb25nAAACKAAAAABSZ2h0bG9uZwAABAAAAAAGc2xpY2VzVmxMcwAAAAFPYmpjAAAAAQAAAAAABXNsaWNlAAAAEgAAAAdzbGljZUlEbG9uZwAAAAAAAAAHZ3JvdXBJRGxvbmcAAAAAAAAABm9yaWdpbmVudW0AAAAMRVNsaWNlT3JpZ2luAAAADWF1dG9HZW5lcmF0ZWQAAAAAVHlwZWVudW0AAAAKRVNsaWNlVHlwZQAAAABJbWcgAAAA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MjoxMi0wNDowMDwveGFwOk1vZGlmeURhdGU+CiAgICAgICAgIDx4YXA6TWV0YWRhdGFEYXRlPjIwMTAtMDYtMTVUMDg6MzI6MTItMDQ6MDA8L3hhcDpNZXRhZGF0YURhdGU+CiAgICAgICAgIDx4YXA6Q3JlYXRvclRvb2w+QWRvYmUgUGhvdG9zaG9wIENTMiBXaW5kb3dzPC94YXA6Q3JlYXRvclRvb2w+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL2pwZWc8L2RjOmZvcm1hdD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyI+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDxwaG90b3Nob3A6SGlzdG9yeS8+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjMwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj4zMDAwMC8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6TmF0aXZlRGlnZXN0PjI1NiwyNTcsMjU4LDI1OSwyNjIsMjc0LDI3NywyODQsNTMwLDUzMSwyODIsMjgzLDI5NiwzMDEsMzE4LDMxOSw1MjksNTMyLDMwNiwyNzAsMjcxLDI3MiwzMDUsMzE1LDMzNDMyOzE1QjRFQUJBOEQ5RTYyMDlCRDJDMjU5REVDODdDOTdDPC90aWZmOk5hdGl2ZURpZ2VzdD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjEwMjQ8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NTUyPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT4tMTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpOYXRpdmVEaWdlc3Q+MzY4NjQsNDA5NjAsNDA5NjEsMzcxMjEsMzcxMjIsNDA5NjIsNDA5NjMsMzc1MTAsNDA5NjQsMzY4NjcsMzY4NjgsMzM0MzQsMzM0MzcsMzQ4NTAsMzQ4NTIsMzQ4NTUsMzQ4NTYsMzczNzcsMzczNzgsMzczNzksMzczODAsMzczODEsMzczODIsMzczODMsMzczODQsMzczODUsMzczODYsMzczOTYsNDE0ODMsNDE0ODQsNDE0ODYsNDE0ODcsNDE0ODgsNDE0OTIsNDE0OTMsNDE0OTUsNDE3MjgsNDE3MjksNDE3MzAsNDE5ODUsNDE5ODYsNDE5ODcsNDE5ODgsNDE5ODksNDE5OTAsNDE5OTEsNDE5OTIsNDE5OTMsNDE5OTQsNDE5OTUsNDE5OTYsNDIwMTYsMCwyLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDIwLDIyLDIzLDI0LDI1LDI2LDI3LDI4LDMwOzgzQkQxRDlGMkU2OURFM0E4OTMwNUQ2QkM4Q0I1RkI5PC9leGlmOk5hdGl2ZURpZ2VzdD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz7/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAEgASADASIAAhEBAxEB/8QAHQAAAgMBAQEBAQAAAAAAAAAABQYDBAcIAgEACf/EAEQQAAIBAwMCBAUCBAMHAgQHAAECAwQFEQASIQYxEyJBUQcUMmFxI4EVQlKRCKGxFiQzYnLB0UPhCWOS8BclNESCsvH/xAAbAQACAwEBAQAAAAAAAAAAAAADBAIFBgEHAP/EADMRAAIBAwMCAwYGAwEBAQAAAAECAwAEEQUSITFBEyJRBjJhcZHwFIGhscHRFeHxI0Ki/9oADAMBAAIRAxEAPwDg+HpmsttZC1LJNUxywCc1m53jVCcHbxndnjbqxVGop6iCopoKWoqbbGEnjDFWi3knxAB3U5we2D316la/UlJT76uSveFg/MhWNSVyMDsOexxydCZquoWorrpSK1PVU9OMTRnDlmYLtyPqzk5Ht31kUPjPu61n0YlvWmC23GjtlzoLvVUdNV1FPkxbociLjIbB43A847arW671FbJPBcY/BnaZquGqpwVYOSSHXHCtnv7jQ2noa+ojjvFK1JRpLHioSWcIqENyFB5Pvge+vEtxpxTinhqVM0sjs52nOwDCgHt7k6j4R91Tk/tUZPEHJ6Uejlj+Tkp5ZEV6pzJVGIeH45wUDMMduc8fc6i6gNXXV9A8kbJOtDT022BQ+TGhBwO5yMc6AWdrnc7hRUyiNoGnEdTJgbggBZjkdsKMnRq43egujxV1JC1GZlIiYDayBDtVge/p9tcaN4jyc/xUlTaAxNDB83FSxxR18VPNO/mDKS8gAyFGP7c451cr4ZbWD48U0gkpRVpNIdokXIz25BByCNW2mqLtAZK4TCbYn65UBWwcqcLg5785OisqLcqdulrfWSSXBIPnIHckoxbiVSxPHHI+418rqx2Y5pk7fCA61VEFJLPUzTCUQzPHJMUXflU820KO+QRyPvr1eLbUXKjKtdaKletkyzwoeEQZjXaBlRn009dJfA7rrqi4RC326oWipQitJKNiSAx4BDDk/fGtMsv+ETq6cQrcbxaoZYpS/hxzu+4/82BxwO2ixW1wzDb0zS653YPSudZKezrPPQUtckqTlVAYGFVnCgp3JyuSc/nRTpfo7ren6kQTQh6JGjmbey+EmASYuMDJzwfUa7Dtv+Drpuaohkr68k95Y1CLETnJ8h5J+/GtNtXwT6LsTJE9hSppkHA8FDH+4Hc/cnVgmmPzuxg0QDHSuEpfhDe7jQRUcVOFYxGL9PJJwWJJZRgjDYAOp7f8I+trLSU/zdlQRw0/6cdO4y7g8BgcE8dyBzr+hVwtliSlWjorVSU3hrtQCABT+McftrP710/RSOTPSwygdtg4H3xyD/bUpdOQKFyTRI13cGuHaua90Uv8OvNmnoFBy1RDAqBTuB2lT9QwMnGP30PvlV1JUXmrS3RQS2KWd5IJqREUFm+kk4zyCQTjOuzrl0N0z1NSyW+6UMFUCCPMP1FH/KT2H2B1h/xF+Edf0jKL/YWeS0QndNSrArgKFIxsxkgd/fOkJrQjzIM/CiNGAOKxS4TQRUsVBR0BgRyqylB4rllPlVQOePXHJ1CkFI8gtqRVsKR08ks1S8I8NectvU/QR6c5OcaumSai/wB+tlJX1NPDE5kqJ6cLFEj+oCndxjndjHrqlPU1QhGRCtK7Cepqt5/WBH0uDjyj2XuTnSIDD3xXREAuT1r1dTBQ1Zg6dd46e3RhlbeP1NyZJZjnk583sOBpfkS50dR/EhcfkqhnH6RYtAQRgrnnPHIHrry1a1NV1C2pX2l18Mbd77T6H+oHtj20w1FdS2OwT3ZHghkl8ItbZ2R/MMhgFOcD1BHPvo670bjnP1pbf4b8CqfTsdJf7nTQ0dFmeUMZRIgjp3jA88uwc8Ac8/jVC7Vl0a40ksVVbkEM2ymKRtGu1e3lIxtI4x30Q+beugs9bbrxV0r19LNI0cjDiVZMBSWIG0L2ORnVWtpagUS1bGF54GWNBFUKr1Oc7izcrkHuFz6aJjEmfv8Aquv4m7noainpbTFWR9RU0ci0ZmaPwaUCXw5ynO0HCgEZ5PqMa/Xm3UsNChokWOMTyU7vVTGSZ12hlKqBtUkHkempZaWWO3+K9hkjjkkSRAZDtCHgEnA3DOfN2GrsYFvpoqlKaiigSpjdaSaXxNzAcsu8EMpx7nkeuvjMeKA4IbFAKH4a/JUjX16qcqNwjaRBDCzjsqs3mkJ7eVcffRmzUlxmslTb5a+ekiZyZKenK5ZyvducqPQeuo63qSkvTw3daaoeOleRqmGoqxK0uRnyYUBABxwMDtoWiR10b3KxVj0aVkLSSRMviFsfUgDd9uAdTkaWQf8Aoenw6VPc5O5qvK1ZK8tPTvNHPQSLTxU2AGLYyc5yDuHf1178Smr6I0tVviqY2LVBNRjIJ5EZbkH2GcHQyx3Cip6c21YTI9USJ5ZQTvkf6GjlH04IBwfY50UNDGK2jnoTCstDcfl6nxoi4diBnewOGjPOAAMZ1Bk2tjp8cfv8DU8Mp4715oIVorlF0/GS9MtQlVBUrCVkkDLghmHGMcHOi/8AtU9jgWzWehg3Ty/7xIsK7cAcD/mIHvwPbPOhJqbbW3x2tsk9qtNsdp9lRJumdycEZz6twvoBqN7lLJTm8tb6ekqUV4KdAcyTynglweTgeuoSIzsC3PH6/fpQXQg4q8LhV05qaqpZWMqNEd6nKk4wD6MBj0451BcLrb5JdxqZY5nKoQgXapxyoPA/76DpUXGdY1u5qw8SD9GWPACk8bf39dGXlWenmp0MKxpEs0SysMF88rzxk+nHpoTQhGwR9KnGpUFjU9PcpaWhY1VG00UjCGWGRYpZJoT9IKA9gRyw51Vo7fYPkjd7W1Xbwsxie3oQzEsO8bnnd64Ov136fjcRVazTgTxLURvH3jYn/huOwzjgg4+w1Wst8lt9S9JVU9Q5JKuxjWTlhgHjhl+3cHsRoirhCYz8SPviuBST6Ci1krrdS0LUYrIa+PJZPnKMIRz2b1zpipeorfMUpL1C7RTbkSaOUBVcrhSM9yOw9PT76Uq6hiSteoq1MTBVDYjDLJGeFliPqPQ+qnvrzDcqOlma30EKRoEBiEg8RvuRwTzzz76Vlh8Q7uSevy+/lXwfYc4pisclDNbauipK7fNXQFlZlVSnh5KpkHGSc4I0jXa9VtHWUYqIYBUIgKwGANIWY993oD9/XUc9UbPTw0coZ7hKyDw4MMY9pJXtwSc9tMt7hrJrZA9y6gpZ6enUzxyH9RaJ3GEpt5GWkByWRSQvGnYYdjbiMg/f0r6PKtuxxSxdZ4sQtdbdIFpkkaWKNySk78eYk+nHbudQPd4aW2Q3C321FlX9RN6rJ/ysCGB7HupGOc69wyS1IqYbTbmmjdXDVU4DvM6YJ2oTtBwScDJ++r0NQtW8pFvxOi7Y5ahPDIyMMQq9+ONNsBEBkZx8aYJ8uCKvzdSVo6caruFfRGveDbF8iiAwRkAYdUAVc45HONXenrRPeKZbrcKSXwYqYQIYkJkmYncAqdu559hydRUnT1ue2RmGzNUVNTLHIiozI0MRGHDemOOM8c66b+EPwkstVVxXGW9TAtAoFJNUAyRQ9wGQHC++fX7jQ4YkumIj4yfp8KH5TktWXdF/An4g9XUBaC0tRAyqrSTqVAiHIYhsAEH34Ot36E/w12axVNJV3y5/xiqpDuWMQIkKMTklz3c+3YDW+Wbp+x0duWC2yVFSSNpdvMPxuOpJLeKaMKlLvBO0og7fnPfVmlhFBhgMn1qUZ7dqHw0lvpJQnzDoFUKImBWNf/p4A+2jVP8AKoVEFVTThuR4NQEYn7A8H++dVVp4UG5ItzEljHgkH+2oZZLc4MUmxXbtHG3mXHr20XftOadS38QZNGfnaXZvZpXZe8cudw/fnI1EnUcKbxSmWDdxjYcD9vbQSmalhm8tCzwqNplaoby//wAsgf20Du/X9joHMLrAQcgM82M/2OTqJvAg5NNxac0nCjNNdRfSQUmpZKgZ/U+XwGx77TwdLF3FpqyWpK+endgSFYlSPyCcH9joAOtrBcW8GQo0RPLwhsr+CpDDGht4pmqJfEt9waogceR5CCR/0uMH9mGl3vlYdadi0iReCpFeausqKCUCWYzKG+rs3HqD6/jVkX2KrpmiYpIGG1Wdchx/QwP50nNUXGlqHgqkIO4b0I4I/qGvMlS9NKxAxEy5H/VnSRvEDZpt9HcrwM1m3xF+GFwSoWu6Wq9tsy2+3xuVMTZyRjs4J9D31kF06fv89OKP5GqZ596vHFGmwr3A5xtYe5xxrp/516itmp48SR1HldACD+QfzpQ6o6PutdBNTfMFoVcRsJXZmK8YBweTkkDPpqZRJhuUc1nL20aBsNxXPa0ZShNvpL5RxvGjB40XxpXl/pDR/Se4wDj7aKS2i3Wimli6hoVSljjgmrGZiU3sMxRIvo3q2T/bX65UFX0pcbjbLoRZ6CkmMcBhp1Eg3eoTuWI9c6qSF6+iqaatKmgSWKFEjpztwMtvJY5Zz/MTn+2k5Mo5zwKQcbjt7V6vjUl1paGW30L1CORGk9LUiSCBV4KeEOcFfU9tRtsiolkppzU+LIy0iywb6csvGSQctjsDgc9ydeKaooLN4kzQlDJzAqOu0BucjA2jj2BP30Oq5K0UkV5hpbf8lRPtjIf5maJmYkfUcgls58uooNx2joP1piMkDHai9JXVcs0wrXo6WrnjWPxKtGC+Tk4weAPbHPpqKppunKemhoKqnapkZDPAYJt0B3HBWMsdwB7nnAPbUkVDfb+JIK+njd5AsvmTYYXx9EmONrDlSRz+dTWfpqhUzxx2JopqeETRTtHJKsfPnZFbH9ucemuqdgIJx8qVkHPFe5OlacW+kvNqtVVUyR4hlpCMywqxIJYJxsPpxn30DlsFdbOnaeKagqYKthM1vpFQ+OzmXvkgYVR/N66OU4vVDUGlmmKU8u5gsROyQDszFcEkf0nnU7f7QXaqikpKKouEc03y1S8sgjc05XBba2PDX/lHoOdcjdmbHbr1qKkv0PApUo7/AHK2257PVRUEs880RTYoYI8WSd+AVJOfuPvojWSxOgq0kkWYRiOtpg5ZkQnylWxhsHnBGR+NC6npaitdVP8AwfqBgqS+HJCYHEIAzu8x7ZGOBoxLV9PWeAy3ClqVeXGxY15k442knOcep4x6alOUYjwxkn4UdxGThTXq02ppvn0pmjWSKFPEVgrFs9l3HA74OpquvSkqXt9dTQTUlrjE0k8irKGnK42Kw7HP9saXpb5DVXpYpI/9zNMfACrgxqOcnH1HjknVa61kgtyK9NlHqCwXbtWQ4y2SO+FwM6gkDbxu70oFIbBptqYLVEKCohSVWZQKVEYS08+/6nb1UrnAHIzpbuXST09ZlQS8LtJTvFMAWGfNFKO6tnlfzjRm1RtaoI7bOsKV4j3LTNJ5Y1PKq7H2ByQNT5eop6ymiCAvGxWbwvEaQH649/8AKD3Un11FZnhfCninIX2nB6VWS73SmkhkoaWNNihHScLHKwI8ylc+Yfcj76I1rx3WjhW31M8ENQ6skcKLK9PLnbh34/TI5Dc/toPUUVXSYpZKed6806yqp5kK44jJJ7gf66it9X1FeIZIOl7jSUFTDMQtLu2mYhfMp4wSfQevOuCEOcqB8/vP7V9NEBhR09aN2a2dQUDLA1Ga+F2ZyFKyCR93KMDyrkAkqPTnVz5Wnt1K1/prSoiORK4kDLGCTtDg4YKPb1PfjS3V9a1lBI1Y9WTUq6NEFXYISB58n1O7t6gcZ0YNLNUW2pu06KJ5vM8cdUMneMhtpHAYcjuNDmifO/sf1oRfwTwM1SoaSr6bjIaOilepZYts7RgBn+nyqS2fyRqO4U8tVOJbvKGgog0UK09aqlmI8zJGBgnP47aArSNZaZLpcZ5GqkjBghD7VXvtLH+UDP5PPbXyyWqou/zM9VMskrU+yjpkU7EyQd27soHOPf3zp9I85dW/P+q+TA909PvivlJb6qpunzVJVK9NRwvK8SjY1PGAByh/mYkZb1Or1BXqKmO5SRTy1E84SJvDKiFOR65/Yfk6tW+90kN2qYqel+dho6OodpHRY95UDAOMHbu9OTo70NT22/X5aq4WsUlMojkEMU74MrLkL5iWbjJ9vTU3LSYDDtipSbgQD1NPHwm6Drr7TZrrXXba0DxJEcIBGG+ncc9z7a6u6Osli6doIbZbrfT00SfVHHgNIw9XI8zn8nWV2C5xIqU8K09FT0yhYoYyMgAfzH/t206WOsldFlhlSnUnAlIyze4UDk/n/PVjaIIOBRkgwuDWtrdIqOEPOAkMYLYlYIoPsfYfbSP1L8RZi8sVtqaWJVP1oPG5/BxqCrvlvo40jlo6m5VUnCRuxyPuETt+Sc6Teo6+repEVyt8NKGOQscp8VR7cf6aPNNgVZWVmJSABmjlD1vcK+T5QV85QEeIVwpYjv24Ua81nW1RvNNQrCsYGAgOS7e7HHOlKgmyssNFR+FHKDvfdkt+dErLaTWzSHbkg5z+NZy6uyDha3Njo6KAZBUdcvUN3/WudwqHjJO2KIbVH/j86IW7oFJ4xM8Q3yEE5yc/nPfTHSWqlt4EkhZg2CAvmdv29Bpmt1whZFaKRYFxgqiAkfcs3bVUZmY5JrRRRRx8IBSp/wDhrH4avIQzMRgDChfxjUUnRtbSDZH4sQVtxAfg6dzXUiT+HEs9X/W0X8v5OMf21JG0VQhVYDljnznJA9tQLE96cVVbnFJEvSniqklS7578NkH8nVOoschzEkSsmMANj/LTjW0ar4jbiozgrnI7fbQI/LxMyOjnBxknH9tCMhziu+BH6UnVVHNaphURwYIPORxx9x216S4Wu/yJCKUMfGVSi5BVvz/MT6nR+7UtMIHZopiAOFTJDfvpJqbtJZbpDcKAyQTxHOJYchh6g8eun7G/eF+elZ3WdAS/jyvDDpQr49fDFb1bqi5W8/L1NLF4jyIBk+GMgYx+2dc6VNPGw8SenhWnB8WHAwjNnMg4PDkcgZHHA12obzQ3u2fxCKTKzxmN4/E8y5HKD751zB190lHZq+ouVHWfLGRpah2BDQgR4VCVxjPJH2Hvq8uts8Yljryu5tZLVzFIOQaVJ6+0Gho6yos0FRa2d465YUPiwS/yYII2qy+hHfX21W3pu2JHHXwwLRVtRJFCI5tzDP0y8nG4HHBx/npeper7bEaqtmpaNRVSGOu2RsVdOyhkP35B40RpDaWtcVvWvpZ0qWeeFHhaFRHnGAy5KsD30k+5Vxgj7++tLoG5JHBr7a7bTWaWqmpLzFdp3fwK611zmnmqwf8A02ByMrwVKkHPOBqtVWy+Wa6mGyXaVqKYPPErzkzQv2eF+fqGdp9GHI1avFjt1xp/nBSvCYo1RqiKcyI7+hcryDjjJGoFtlFDGpq6ipeKBt0c3zikI+OBsH1c+rAY0QSA8M31H2KiwIIFXaO3UdJLHXD+H081RiNo6moZUB/nLdy3PAAA++mI2ipFBUS20VKq58Umnn3eK+3AjBZsqPXgaBw0sN5pfkLzU+NLTt4qtJGFMsbd8jkHn+YZGvidGV1HdQY2paKgjVXFMHKvjOQcgebPuNBfGME4NQdAOCagrrxcY6b+DWmzhKWOPFcHfdJ4p5LqzDkDtgjnVOK2G7W6WolrII/lv94ieGLeykcNGiE+o54OM6ln6gvUFB8lS1cN2dp45WppCZTEC54DgBgMcHODqFmpq24U1fYrjHb6mjmO63LMJYhJ2Y+5yO3JI10ArjPAHfr9an5kGOlLF0okSumrLO8m6ljhiETcvyeQSMfvx66Km5WmC9WqG70FSaa37HMfcTtnLt7Y7D3wNMlP0XdLhHNU0NPBVtUN4maJkMi7D2ZScnk84GkJLDWJVR2q6QSPKsrmN1BGATlsn7HuODzo0ciTDDHoPz6UNfMOT0pkqpgbzIaymgqaI+JLTTEAtEzHP3zHo/03UdRVFNilloqWNQyvNHGixyD3OeQONL1FZKuMFKKpleJm2+E2P0iRngnupwcffValt1TU1W6xVr1McuWeJnK8DhgUyRuHoQANKsqyLtyOO+P39K6xTbwcGm3bbK2siqLzc7dS/wANkEu+nqfEqWG0lz4agggnsM9tAqinobZVVN56dM1WGnEKR4xJA7LnxGPqCD5cffJ41HUUF6eWtnp7dStLRRidT8oElmiUhXjfvyoIP39DquaBrxTx1dLUGjaWJYjTqWAcqcqQecfbnnRECxjk8dKK0hIAz0qRXp4R/vlwVokw0lO1CJN3vuLcgk8caLSXW501whuXSNnp7jRVFLmaolTIpBu2lcnAG3HHBPOht0pa2khhN5qY4ZpszwOzZlSNfKokIzxuzj115uCzz00TvP8AxBYnCwmGUiJJBg5PPm79iONcAUEHr+38fvQQdvvcivNQ92qJXeSSoioYXEiRsgZGwOcpjPAyM451Wr7r1LFcKQpUv8gzElGiAyEGTjcPMMYA/sNFYq++W7xUmiqKijVgFxGS0p9semfv20Nqbg71NRVpbXjjjQosM6Bmhwc4JPqSedTjJDcAEYqe/wALhQDipBW200tTPLYIWllhCyGOIQsodslS0fG7A5449dE7TNWR9R2ujshYPPVeMqK2ZSuNu3fgDgfb07aF0FdWC2TfMwSVHzRRpCvESxq/nTd/Lk4z6kDA01dCVPjX2SsrIQrlVhgC8bNz87f2A1MFmkGfvpQ0bfIDW69HWdoFghlU1UuMx7l35b1bB9ufM37a0i3ukIMalpWxhjApfn2Hv/fSZ03S1LQjwoiYSccnmUjvuP8ASPbWndNdP19SvjIfBhjGMhQpI9BnsB/nq/RcngVa5VeTUPy9xWEuha3ROwBEbL48h9QWH0/jQG8Wyc5CRMB5t28ZAH/fWm09kERM008skgBO+RMhR/SgHCj78k6pXey1dbHJVrTmGAjCeJxuA7hV9F+50lqEZVeDV/o8qBxmstp4Vp6WQIFPIXGcDOitqrKK2kvVKvh92Ib6mPZRofU0ssNVKspHhl8k5yAfTXunrIXmM8iR9vCiAGVjP9WNZLJPWvRFG8AjpTRFcd+7wmglllUMqK2MD0B98avJVW+QxuXmrJMgPEANob7+ml6F6ZXaUlBEp5k24LN66JUKXCvmAgkW30Td225dx9v6fydRo6pgZpyhp56hFaSGKOE8CJJeftzxqH5GGCUqIecnvISdC6KGOgIcUEtSQeJJHzn++rlXVyThXRXTBzgDjUSOKcQDNTfLRqxEe3J+oE5zqldLXSxMtUQQ2MYHIOdWqN95Mj4BwAxPB17uAD0TFWJwcEdwdDKgUaRBtyKWq2pDU3y+4YQeUn0GlHqECOkWOijWWqk7tITtA99PM9AHplqljAVvK3GcaBXKgWOnkWRDxwCB/bQtwDYrkiErkUjUJr+nq+OS7y0xpqk4bw1K4z649SPfQr4hW+2XApSylHg24EezyFGPr754OhXW9wq6i5IBM5jjYoqE5BI9j76q3WSsuVpiuNFKqvBGI2DnBYe2daawMkabW6GvM/aG3iut0sXvL1rnq90s/iXOgSipXUeRhImHqo0bG9WwCzg4++NLtPbLvTz0lyrZ1RaWpEqgEjEfq/HtjGn1Xo1aZLnXyU9wgrSaZGBbw3Yc855BH/ntoTT3qSeolsp8B5acCFauOAo0C796uytlSc5H3B++mEldMhRx3rEK7KCpr1ZhW061c1pmL0t0LYmjIllgLZILRgg7cZ/b+2pLdRXGjrxUR3q11kHhmCSTY4zkcrtP1k+3cHVime0dQzU70cMHztt3JW0kP6aPCzcTLgg8McMB2BB7aoW6mmW6T01pqpxCd/i0lUBJG4B5aM/1D07HGhFjyD1x3H3/AFQRI/Izx8qZL1K9umjoOmt8Vvp1WVKOJd4MrAEtlvNuHqAeNV7pdbjHZKKrpZammNyq3kikWbfDHUxYViyDzIpJ/H5GvMtHckpqOS2WwyLIkklSzTZCxA4RRjJLevf7aoVdnnqXAtlfHHtTdJFNCVDn13OpDLke49NAXlgX+/nXUG4gE5/f86OTWuuWlkhu8kNJUTJsqKa3umyomYbkkTAzn3Vjj1Gg8lBc56ZKS3WlLfTPHmWppYwJHxwWdzy2T3UYwdXbNVzV91SiudBRFRUrM1UKliAqqAr8fz44A9TjRGpltFzNZS01uuVA8Ux8Mbj+mv8AU6Nxk8k7T31FnZXJHX4dP3rtxDJD5h0odF0tU/JN8pXRH5WPxFLHDwZ7phfNgnkeoOvT2ZLtQzwCepqhNHzEZds7yggBueTjBwT7c6oJSyVLRSUtNMJKd96yOxZahVzuVkznJHtqxVUtMLZQNdVqo4ztRK2lzleSykkZLEDjB540MsWIIbnNLLll4PNQ/KXOqqI4aeOWGudysgkcqxQDadwHByBnPuNeqClpal0nNohjd3DvNUVDx+OI8oUbONrEHt/Nxo5dLrXW6hpaGkuLQ3GrkG2sWLmGI/RiN+ee7EaEx2ukWztQwzrXVLkzTyyxvIRKeDjPHOO3fXQ4C5JwT86MgEoLEc0RuEd1NJMaahelMHh00NSsrn5imZclWPPtjJOQQNDYKB6aho5KKkZZZV8R6iVRup1JwMA98gZ5zj017/2iu8FH+qnycYcLsjTbkBfb/wA6jvApqC9xPd6uoa21gVqZBktGu0ZyBhuM59OOc6FGHJ2j/v31oW3z5AonFDZrzbqqu6kkZRgRzxSTeHHUoDxsY4IZR5jjg9hpJtNkiprvJRU/VERRKldrU5Phtu+hFZuGYjHB++dEblaRe0nqo7XJsRcOPGILAHAZT2IIwdXrb03S2yWCnnEE5rRHUz0aoRs2A+GAcYBPBJ4++nIXREZS3J7feaKEYDDmhzXBuoal5aqG6GqpoxGZEmEIrFU8bmxwwH83cjvzqlUPH/DENHYaisLMUlemifxJWBz9bKSVGe4xk86N1F5r6hPEnqIa23wuPElVyiRk9w8YXcG+5GD6HVGTqCy1xehprhfbbNyqz0yGVTnsGVX3A+3f8aIhYkDbx8/3oPU4xUlbDWVFHRUL9PiFaaHbMKysmMMSscgDkZb3wANWukZBD1HSJCaeoLSBZTTsZ2VQeMsMKoHv6ffUMPS9JfqGNFkuVPcYd3iyVC7jVKefKGbAf12Z59PbSzb6BbfUTXkCeJqeZEVmVgF82N3HBHB47c6OgQkhj9/WiRquc/Gu3umJo6SKnePbLKQFCschB9h6t99bV0yzPEnzCqCBuTcCwU++B3OsL6Aqqev+Xrsq8RRWUdgQQP8AxrY7BepZ5RBKioCcBVwCB6DV3CwBpuU54FPUtNH4aNPUsp7tjl3PsAOF0OuppLlTmng87FSqqEyFx35P1fntqOvrYxTARNvcKRgKf751Sjkgt1IUExaaWM7t2cnAycnX12uVzT9g23BzWddQ2SISuFmBdOAqNlcnvnGliaVoV8BQoIbbkLjGjz9QVUtwWOIEROSZGYcgn014uVFFPKGiQK0mMsT6jWKnUI5r1XT9xhHFVYatE2iZ96xfQvux9ceujEfVtLTIzVEvh01ONrsBku3/ALaAz0b0s3jjcBCju3r5scf56U7tM5pRQRSNK3/Ede5LHk50FELtimpJxGpOKeLl8YrTSRinoUYSKfrkICsPwdfbd8ZLRMrJPRyht2ACu3J+2skj6UrLzWGeqplkJOAjSMoHtjGmyx9CtAvhywiBAMlWG4Z9wcaf8GBFw3Jqqa8uXfy8CtSpOpqav2mnhIEy7imDkfjRe2VJqjNTM3DLuXI741mau9tQwQggpyMMTyPbR7p7qIsyPKDv7Eaq5gAfLWgs53KYanqBIEiMDp3UupU8ZHfWddW3YQ1myKYkrwR9j76PVV4UTGZCRgEDBxrNeoK+OKocyNuZ3JHPcnQ449zUS5fanXrQOtt1XdNwLLGvndnGOx78emhc1sqKKlkhVy0EqkKQPpbHb8auXS7SmEUluqoo1UkSyMhkLH2VV5P3PbVKK+LUQtReMkssQ8xCkBvvg9vxq8TxkVXPSslNb27o658zVhF/oryvV4mpolqooHDyMZGOwngKw7KPxqP5Hp293KnimChZ1DKYHK+AIhk5yfMBg4z/AJav1D0VXW3CWO4xVEscgaak3mIx4Y+feeXXI7DjOvFDVmC2XWoqrfD8sakUMU8NNvkbchdwcemMZJ450aRnbzDggdq8unLLMe2KprarVT1dRV2WvqzUXCQLAslN4IhjIJcHBP1AHGCcjQ+Np/Bjq6OCWCiDkR/LS+G6qv1E55PPPpo9S2unrqe2U9qucAekLSxRuxSfeVI2hDwwHfynj20ASmvVLTTV9XVJcKCAqmwYCqwbAGR/wy2Tz68jXysHPJ5+P0oDnxODTo61dNZKasnqnjpSsbw3CHG5FY+ZJkPDrnnOR++paq41aUiNcbVRViSAFZqZo0MzAcDdkYBHPPI9joJYb9VTWK70iQ0iUi2pRAJn3YMUw3qxHIOGyD6DX3piU01iuxo6KIKamKWWCXLUzgkoVQnJznB4ORnOlmiZQSemfvPNDC+Gdwq/JNb7Yxq6u2zvDWSxmWOnAqZUIHlBYZVR98c6v09wp2kpntNHXNTV8hiElVnxEBGAzjOT5sAE8c6+pcxU0cULUdJHBMslO0cgwUxw0ZPG4Lx3IPOQTqjUR0NttottjVFQT7SCheSmOOTknhSed/c9joBcHgg5H0xRd/iJ5q/R3igR5XeCshr4GEUsTSiREqBk5QoOBkfbv66v0MjS22SsMtElLUqsj0sleElOWy+xVOfcaWPEFRU1EF5WVpFVqp3RAFqAOA64OM+h++v0IsiULPU2gPGGKwzABjnGVBH8w11oQDlR9P8AtCCBMYFfeqaOkr6+e+PUTOKthIm2oDqFHlVQMZUjHYHRSzz0c0NOsMRmjjkXdBKzoJiP6ZP6gP5WH99fKKso4USaoqFo0mTslCFVHB5Khc84x3wdWQLzMzVtNSG6UzRbYn5VJo/sMglhjIwMjXzszDB7dK62FIwK+X4UFfDcIhQNGYmZwgkYzIT78EccD0/bQqougut1ieWBZ5VpYYpzOMIJETb29jx6+mj1Hev4nCoudt2z8qJ59yMD2CuxUc/8x/canr2tNNSfwu40FapMe0TqwBZ8/wAmEG8HUFbYNpr4kYAxzS/RRXCeWtLTipmSPx2QhlBVGAyqj2Bzj2GdSdPq0dDdrt/tFNXOWiRMozfpmTLOqnkdsZ9hr1RUazV1ysVyMkJWJ1p2yWkkUjkBhg9uxxpk6Ir7TY+rrDSLQBbRHIlHVQOhEk8TqUdpHJySNwOBwPTUvF8LOOv8UeBS5A+NZVXxVFvuMbl4oapUUGpp6pXScHsjgjBdRwccH11BUS1lDUxw2pd0VWpk8KICMxsOGXKjnnt9jqKooelpLiLZQy3Sip4AD4daPFIftlNqggH14Opau3VAp/4fb7pBKqnar0pDTsxPKebBX/Q41eNjIz0+IoTHxGC/xV+vpbtSUSVlteOCjceHJvZpWWc4IzkkqwH0kcd8a92eKG63EUFtuJkqIwsjRSBXQgfWVUjBPrj9+dCVPgBrE1ezximRGkVMhyCTg+oGT3z3+2rtuqW/iCLSQV6VAhTwmyY9wPHiHGMjg/bQmX8/j/eaj0baecV0n8Neo55rHHUN4aNExRVXBG0Hy8a2SxXCC0Uy1k9QxeVt+AMsc98/nt+NcofDzqG4Lc2pKmZpY5lVYooR4gh2HvI44BPPHOtvtHUpetL1CbnQAEKeAcf9h/31YwSblB705GnidK2EdUTmF6l9xkfyxRufKo/b0HfQ+ovVRNQ1KvUOZTE0JY9y7f8Atj8aTG6qefIQo6bSxUD27AH01HHcMs6PUhd5/TTd2IXn88+ujTEuKs7ZNpAobeKmvo5kYTlZYgFcY+r3I1JS9TyTRgGU7xxz66uXyh+btCVgkVm3K0mP5VYY5/JGlD5ZYWJjIznt641mb2LY2K9J0ufx7cFeop/+fNRRzebLSIoJPr76H26xQ1VwjlZtviPgkHnj30PtdewSOIN9JIYe2j8d8jovAI8PjLZI5GkNpQ5FEkG44NMT9N09LE1TPGfCQ8MeP2++lHqD4jWa1N8rEZo5UG1UU7jk/Ydvxqr1Z8QZJKdbfS1khnqn8NSWwqA92/bTl8J/gRUdc0M19kutNZbDSKTUXCVQ1TU4+pl3cKo03Y2kt7JsHJr67ubfTYvFmOKyEda1VfWGF4KmOTJKb0KEj3GdGLP1YxqFp5lxIc4Ofqxpj6t6P+HRrp7X0T1VX3WsoiBPS1S7JSpbAkRj3GgTdAL4MtdSytHUQuQySnzbwccYOCDpq9sVtG2SVDT9SjvojPBnGcc0709te72X+K0jNvTOUz2GsympKyvvNRSSryrBQTk7M+uPXWu9CoaHxbdMwxMg2qfQ6odQWOltd3/iYTasnlY+n51UQypFJzVvOGnjr51d8SehPgp0fR9PdH2KCq6hnpfmKmvq6EzLMzHAiwOcf6ay+9B77TU/Vz2hLVV3hBUVFAiFTDg4OM/TnuNaNcqq9xU4NBV7kHKu4BKn899Kk9NU5mqayp+aqpxg4HC6vp9XWaAQ7elZqH2e8K4a7ZiSa5b64sFXbutKyr3bqWSVoZKmQkpCrjnO3sBx39e+rdBcK5bVRU7U4ZKNiauUSAiYuNvftgrjk6b/AI12OrtV8pbvS0k0kFyhEMyx8eHUIPLIp9DjjngjIOs+qaKTxI2o7hDRCZD4sSkNDUEDGdicDnuPTvjQd4miXmvPNdtZLO7ZTxnkVTpLJDb556qS41FIaS4qsUgc7IS/KuW/oHqccaKXeJ6avkqTUxiOpSP5lN6qJGPGfL9QJG4HHrr9051DQ3NU6Yu1wQuVMVDUTsPDLk48KbHJiPYMTlTj00HrY6iwV9Tb0iqSHglp6anmkH6NS7hRgjIIABIIONF2PI21jz+hqpiV3NNwrmtNOKm31sVRBUblDlDvj3x4VWI9QQRnQiw1dZY5klqXdae508uVEJO1seVymOPMPXnnOh9J1XLTSVSUNDAPAl8SCeVSXwMbgSOCAR2xwedHbRd1uFv/AImLnPQVVPuJMEaSGQn0fd27nzaVdHjyHGQak452rRKlr5q+2ijuYpI5yfHWU4HhkjD5Rff1yNEqjpilt9uiuIYWlZF2xOD40NSD6rGTux345Ghxu/8ABGpqiqdVqdoR6dYFLzFjkYbttZfXt+TqGvr7u1fUm5WastlW4zHJKJJYpEwWUKy5IGB6qcaXWJn5HSoopiJDVer1tDywTyTxyRKPrghXwg5+rykghSAMr3BGhs9koaRpahr7ItDNvqWDQCQnYM7VJ7E5wATr51Bc45K752xxP4NdFTVMlM0YZDE6+ZgQoIVSG8x5/wBNWOnqyknp6mKCplhDPgJMQybc8ZU4YrjkHXHR4hu7VBjt5Wh1nv1PWO1utyz0jyyAQtUuoEmeBkHAz+OPTUNTT9R3atlisdxkijpMxCMsV8Yg8sH7be5CjAAGi16tlmtlYtaimkqpI2SF3VYgwJ5dUG4tx6g5/GpK+/2CShqamyWupaWeBRMIanwVWQ8MVVk5BHmwCCM4Ouqynzwr19amhEh6c/GhVfXW2VaKKprHSfwxTNOSzGZs4O/0YH09eO+pae23GyikjuU8c9LVuTTRGNlWQD/5jDgn3U5BGvC1SmlYCuk3rAGSaNfMgj5CMmfK5GckEZA41FR/7RUqPWWrqJaySdFaakqiVjZG5STw3yPTHHtnOjLHlTk/X+PShkEHJ60SuFTU3epaW3vG06RbDTSRl5dq8kJLgZPv6/nXlKOtWCFbhVk0s0IaSFpVNVkncEjxxkgAZ1+slLcOpRNdaCoprTcYcuYkG2Kdh9XBOFbHOf341BVwzXuolqamnjguFrY/OLKAi7MAiU44Cj0YEjnQxHuOPSvozkkdqS1Sqrq56qnUQTQ/7u8rMQNoGFVSf5gOMavGa4LC6Q0UHiQqjhYUOydVOCCxyWH82Af7Y0dg8WooEpb9bkNxlRp2Eb7aepO3YHYr9RUfyqfudDUoGsk4lpHlMEEiOhL+KhGVB2n1UgkYH+WrJ3UnB7UQEYPPIoVclp6+UVMFNLDIQEqY2GUlj/qQ+pXH76juUtXW/pTqjRNt2VKOMSxYwqMByQOSMc+hzpirKNzRPSQwRPPS1jkr9DJCT/Ic4ZT6jQSoEFnjjmM6MlY0gipyp3rH9Ik28jk5IHpjOupKWPlqK449a9WUmgqrZUvVKot6y1khSTaz7SAMg9uPxreLJfYprStXBKdsoAklJ9ca5yuNSrQtGkK1EzJ4LOE+pc8DjueO3+mtA+HN7Siq1sdZNJM1UBLFTsQGRQM4x2JJ49dNRuFGTT1uW3gVq9L1VEa7wWnVfOAADz6AaOUPUC1E/imQFGOwZ9DyP9dA6HrbpqskFLcrJ4BBCqzRgqT+QODojHZaaQvPa9qo7byA2efTHtrgvkzhgRW4Hs+6puU5NO9qukF0t81qqnKiZCobt2OQP2PP76WZ0LExrIPERipbvqlQ3U06zRyu3jU5yuBz+P31SS8mprZWU4fduOQB30pfFJFyKsdGiltpCrjimaz+K6mN1MpUkZUYJ1NeIK/eJYaCUYXjPr9te7EUKiXDAnk4bAOmugjaaTZLK8hxwpPB/OqUybTyK0MkGTuWka0dPz3p97UEZmpnyBKSA3/+60a4dWx37oaq6Cuf8QsiSKscnyTjspzwCOx9dSUtpWmqxVRwEyKOY07aKvRW24MklTbiZBwzb9v9zo0N48LZjOKhLYxXY2zDIrObB0l09Y7vUXG1Vdxrq2dPD+ZqpQ5RT9QVRwB/prQ7N060dEZp4SA3mRfb76I26z24OGpokJz6KAo/86LPdaNlkp1Eh8JcM2PbXLu7e5O9zk0a2s4bVQkYwKQ6uSroLos0YyIxgYHbTj8vTdSWF4pAPHC4598aTbheIKm5fLQBm528D30y2Waps7R/MIRHIQckdhqsKseBVhtApJpqhrbVvbLkCCreU4xnX2qpqdS0kbjLHOSfXTd1/wBORXCmF3t4BkUhmUDv+NZ0LgVDw7iQhwQ3cHXWQkZFRhdVbY3Q1n/xmsUt86UuNCu4SrH48O1sHxE8wx+2dc89LwYnSolVHWjpJ66VAQSiY2Yz7ksPKffXUXUtSDEzSgAex5/bXP8AeZLF07VXS3hXhW4qqMgh8IgbtwxKT9GeeNWthIRGYyM1gPbqyV9k4HPI/alSXpu1UxjvjTVMqpL4ctOEBeI44znjH7aO25OnboUqJJS0aQrtBQjwNgOGIzhwfXGDxr9BfrDXViwVUqQOdy1M0rHEqIuQSOxf0HvwcapdOdQ1VfWmjhucFCkMv6UzoP0AfXZjknsc6dczOmWzx3Pp9K85MjFQrDGO9Epunf4dYbZcqZC1VFXkK8Y8WMleAox3DqwJ/wBNG4aOioY0vlpaKnilkdaim8sq0r48yEHkgHlSO41AiQxW5IKfc3gs8sU1K4KK7Agjwh9J/mOD6ftpVtdv6gprjNPK0gpapFU1UY8RGZDkGUHsSMg9joOfHUjcBjkVBWzkelNnzVzaaRbf1rFFNHiWGBCsLgN2A3DGPXkj7atU9Z1dBcfBud0roKUhI4p5pFkQO5wWOMjb9+3ONUZK2hqIP1ZKagR5C4qaKPMRXHlLoT7ZBxn8asSU/wDs10/Ui7KtTRyypGtPHXMEmgILM6gglPQgAc6XCgnHX8h/qhl1dhgVe6glp7XQUVkuVDItUkT0UgofNE0Xibo3Y5LZOW8uePbS5QUVnEFbU0tUitHMYIYk8RyP6mlDYIAHbHJ/bR+k6s6E6qipKiae5QzUqrTNLMM74V9XaPB3L2BIyQeedV6+8XbzyWe4R19FG7xwBKYLMpHIO8gkkD0OulGUtGBg/T+6PtXxMspArxYqWkgq/lJZZpkgXmQBEhhR84KkncSc/YZ17n6dtNoNbTmGup5pIAkbSlJA7sfKSwOTkff11RavtN6ojbLvSpNBNSuY5oX/AFElbnDcZJ4IOTgdwNCKuaooLcy0l0kmpTCoWGoJIGB5d/pz6MOeNdEeTjPJ7VwAcgUbk6eY0FypoLXSQtJHFVlgzIEljOHBUtkYU+nBB1TNirKWKrrKu4x1UVyKZK8mlKDPmIOV8vA9DohL1G1z6agIrGVYIEnkmZw7QcEZI7hW+nPI9xqnT1Zs9shu9suUAh2rJNM0YZwGOPC2fzBsEZ9e+j7pB5fyr7Y6jcaHSXqtSNb1bKKqE1DTrKojQmNVzhJSR3J9ccH31ahvtfPVC7xR0tvaWApU5lxGsh8xCA8GJucr9zqanvs/WNX/AAaKoang8wQKCgGMtvdvQjGMYx9tBKppK6Oejt1VUVzySBjG58IYYYK57bRjPcangZwRg/f5VNVG3kYNEaG9TXG6XC0Vcoo7gjuKGCGAtEdh/wCG+OMkchsdz351LDXR19QqtZdgJ3PAvEZkAwJEB+huTkdjoHIlVXGlqVWeNqpMGQuVD4O0nOB2wOM4OvQSnUvRWZTDWr5jJUq5yw/mDAbV5512QBj5eDQdwHGKtzmpUz0EkYBp1ILzKcKA30g+p9R76F11Ta1gSpnrIpoVkEbPID4kmeSEGM4Hbg+ui9ZOKhFpJ6qnrJaX9Y1EgIYk90UADy9ydxwPTGhtTJaKzfi31LrT4M0xzsg3NgFwoIUE4Gdw12ADPIz8q+jId8mp7ZSVVhqYq2ShqSHm3/L11MEQjI2sFbluD6akv16orX1JNebdToktLICmXGGO4EeGfRScgjGR7nXxEv8ATx1dsoIZampt8pecuxkWNT2wgyWHbt20tVMFVXePHNBM1XNIRh48F3JBOM9vc6ZRdzZejghCCDXRUNLQ3NKO8Um35Ws2ToeDgMOR98NkaMtdY+kqtJDIfCnwjRKmdx/q1mXwT6wkhpZ+g7jGnzFJM09IPqMjDzSx/jHIA9ta31TY6epvtE0IEdLMFeInkbCM6RumaNgh6fxXrei3Y1C3DjrQitrKGqusk1HVBkqE3L9iB21S+W8CQupYADI26N01gp6Ja6m8Fd5CTQTFeWCHkA+321SqZFcrIvKSeXO311HPYVaKPNk0Xtd28KnCI5k24PA7aaLTfJWkVhxjk86zuATU0u6mbIb6lPpovbap4pm3Hac575GlZYQeRTccmAA1bLaep4UAYplv5uONGoaqO5ttKAkf08Aaya33NVqA2QC64499Odp6gjp28MNg5yCOx0pgqeafjCsuR1p9tdO8cRTcEP8AUwxx7aHX2ampKKUU4VXYkk+pP/fVVbyhhJZsMfXPpofVMtUQHOQ5BBz3/GoljXwjyMmlGhvcVpq5p5vDR4iZJWb09dRJ/iS6MvUy2+nutI1VEShGdu78Z4P7al6o+Hct1ryomUUlYNlQpYgqPUjHfS5S/wCH7ouxJPLZ7aGmfIEk3nIH2z2/bTcMcbe+T+VKySup4p5uPxgolshhgiXxXPlA5BHt+NJNoDzCqqpTl6mQv/0/bQ2g6LaimxLN+lEx2xgYA0YI8ANEpCgH9tTeFEBCnrSXju7BiOlBL+zyKYdgPHc+msp+J1otVHan6kqrPLWywIKd1V2C+GfVwATjPtj862OdY69CwXzJkH86F3m0Cptc8KjcZInXtgcj1/fQ4GMDg/6oOpW66hAykdRXKclRL1PdI6ZKakg24IgjQQlEIxld5wW7HliTr1N07WwM1NEtRA8MQkZpYiPGO7ysp9Rj2Hp66lvdrqIknesRkSU7QqHDRyg44B7rjjvopSXJHtdEBJNNJBEwqJlbEiKnCKBnB4PYc60LSnYGjrxiUGJyvocGvtnrrpao5HentExtaK61UsUkM0aMc5SRGBYg4GCD3xo5V9Sx1cIaWAtcJJWkLwyFMjg+GyDgkA55HrofR2e4XWtgrZK2FU3+A71LKzzKy5xGDnt2Ax31FUfwS0RTVXyNQyo6r4k4MQLqw5UnzMe/fA+2lJQs2PX4UMoJH8vTtVy4x1dmr1rf4cYqaogTw6ZY3jl3jsdvYHPr6g6sxVkt/wCnzE1VI8sGZ2jeHcqQKfMhXOTtPbHbQP8A2y/i1ZK86lBPJNH4DOy+JGSCpTPAfjg986mp4GvFUlZTzCkq4cxVNLUxlGYNwpB9Cw9e2RqBiZADKMY71BhsbI6etRpQ20VM9QL0rU03lgj2qsrytyFwOAA3PfTt0c1TVUclsuVDGlxf9SELGyyVgX6lVs7RIAMg8bu2gdtWS2zRQXG0wTVYKxxzIvkIOeZO4IU4ye/J9NeaLqG3m4wW6soq2ikjdkdjUGQSqTglCeCobkD+kkai4aVeOajIxn6VLeBdorlB8rJ8hFUMzxBodvjAfUmzGBID6evODoKLibpMkFRHGVeTbDBk+c58wLepz7/jTldI0ttLIlDB/ELPNIPDdJDEyOeQh3ZCnOSD2I7HOrcVielsxuGyBzHIAktO0e8zMvIAHGAOTznJ9dA8VVUZHNBLEjJ4xSRdbZFTT1lJEIQciFXxzyc5K+y57Y1btBa0UgiuNPKbfR74pZ3iCtUxyEFEVe2dwO37DJ0MvlNXW6dRLbZqc7Mq8gkzv9vMozn7Z1Vrf471LUCO4SpRRQzeMsBQjcCoBbH/ACgYHtpqJCyASHg9+9M+J4o2E8UyW+7Uc95koxTU00kJKR1BUUzzqeUVwCB9vf0zoTcrZFfKhq2guBoK/bICZEKLG8WS0Y2jvt9O50GulooaN4hdFaepVhGwjiKMygZzw3GBjJ002xfn4IqguWp5aiNTIG3y08mQElyRhhgFS3318QsWHQn+Km+Q2VPNDbrWF7bT3Voy4BNtllp5jsilB3qQmPLuT0GBwfXU7Wfqy50Tz0NPvAGEWCnxGFP9Tn1IH0g51F038tbp7hbWkepaXcIolBYCePlPMRjLZZeeDqpcbnaa+U0dd/Gado/LuaZZVBZcldhC4Y9sjnGibdzjaOB3/wBUJoww3AVEbY1qjNTc6xzO0G40keHiiGDgSSff+kZI9To7eaoWuxU9JPb1imr4Fq7isRKR+Io/QiI53FVyzDjkjQuz2Sngljroeo4WBdoUhNO6iSQr5VIGQyj39xqnVrPFjfXwTVElQGrKcMXSUj/1MN2b0I0Rtrnr+4qO1TVJaWV5YbrI1WIKlWWSWnn8oJBK7gDyMDtr1Q3wSrGaitq3jgJZAzZJDY3DJzjOB+caJwU00VA7K1PlA0PgsDKrYJcbQCOfQ+oGgFS8ddBHVRxx0tLI/wCnEjZ2ntk45PqOecaMMSD5VM5x8BV+y9VSUd1eutNJUCpjqTWBlxuBU5O374yCB3GusulrpTdWdO096pYoq201SCqiI8slKx+qPHfAOdcX25Kuieaupd08UbNFLJCxDxBgRnjleOx7emtX+CXxltnTstV0/eKYUlslUMjqxMScYIbPIyec++dfXloJI8oMkVpvZ29FnchT7rcV0ndek42phNaeoaZacL4qoWPiKe2AT/ppcht8hieNKYu0ak4BzvI7gD39tTMIqikjqqKrhnglIZcvghfb76I9N3ahrL5UquEjWYRFR3RgP8j99UUYYZya9LQhiGBpdhp1afOxtr8ebv8Av9xqZaVkmSeLJU8ODpw6s6aenJuNJBkFS7ge3uB76D2l46glWC5J7H30QOGXNSOQdtfDSERiRQucZPHf8atUVXLGmJUK7eMDv9tGqO2NOoLqF2ZGAM8anksTnOOcjA9NLOwzT6FlXIqrTXZgQm47uwOeMe2jlDXIkySSSI2ByM/Tpems1TSnzjODjO3j++vxzTxvywYc5PbGg7cnimN7bOaeIrjFNKJBKpAI4P8AmNQVtwgiUxI5GTkEtxrPpepo6NDJVTiCJQd7vwg/f31Rpupb/wBQnw+k7BPdUT/9y2IoQf8Arbv+2dHit5CfKKVOZeKfUhhqKhnEYC7G3Mw4Os+6tvlut5lkmuEFPGufM7hQMffV9ujPjBcYx4twtlD43BSDdI6D23Hj/LQC5fAO21NV811ncqm4SQg4Qvxu78440cRKhzK1Ra2ZQSKr9I3yhuMi1FBcEqVlbIKHI/z01XaERMxCHa4DAkf3Ggq2GhpI6eKkhSBKXAi8MDgZ9dM/Umx7dCUlV3j8pZV24GPbS8pQuNnSgqvhgqK4y61tF2q+pbxHKyOKavbwlMygeHnOAB2x31X6ZjmitNVcBdoKatMoFLHuWMtg8kOw2jJwPvop1zFXVvWXUEdNFPHR0kxnqamMZKg7cjj6ufT09dClIqKKcwU1O2+WNYvHICqgy2e4zg4yO2daNGIiUEDHFeMaopF5IMcZNM1BBXm8eLcaCWP5dTIQ6AIDsJ3KewG7sy9jrzd7XBUrmR5XjgKSGqlUqyM30hyfKcnsex/y1H07WX609OVqzmkJwYqSmjwY2LNlmdeQw/HOqcVc0oapF0hoJ6hDHLTrK8kBGRz4Z5UZ9MnvpJ0w5Knp6UgwGTg9OlVJVprcq1Fwtq1eysMJDPsEU48zHHf6cH2PfRKnYNPVVtRPND8/CYn8UgnhwyoCOCPb11fW7Wy/VSW6/FKlnlheoSJG/WVPKAH4IYLnkfjnX2+9Kw2iaip45YEpK2qqGBki3KRGPJtY8N5SCfvrplB8pyCf2qODwvrVijhudyqC0VRF87aZRJDMAEJjZsGJx/McdvftoZ1ZQz2mvZ69pI6eOdpY/DLbkJ5yD2KkcjOD3HpqC2zMadrXcgI56uHa8oBLM4O6PH3wMf29dELVeLre4auz3+oPiUcCVFM4AZpk3YGz0YgZ786GFdDuUZA/b1FAAIPHSvvTt5udiuMUtnrDLBUSCoRZl8SknRvqRsjyj7Hsee+iPWPUV4o3pqh4WtlCsbgoJlCsZG8wB7ucdx37Y0Nnpat6OofIvFJGWSKKmo1EsRJ+rGRn769W9rbWQi3XvqS2VVuL+OIamJpGhcrgsGXsR7H11LEbneRkff60wqo3mPQVLUXahtVvhrKSpuNbTSLuXcwlghz2wGGRg9+fbVW2TUgtS1d1p3aqqGJ3+JkICx7kdiRyM5Bxr7N0zJ01QU9wtHVdFWwKAhSLxVaSPJIkI2+UY49R+dfrbDZ7u00aSQzT1LK+5p2hzGvLDbsw2449saiwTBxz8alEI3B71W6nsdFbLlEIaOomq0p4wE8TzvI4ywb+rIPpgAa9Ul3pbSsExtSUkuCPCgndgABhvFLcY+3fRS9dVRLcpHprNQi5SSBKp1WSd4iAB9Uh2jAA4UYHbUNe1dfYRWQ3WnrIKdgXgj2xGnlJwp24AIOPTXxYlQslBlbJAFKYvUr3IimglHhGOSMM5BZu6kng4zohPZrtfJXustDTtDCTuRJPKNxyQSOx3ccntqvQ19nqjUTtQolMZgoq67DNNPnIREAAC475z+ecauWu+3VYJFvMcNZTymWKOKR8qSOysi4AA7gjDDHtpt0ZPMgxj1qZRkHHAr7KlztdVFWVzUUrl1UUtGnIbuFGBxjuD+dVL71NTPVTUF3tkVX4ka7pBM3iRj1yynGM+h0yWY3Cjq5pL7aKSufc7JOCRK8Sx4ADqcBuQq8aoVlN07Szy1dst1PFUUka/NQVMXjTvNjIiQn9N/ucZ4PGhIql8uM/KuI4DYB4+FL0NDdquogfp2gmihhfxUTb4kY9CxcHAz99V66jhoYKljNCZYSVWnhfd5z65XKjHfk/jXy/tf8AqGnp6ma71ElPN+mtMkJiigfPMZQcA+o9xqa+W+3Wiip47cVhjhIjk8TzM7FAxbj3OcfjTmNpVSefT+zTMrB8etDoK2kUU1S03ydapMcs0LYLR7fKcD17gj10JnqI5zV0UiwqZCJY2jXCl1HbHbkZ/fUT1MVTKF+W4Y/+mSCT6j8nUkscZppIYopI3Y/zjBKr7n88Z0+q7Dk1JFKnJpq6I+IvV3TlCIaB3rKOEMZEnchEA7eY/SPT860n4O/Eqe9dQXO4VyeD4k0TKiPlU4x6+nHfXPiyVtREtvjLOiEkRL7+pI9Tx66YOh+ooekuoqWqbEkMgEdTk8Yb/wAd/wC+oz2kbhuOTV7YanNbOq7jtz0r+jloulJf7WqRVMJnVSArd9uPfWW3xZenL8YX/T3uGQ9wRqr0ZeKxFiltM8algGiHdDn2P3033aooutKFrXdKf5G8QKWTeMFvup9RrKmEwtjqK9FNz4hDLROxXiGqZGLHJIOfTTnC0TIHEYcnnIGsV6frKijna11uY6mFtpB9fuPtp0oeoa2kYJLnZ2y3GlZU2txVpHcB04607VlK1TSssSjewJHHGs26hqzE/g7CsrNtSMryzfkadrffoa2Jo451DYI79tAaS0FqmSZaCapnDnMrHG0fbQwdpyalu3DaKVU+GtFeKmK59Q+NcpYyGWCbinj9wsecH99ahZRDQ0YpoYvBgGNkUagKMew9NU6Oj8MYeiqEOOc6NUlNAG3eG4QccjRDdu67c4FG2iPha8yXq8TKsFHSxxqOC7cnHvpbvVrrpHLTzZXBJb3On+gFvLFCq/YnVPqRaL5d4oWUsynnd20M5bmpxqN3mrHKuiEMgMhJUttAJ4Go+qrssX+7so2eXaRzhe5P9hohUylLzFTtjww/fOs8+JtY9RTXc00qqyUssEbmQIFZ+CSx4Ax66LBGXcZ6VW6rMkCFlPOK55616oWeC6w2/MtVdLg81X4TkrT0yt5IwezFj5mPpgDSrHVSUVLBFFTKzVG6RPmFyB6cA/Ya9ObfZJZWtVY9XLEhQS7cK8mfMyqf5QO2e/f7ar1t3mqWhqqnaSF8rjIKkDHbsP7a2Kx4AVRxXjMkniyMxPU00WqvnrLZTWuz0mappyXcS/ojIGMtjy+p16qrzgGiq54Jp3ikhlkXnA9DvOMnIHfQCz3mrqZY44a+Cjk27QGULG5xjzEDGfuf76qXi2NSV+KieGNWUFkhfxNv2yTyPvnS/wCGUyYfj96VMALY6VegqI6Z4vGwJmfxGlWbKKR2CgDg+/J1pt5rXu/QvTtDV0iNPSfN1swnbzlZiFXaRyAAvtxnWTUFUq/LymMMkR8RVOOWU4GffnT707LPeqyKrpp3qquNDmmYgeIgBD7c+65GOcHGgXyEEN6VHazOF70LooHaOotu+djsJ2eIJMuHDA+hxj251JKtRcpY6ilipoJYcRVUZkCPMRzuYHGc59O+PfUVJUW2lrDWQV48KOdkgeoYLOyj6UPB5XOPvoz1NbgtymrY4YqqkqWAp5oCGIDRhgTt9c+hAI++hsSr0C4VkPHSpJ0q6V620xzukEsSpIHz5V4JaMe57bh++g79PU0l+huVvBho0VZQkI/4pUcRA9ucD78knV+qqK+qoaS51bywV1M4hkZ0GVRR9aE8EHPf9tVb+sFVUJRuklPRuoBhpSfEZ8cybT7+o7e2gxl0baDjOc9/+0JNycbsZq5SV0EE/iXa21lLLUSlWQOWiyT9SY5UjtxwdWIrHXU9bXSVdJHQ+LERHVxB5BIjHPlIB2ngasUgufTttoqWzwrWRVu5J1qlAXcozhVJzEwXktnB9NSWDq2kSOS31ktUlJIh+VKliI5RnLbuS0QGC3rjsNRfeMmEZqaM0bZTn51QvBtt5Vaqtr/lKiQnIl3+FIFGC2O4Jx/qc6o2w2qtbwrHLSQ1VM2IqGY5Woz2be3BP2P7ar3+79XU000MkFPG8ZUymOcYfPIO31HqGHcaisc9Vcljmu9ON0ayPvwBkDG1j9hoojaOLcx4+ef0qQUopJI5qaOptNNGtsuFu8SElVCAgqWJxuT1G0jGe/vorW1MlZWRWyz2tK2qqGSgSZe7yqezc4VgPqPsM51+tleKy418VzdJIaeB60/pbHp5UAbGO2CcdvXVG23evoDVVFHPAizRy+LMUO7ZKMl4zjg8kHAzqJGTnB+vBzXEyeCeKIGkpIZjSw1Rk3Vny6zmRgryHhnQHjuMDHpz7aD1dro7nUThK4K0hcRORvBeM+dSByCBzk9++iVsuMFO9At6mDQ2+4l4I4hhVR48ZJIzyMEZ9eNUrbYitWK+nuK0VfMZHjhmxtA5zIzDOzg8KeedTjXYSxPNfFAmGJqsaOr6copnqLvBVTkFqiiEe4U2PoYtkr4nchcnA5PtqhVy0tbV0v8AFZpqOlmaIyqp37VVTsz98f8A9tG7hDEXEVZmOmhjWJzI216lvQ+w+7dsY1Rr1j//AFj1AEBU+EY0wowu3aueW5OMnGjJNltx61NZBvBPWqFlr7a9yq2pKMRK0TvHDvWWJscLkHkN6hgc/tqr1BPb6Gmo40o4ah2jKtKJ3wGU4IAGBj++dXYun7hT2ham30glqJm8ICGZS0aoOcjvkkk6EU0vUVomjoqmlamaAOQ80X/DVsEkEg4PHGNPIoZ94PA+NNA7zu7V6qLrdI0SSRKRKdYx5Y6YRb1x7gAk/fS1JJ+oWj4Dc49s+miTg/NGasaOWI5IMjsDLn1yOc6oVCU6yb4GYx5+lvqH2+/503GoXJFHXPet0/w//EmpgaTp27ZliijDxTNyVTONpP2J411FLR2rqOhp5xVTRzIgaCYH6T9n9Pwdcn/Afpx/kp71UQjZWS+DFuHBRO5/v/prarDeLz09UG2JURoxQFoZOYnB5DKT2z7HjVZqdiwUTx/nWr0LU9zfhZDyOlMl6L0ZR+ooShB2x3GIZX7B/b/TRbp+60chWGoqYqhTwGDAjX2k60tU8Gyvp5LbJIoR0mi308npnJ7aqz9EdFXlzUQO1pqnGBLRynwnPvt7DVASf/ofStjHjsab4IenvF+YjnkglGMbMf5++mKk6ms6p4AmZyo+piAdZfT/AAqv6MqW3qcVKEZH6m1sfvolR/CjqipYn/aBoscHs+gMkTdWpwboxlRzWgDqKiSQFqldvqCRz9tX/wCOWashdTVJGxwR5tZRcfhR1rSAvT3ymqlz9LNsI0q3fp7rW1IfGnWMKfqE6/8AfXVton900J7mVTyK264XO0RReGlw8J8Z3Fs6zjq3rukp3FPQXMsqf8Rh31nHy3UlW58a5VEmTjbHzj9xr2On2UkzxszHu0jZOPfR47UDqaWe+ZOF60Un6werfFFIWYk+dhwvvrK/jT/HrnYIoLXAHonqc1c3ic+IPoUj2Oc6crhVmBRRWpcyZ25K+UDPJOlf4VSQdTXzqfpC9YqKerkkG1myMZOP7EZ1a6dCry4HUVntcuJ2ty2axajtvjhqePbBVtkmOoQBZOPoU+h79+/vr7cbJNUw/MSxiD9IMoBBR8DAxjnPocjI1+vdqmsnVlwtVfJJJV22paMDazeIFPlIA5HGDjRez0HUlxuRt9vsVdVR3BtxHhsD4Z7gHsOefzqzeOYNhOtefgODk9D3oPaEtyyNTVcCU5QbXBXdl/yRga9yXqnCvbxRLVxqd8YMXhYJ4wcfb9tad0x/h1+K/UNz8JLWFpZFl3TV8hjCEYxuIBO/2A043/8Aw4VfSVlpLjcevLYlZWv4EdHb6V5v+rc8uBkDQnQmQAjJPx7/AL1ERM7k9RWDWFBdK6ltnyUUBqZ/DCrnIJ/PbnGvVM9MWNPbpIaaup6lG3vJtZ3VsBkJPfPJB1r1k+FNJa+oKO8Vl8kmWJ0lQimAKuDjI82MepHPtqGu+Almq6ma7RdQ1SrMzPKEpI9qsTk4yTj8Y+2mPwcgbzcfn3p+HSbyYkquKznqimNJ1JULVUMsNO8ZrAhiwpY9yD327s9j66P2ytoI+naOs+bEZTfAodMCWJTwgPBJViSpPmGfXTfWfB+qWIQdH3ivvlRRIQtmrtkVRICpP6T9mb1CEDPYZOkKhrFobJU27qiYQU8MZ+Xhjjy4kZsuh4yhDDnP441W3VvJGqo36d/y9aVu7Wa3HnFD5p7jFCJzb6l2hq2fCDcGjfnaAB5ge/torU2hLo0s9ovE0UsCLMiKpRiz/wAhDchgeNFGt0FwaC3VBqaeWpp0zTiJjIFZeCmCcMMA7fbQqn6V6qtxNxgip1pkYMlWZSkowcZJLc59ePtpQSKw5O1hSSKjnLDB9apV3Ud8uVQ1ve1F0po0llhrUGxmGFwgIyM/n31egvi0K04eZo5FIBoYUXaqO3pk4bHYY/fVStrvn65oqyCsfchhW4U8JlUlvsccZH2OrdpttupZJK6O4UmZWCwzGOQPGzL5sL755xjg8jU32bAWXHy9f4/evvDUdRj5V9e4WO71ot9fUNaZIVMEcnyuWYBsqSD6Dt7AdtDqiaGz3F2kua1axMYlMDMdzsMcnHt2xxpit1zpYqINNOlXJTs+A9PlZc9ghkO4N39gfbQSkqKWqp6iokpVT5iYRK0gELqF54x9jjPcaGm0EjBwPv0zUCoUkmrSZpjVmQwpUVVmLYlJHiNIQuCexO0fk6H0Ty0NbT2qBs1RqFREXJCuRt7diMZyT+2rzX4FKGxVjKzGk8gibAMZcsqFm7kckE6tQ1luqLjX3a2tdjU2mmdGNQ8bxB2OxG3jB824kZHoNFCsM5HFcgjLsB61SarrJquV7QKKZqgMsdVUR5dTjsQfImACeBzxjVB6e4T3WmolY1MVRHD4TqDgpyWUAdgW7+p7aKTrDaKa311ZUCF3gENaQBtfa3OQPqO0rj1z2x319da2+W4RdEJ49GmUneEjxwM5w0f1Rr77c599TQn3k6ev+6kThiV6V6vXyqRtb6lqeadMNLbo23YLNnyvnyHj/hZJxobdFEqRMagvFWyNUwMDtBYEBUAP0lcYIPYapPZamjpQs0uFNU8zrtAkMi4Gwe2O59RkHGrFJUVFxpZY66CSJ5G8TwwvAOPrDHsCMA55OpbFRQVORUSO61IzLcYDQKGpbajs9fUIS7StnLFR6k4wMemNXL7vtFottsW4pb/FjarqnqpDJIFkH6UAQAk4UAkDjLc6lsFPSXW+IZvAloqOBG/QRhEjIckf8wHfn6j21DKlT1VdXeNI7nUNUTCGOFTJKruDtX7g9wTwrcaIjcgY/ujKpKbiKVJEpEqIJ6KNo1cskk09OvhycdliOcA/n+2hn8InuNfT0MQef5iVYKVomyDk9sEdxnkca1qm/wAOnVNPZv8AafqWkr6KmkkGGeM5UYycueA34yPvp9+Fnwdp1vdPfYrGtLbqZBNTzyMzSVUpHlkG7075OBq9tLOSXkGmSGiXeaYbH0vB01ZrXaoE2mjpxH25JAyzfkk6dbTZ7X1fQG31yCKphKmJiOQwGMk+o9xq4lgEs6+LDkg9wxXj1/z0IHzVjuz1CYKB8HA28H7fjV3+HAXaRxSyTtnepwaqulysNxbpq4GIVWQUpawfpVCE43RSEcj3BBxr9cunv4fH4woLlaS/m3U48emb8bSeP7a1Gey2P4kWI0N5p45pUAMUz4BifHBVu49OBrNbn0b1P0XdI6ek6lNGoOIoal3eFx6gNjj9wdZHWdEe2zcW/K969B0HXY7hRb3PDjofX/lC4711PZ18Wnr4KqFT/K+G/wDpPOrdP8WLnTxspSWKQ9wr4z+x0aS43etMcNx6fgrQm7dLSSxSbvfjhv8ALUdytnS1YFFX0pWq7ZOPAdG/9tZXxVPvLWt8w6NVJvizV1qkSUtS+fLkAc/56Gy9UUVSxb+DwCRhzJO+7A9TtyRqrJ0h0tLUK0fRd7YqD4ir4qp+SQcaKW/oy1SQ/OUvQ0KrH/6lVVnAP3yx18XiXkCoFWY+bmqcfUFHJup6ITV8+3iGnj3KPyeyj86H1NqvVask3UFclpoQBiKnYNK/2Zuw/bT1FaKtIFhjrqamRuSlHGNqH2yeM6H19iakhepgVWmHKzTSFmH39lH4GhtcdlqS2uTk1md/raagozTW2lFLTohMtTNks3sozySdA/8ADvbTUde36qVGCRxo2W4ILE8fnV3rWaOMyVtdUS1LR58JFO/dJjjHsPudM3+Fu3VE1ov3UEoDSVk7xg44IRcHH4zq/wBAVmmzVD7QgC1YMas19Cj9U3FoYFp22hpJkhUu/PIyBuP5196Et3hdT0dCgp28UHYc4cOScRnHuBnPfTXbqNa66zs0QI3hQxGCONNUHStHKYmagjeQtuRymG3D1yMHj863QhyMr1rzptRJjELjIHxrV+mLXBQ2aGhnp4HhXI8Rxlldzu2hgctjBwWycaxb/E/05ajY6BrdWKtziqDLtUnJhcfU2QCMkDafXR6uqesen7dDJQdUzUVup2eatkak+ZqFXbwVGcSAdsHlQc86xDqn4jXTqKqNBLdqgQvn/e58CeVcc5kX6gOwUdh2zqpXS5I7jfJ061OKYOBtpJsPWlXQtDXV9VHNTU5EclMeT3wSPf8AHfWyWXrLpqqt0IghpmMqBwkbbmVSfqA77lPbOdYT1V0xLJDU1FOrxqIkY+TnaD3wOMnVPoG+0vSl5+Qrp5TQ1Tl1JwNjn+VuDt9/zpyW1W4O41tLXXZdNVEUA5HetU6ivlKl/p3o5HFZKjj5hotoJDZQ5B+oHkH31m/xXpKqs6rPxHagpYFqYlSvjihLQtVrgGR1UcbsAk8efk986cOpEgcwXmyxb5KaUvGrSKVXA5BIGPzravh58Bo/ifbbZdKLqWmjjukRhkidCVD5y3kBxx7H24zpeWC3jgKSHHxpDXJjeP48gzkdBgfnXHNZ1TO9cOobRNKtMH/3uXbiokmA4Vm9FPpjGRwdFbbfKmoDVlfLFPlSAvheUOxyHPcjHbAxrtrrr/4cHTVBZq6r6S6yqFvE4SWSKpi/3Wd++Fxyg4Pv+Nct9Q/C09FVU1h6ptIjq6p1mmp0Y7IgpwrbhwwPcAazLWsd04ihOcd6zUenPOwUUoUEj1Udco8D5iIeL4S1G3xBnkgHhdv30Io7rSXG3C016Tzz1lTvi8JlAiKsQTnnkcH0Bwdap8PehOmupepJLZTdOKDQxPLPIpbf4e0+pPr21rXwzi6UtUlTFerPa7baIreDJFVwK1Okm7DFwctkjnA5z208+h/hY/Fkbv268UyNKIDlDnb1+vSuVbhYqyC2vT/M+NcFrMzMkW8lVHl2gc8k6B2i8XqjqhT1FEssVQ+JTUoVUHPIyRgY7Y10Tfulehb51JcKXpiCqWh+bU0jRnwJKdSPq3eo3dgw7YzzrKPihY770BcI4Ooqqe8WSvJanrZADvc99+Bw4xyuc4wdFfR51tzOq7l+WCPv8qqnj2MUFJdVX22pO1IadDChZZCuW/TXARW9T657DTHWiO3Wv+HJtaaoq0kZIyDvVVXYxPryxJz/AJaWaeCtusgt01CaR43Mjl1O4lhtAbjjHvxqzZbSlIt3bMkjUkMXlVSWD78ttA5HbuPTVZIqkYzyPzqKv4YOOuKt3aV6oyUtZbJXoZJkTfE+9g2DtIzgEj+nOoKK20dtjVGrKuGIBh49PGQY3A5bO4NnsMYI002Wz1fUlIlNT0M601TVeJLMVfehAx4ezvhl5zwNOdk+DNjpZWqOorzGYYpgq0yFkZ4858NgCSTg++fTTdrp11OoCLgfpU4IpJAQV49aQLVWVt8p6ShrQt4qHmSWnkpkYVbv9LNnHmJXAJOeR31px/w1VNWsSTdW9N2GaoUVYpKyvkqPEBPHjGJWUEdtu7jnOnm1UPR3TsC/wegipYUqPlo44o/CdcnueztGPXJ7nTuVSNZxTVIkrPKqLNtClseYBTycj8D176sv8PHbgmZjk+nSr7TNES/JVHyR6Ui2b/CJden0kknuPz8NxpkLVFndBC6fzRxkk+Qk5Pc4441v3wN/wwfCX4cype4aZ7hcpSmxquM+HDIUJCtn6sNyDwB7Z1klk616k6EqXt1FLUR2+pkZJKaSQGGN2H1cfQfsDg+utCtnxXvlsnEaTozh3hcz+dXLKNrAA4H476SkR4HzH0PfFaGL2XmkjaFCgI5594/Cq/8AieuS1NrrbLTO9N8qiVC0+0gPvBV2yTngZ4AI+3roT8KLhSdTdCWatjAY0lMLfUGMjMbxeUg+xxg/vpa+I1xv1/vUt8uLUzfNRNGssLksGB2lBGc/fGPfWa9AdcSfCTrqOhu9DUW7p28zeFNuJCwzMcJKR6MCdp+x57a0uiqY4fXJ5+FZHUtPmgc29yNpAyM966cms0LyZjk+s5jB4LnHHJ440r9R9NySyKVTc8WTnkH8e2n2Lw8mMhW3gbXR8hsjIbPt7Y1NV0ySxmEQYIGcMw8vH/321fGIMKzpcocVjtsq7lZapCCwG4ZHOGH/AJ1plvrLV1NQmnuNKJsgA7uGBxwQfQ6D3/pL9JnoUbD8goMYz3I++l6lqq+xOFRHQRkB93qcf66U2eEcdaOshYZzU9++GV1pag3Oz3ytamzvEDQ+JJD6EBgVOD+dLiVDxV8kMvVdQH27GXwHDZHZSXJ51rNg6rF0hiV2VAOSrcHkY2/cZ50RrOlOnupHzAJI5lzuaF2VyQO4I9QeOQdZ3UfZeC9Jltztb9K1Gl+1k9kBHcjcvr3rFamRpyEae9VpjP6h8Pep+2OFH7jVuWS4PT/7l0i5LLgLVVKDkdiQCeP21c6h/wBlekr49hTrmS6XF5Aj0cTb5E/5ZHA2rjPIY59hpWnvNquUVU1JPcnNMQCJa11C7iVOVGCcYyAdZBvZrUBJ4YUfPPFbyD2g0+dQwYg+mOaIUlTdCzTXa426hdQSIad/EkH2APA/fV2rt9DJSpcJKaUxlAI5a5y7O/ssfAz+2gfT90s9O/ylIkAkjxMGkw8rEjDe5J9Rpvmeuexi8VKxySzoYoKcQktCgzznsc+p1V3tlJp8nhSDmrOGdbsBozxXNXxSq6ipqJ6ZJGaYHwwoUCONDyVOO7e/tre/8OljSz/C23okSCaojaYkkeUuxJ/c6yzqXptr1UyCOlTwaZ1VAh8zO587Y9+f7a0Dpn4lRdI0dFZRaqarp4oBtEUpUqgbG3JGM4B5++tT7MDcxYDpWW9rQy24T1NHKejkouoZoI2yko8pY4zz6Ea0W2xxrTp4yBwDt3AEqX9h+dc/UHxZvM3xBp7P1bYLfa6e6SPNaHp5GLMgP0SKxyCR64wTnGNdE2nwmpo2Ur51JztyBnt++RrcwMHYgV5lPE0QDGr0cRSOPbFvIG7cByTyduPuMjn21jPUXw66Kpp7nYpLDsmhqVqIakNuJpp1LRRlO2FYMucce/prdY4IVWGSKRmIfeVAwWGQe/4J0jNarD1j8UqW3SyyyxUVp8OpWnlYAS+OdkcjKcHKHOO447ajqOxbdmJximNIl8K6VmXco6isPufRt18A2iOlC0jL5/CbJKgZHmHGT9+dArl8IYYafxIizVEke9IwA4kXHcsOcDvx9+2urr78Fac0AHTtwlGwPtgl3FVO71Y8qfQDOOe+NYn1pQ19jrHls96hKURAkppQd8beof2GfUf56DpV7a3EXByw654NW2oOJ7jxIxsXt3H+qz3om30EdJUdH9V0qJDUqZKetgj868YO7GMgHGG9jznRKwUXW3Q3UR6bqupJaMUksNZSTRVR2zI/AYY4GOM47HRfp6kufVF3pVe3RrKwAkjTkKxPOOPLxk4Oi3XfT1ys0VBLUxCemt0hEM0hB2ROcMpwM7Mcj2I1V6vJ+HnXw+jdc0xp0iSsFm5A6jJ5rrzpD4nL1B05Z5q6WTxYJkpK3xZA+T9MjZ5+3t30J+OPwctPxG6Qrw6rHdI1drVVnjBXlQ2OWRhxj078a5hFyuVFNBc+l7jipmXeWDM6SbcBWfnzZ7DIB41ck/xH/F6isVNQtcIIWinO92gVyu18FQCDwfbWeNlJHckRsA3X/laPUNBmgi/HWq5iPpyR2pM+FVrPT/VEVRNIYpDHVU80ygko5XBBGRx39To38Huh0vN4qW6mrqepSljnmFLWZ8JlydmT9O1uzDOeNB5evYP9qT1JX2uI/Nt49QYmMSZJKttQHyknnafKcaefh/VUkdmivc07uanxJoT8winaH8qcgYBB3ZPOe3rrfLAL+0FuThx3+PwrFGeaByxBwevx+dfbn8PrcLi9yoIoKaIxbJIIGMcWCOTxnCg9s+2dZr8fep7JcfhonSNxo6GlnrKqFqGQTh5ZJY35lb1VSuVz/nrofqO2U9pp7Zf6xmq6G6uJloYCi1IQfWg/lZSTx986zv4vfB3pz4qdVxdS/KS0NsiEUSUkZG+cqOPEK/SQOCB3GsvDfXdpC0Rfynj1re3lhaa+kT6XbEyd+cAf3XKnT3Q/WXxEuVZQ9L2qpr5AzGStQLDEABlRK7MEQY58zemtR6Z+DtjsMrXHqO4rf+pfAVQlBn5K3SL9MskvBnk4xhRszjJbWtUSvcrdTfDjom0yvb6WNY4KOhgVliVeVDOf+JIWyTIxyfsABqtVdIXel+atdfYllqoIIsxRYy7M36oLDnI+rBHGNNW+jQW5UXDjPpXnNtFJNkwRlz8OaE9M2CourUyDxFkmEj+HswzDBJIOO4I9eDnnTE/QawmGWSlqHkkE5WamZWZWJBw4x5j6cYxjjV6wzUMFRHTU1JTo5iS3yloD4jJITly24FdpAwMncORk8abaGwtXq9aKI1VRUCGkMlRl2kCvt2YOCHGQeB2763trZwiPC8mq+4nmLbZMg+npWYr0vdZJ62skpJqihoo2cuJApLsRhgpHlx9/X78ajoVraaopphEtZNHTtPJIzrjy/UT65AwOO2cH21tXSlivd5nvy3ChpGopKWVPnRS7gh3kEMOyhccZ3f8ALjWZUFXNGbi1zjjCQmSiAKBmkQYGwngbSP5R2zyTqjvDA8xtwM4q70MOr+IrYPbFBYeqDJK9NXWhGjuNRgpHEqsnHoc+Y+3HtzoVS10FNWqjTxtTpIZITHGzc4wAwzkFe35znRyd7fdZGiq40LIjREhiGiClSu1+cYAx29NAL/0r/B5kulDNI7THKRqrKxiLZyGGM475x276rRZocgdK1N5fX20EnOOfiK+3C5+Nc6edlIFMyysoycAuMDI7A/bVj4k222da9Mz09RAWnaplUAICAqjKyZHODnhvUjGqFpqaiurpqN6BjTSq0iypxEgDYG4jkMCCckcnV56xT06KYxGSoSZonmkkPjNL3CjIztxjOrOzRbSJgOFNZi9ubjWLhS3vj75qj8C/jKlgrx8Muvqx0NOVp7ZcZzhMH6YJCeB/yt2HY66SSVF3xtSkNEBlt/lIx++uOus+jIrjRC7GlWORmaNnGcOSAO/fII04fB/49f7IiLo34i15a3pGIaa5HLPTEcCOX1aP2fkr9xqUcwzSt9pxBznzDrXUSQibcWA/UUeQJk4x6ftzpdvPT1DVASMCVYlcDOQPQj3GfX00Zo6ihq6OKtpqgTQ4DQ1BkzE6sM4Vxwe+dLfUfxW+G3SYkTqDq6h8WQAx0tPKKiZjg4AVCSO3ckD30Z5UUZc8VUx20srhI1JJ7VTj6fkpJWkpjKrqAzZGcEHAb2/fONZ78WPiT1lNZ6qxfDWseCKM/wD5ldFJMoXOHSHuvBJy3t21JdviP1X8SKh7P07bamx2fZ+srgR1c0Lj6i38iH2U4PvpkgtvSvRi0sctzV0q4gVTH0kjB3j8dz/31m73UyT4dqM1fRaY9oc3i4Poa50pbLc6dUCWep8NmZZp3YbkK4Kuw/OSDnJB1APiBbVuREsRjdioeWRWCuikkMAO6juGOTraBRWe80U1vkgWeGXbsWGTwmEUbHw5GfAy3JXk57ZGs1636RvdRHT3iy9H0fz9LSmgjuEtTgtByoeSAAKXGcA7sH21YXGWVfD7jmnoYHSLxMc0XtRpqpXu6zxzU3i5LJJ5kBXcAnrlsf561SjvldcenEqKapCwyU2UhJ4ZCOMY9RzrMrd0GaS2222zo8rimSnkaLnfJgAFhjLEZYDbnGO2mLpxqJbXSW+RpEaTdGoLE4xIVBz6AjzH21n/AGj0s3Fr4y+8v7Vb6DrixXPgP0bv8ap2+y3KR7jU+F4dst2JamvmfwoMkZAZj9uNo5zrPL117dVt9TD8O7dTmWeJo5bjXU27acnDxRsMKfZmBPqANOPxS6gPUsDdBdHVxbp2018dPH4b5NXPj9Wpb+ok5Az2A1Stdk6coLa9PXXKKFZ428M7wHZ+2Bnjj21X6fLJaw+Egwe+KNrEz3Mu6TkdvgKw/pzpDqui6ltPU1bLJX1y1YeR6mclZCckjeeVOM8njXZ1p68pbLZVkrbHcpSUAUGWJA2cHG7cc/nHOsSulqp7bbqdaCro5J3GRshJbKY8oJ45BOT76delbLR1sCV1TKtczqT8kVYKpA4IVuckDn0GtJFciCPxGH0qotNPTWJRaLgH1JxRK+fEvrrqGqSjooksdklISRKWRpKmXPAzMQNq8g+QDI4ydXrLZbp0k1RX9O1U9DVIAKh4mDGZx3bw+zc/29zoat1WvkFvnkhkjkMT+EYuEYDylfb7nAxxprqpaKSywVctSHKxsPKx80oPAbt3/wC2qu9vJp8KBjNehaH7NadaeI0hDBf3/qjVJ/iQq7XFLbL90609U6qryUsgUbtvLYbPmwc8cZ1hnVHUdRNUmvSkhhUVJMzbdhwwwQmT9JHOP6gcaZuoIoKqemuSW4hJkETujE7nU9+P7ebGfvqvXWdb3HUGgp4hNvEJYIpWELggAehB5yOM51ZadaQxIJMYasVqtqHupFtvdPSmCzUNxtNZRVVjuRhuRRn3qc/MysgcKARhuOADyedVOquq+rhYpLh1PTR3CkkIp52iXY1O57bxjzDJH20Q6LlnrrFQJUxfNT2+odcwx7RMwJCruBG49z6YA9dE7nPZpM2a+bXpKuGRamBo1dUR04IIGc7uSvAAGe/OtcdPtdStgZFGfWseXlspSnpWY9GdcU4sluEFTJ85FUGlngVcq2XIwSPMOSPsBr71JQ3K7XKeMW2enofGV5VjAzTtkAsx57f/AGdA7RG/StfVQSVlDIImagkkRyzqg80MgPBIKnaW9xjTWep6q80rW1FkppU/UKqQMxxgDcDjzE+gPAz76o7TSLOebdJyynFaub2k1SxsRaxMPDkGenPWqXXvTLT9OUdLBKsV4rGSAbcrnOc7+PbGGzgaLdI9JXu7q9oshWjtFuovAkeVAXkdBgiNByzEnkj9tU7v1F81XxU9uqZqipAEEGF8VRK54ycDJxkcDuNPnTtVNYEo7FNNSIkUTO9OqM8hk3ZaNg4Ch3yGU+mCD76tzFD+IVBgAflWd/EukBPV29e1NBp6OhRLdKbhNHQU8dNSLU0haWFimNvLDgOSQ4HIOCAdfKWludlqd9NKamiZQ0iBirxStwMDk4Yg+npqtHeqeos6OJrRT1la7RVkbzGPEp4kZcHBJUAnJznggjX6kv8AQJZTNDWNLSU6frqsxcMQ2AJj/RjBDKcjtyOdOzWtpcRGFlGPhSlnqV7psouLZyGH60T+Elwg6aF1FHb6TxXhdaYyTOYm3RZl3ntwMlSD7DQajrlmq6gVkskgj80IkY/qLjIOByAAPftwNGOmKda2uuPTtknWOaVWVd0JLIrA+cZb6QSQSM44GNVrx0ZfLFeqSlklXd8mAzCDcZkBJCxHJLt3IB7D141i9YsnudQZLdhnsDWx9i9dstHjZrwEbscgZ9KRuo70YaqCWgoIW8CRgHcZPHmBYDOAcnH8w9Tpvoa5LtRRSLWCWhmgjwnC4lYjKq+7ykY7dyPbS7drjZ/FNmmmWlqPFES+OVAG7gIWB2kZOTuIH9tCOieuIOn6Gu6VrEFTJJO8NKUjVwSG3NsOMFuOGA7jgc6e9n7iexLW04I+yaL7cJY6jsv7KQHPboe1dV9AUcVFZpPG2y0lcxd1jQjcwG12LccYPb1x++sf+MfRa2bqqvr7VAsdOlPHHI7oS0isDgj03Dt7Y7kHW/8ASFO1V09T0VypRSVS05mI3LgPtHLHHrx6d9U7+LHUWyOquNEtTLWU0lE/jsxKwk+YBAMeb1+wyNZeS7ZbxpuuSazEQaOIbDg1x/bzTbytBRPWywUzzTxqxXZtUkyAHvjuT6/bVKXqyhNrhpkl3Vi07bpnJkQrjzKAOwXgZHvrz1pY26avdVb6IQCGoWdFLAEbccEngEADaFA/OleGjqLh8pBRwrmmk8M7UVnAaPnA9+O/p7a1EJ8ZA/r2pqXU5ZE8Me93NO9j6c6ibfTw2d5qOsMcsKwbAshYch3zlcj+XGCdaZ0/8B5pqOsr6tYUrKh8rECWCKo4yCOSvAIHGlT4D9e0XS1zjPXccX8Mq/ENLUxrvNO5AC5A/kIHJPr2101Fd6Wpt1FX2OppaiKVTHvgOY0GcsMjnAH/AL6ptU1G5j/8gfL61yCOS3O7oTzXJ3xC+GF5s9DWivll3pLBNE6zHZIN2CpwMN6dsY1lvV/SaVLxNWW+EO5LuwkAxIDymD9jkY1/Qy6WW21+2nuqQPTVMJiMTx4w27IIPOc9xpC6l+AXQldRKtLEsdXG5bxC23JdSNo/+XyGPrxoNjrexttz09RX14WulBPvCuOfh90fdLaVY3K4VdutgNVFbJZ3MZQS4d1jztwD/Kfzp4r+kOmjdf4lSdPKldOWqZYIYgHI34ztx5e+fx350yxdISdJStaJ6LwKqAfLSlJDGGjzkFsZXbnlcerd869i1CWnprtReEJanxI2aKY7o5QdwQl8FuRwPU5Gt1DDBeWpxyrVUwXk9nOJozhlqglNZ7vBC38PSFqQPTkxrh3K8hhg9ucAfbSP1bapbRLLXS1ryzsqxkSMzYYHCjnGc8EdwNON0vVFZK2lulP8s9NdEzVRxRmMxyp9RC5xhvcdudBq3xutZJrhE0Mse4gTHILbGwFwcgDHqNZE6XNYXhSNvL1r1C89o7D2g0pZLtP/AG6ZHbjrTL8DbVaeouq6a3VImgSaA7vH5R6lFBYFc8gjsO/r21sN8+Bl9ttJLPZ6h66jJZkQSKAFfO3eCO49MHg4ONYDbqwWCNLvbrkjPSOk42Ek/MI2eeSe3HtrtT4b9ZR9c2CNrfK8c8LA1tNKUVkJHHrn8H7alqMksOJI6yJdrdEw3XtXGnUtnu1jpailr6d6GkKbpKiOMPuGCjAEeZWDAj2PfSNTtK1JVSXKdqWakgkaNixUIiR+TygZ5BwTgjPtrv7q7oiz3ikLXq1pUq48GbMeZWA5GWI9f6vX765R+K3w86Vt0Vwr+ibjQTR01NNT1FFFUrK8JccbcEkDdjKntg6CmtpIPCnGCfpScVsslysqjjOTXO1otAeSmnErrEk0TEKPKCOSD/fTx0fRCpubCu/WjlqTmOQAna/0kZ4Hpn7ao0Nje7/IyWR5N8lLvkeJR4cxHBGMjnIx30bts9XR3SOkltaJUGLYUZ9o8UDKkhv5QMnj9tINblpMqee9eopfw2tvtdNydjj9KI9SdL1FZby9nqXjFG//AA3n27mxxtJzxgcDudUbPRSVNJL4yOCIl2yRSjxWHLHA9AB99xxojTXirqmrKmeWnVFqwzNk+dlHlcY9AMgAa8WC/l55IJIzHuqVkYE5CyRnKMex5BIP7Dtq+0mMhtkhyKwHtG9tKBPbrtYelSwR1lJUSzb6wojgJPUhVZVcd1DDkH240UNzoq+ip6FE8Kp2ApDGpUuSxUnPbBzn1xntovW1/wA5aXkp7aayWrZoYpIUUlfMNwAJB4ODk5K4IGlqhqK2CWPxYyxl8VRHAwEUO5vPIpOSR5cFT6859NWN7YRDDLVXpmrXKM0eSQevNX7PJJVwNRpTyOlHNI5cODFuxgqORlRgEeuc6mVRJMYZjLIs8pl2B9oZSvlYbeVYMDke2qLyOpgqKGGoeOo3QyCLajOVGFOOOQM5x+deYqV7U0dxrqlYIpJfDTA8Qgscn/qB/Y+w0njAxWkEit0NWYakdPSwTQ1ZjR3JKrwME8nseM9vX3146xi/iklBR2WtWtuVRKhBWA+LUSKuNpbsPYnt2GvVqtlR17XU9qtNKK6up3khgRYjvlz/ADFs4XHqSeO2umPgz8FLZ8PxDeeottwvbonhuw3Q0Z7skYP1MfV/7aJPqy6bAd3foKzeoxGW8yOwrmr4h/Dae3WaDqKjYeNUUm2thKjKtGchl44Yd8ew9dZnBcJIb1bp5paorVxGNV8TksV5DcZOT5gOODga7u+JHw/W439a3aiW+oic1fheWQjPlXHOM88+2uWviZ0dS2mq6toLNSbRRmj6gtQBy6Qqdso3jnnkD01mtK1wwyNv6k5q7vRHf2sQU+cZGO2M0/8A+F/oU3nqSfqe5UcVZR2ZjT080qrIfmmAyT6FVXj7Hv763P4qdSdHdLdPSS9V2+ilqYpP0KeWjUmdAcELwSGHrnjGNZF0D8S7J8M/h1D070lZzWXC4MJ2llURU6yOMyMGP1MQQPTSNU3as6p6mpr11FcY69KGokpVp5HAAlI3EFdwIGBgHP2GTploZNavchtoqrksZ7GEu6+Udz/FQTWxviJNPfKmiit1neoxBS0kRdaiRQSjE+mFHf8AuNC5aauqGq6aKme2wSsjh/FAITZzHj1OQDg++jVe0IaStnppKET4McLM5+khQYhwu4ZGc4JHv30mXO8C51dVS2+vimb5rxnhkCyBWUgEH0IGM4GeTnW4RIdPgAU9P1qhhilupPKP6rp34KWWZqS5V0oJqIKkQwmRskqeSVPBI7DHbTP8RLXBVW2aqqKqKG4UsqvTvKhYRykc8DHm2+o1zt8LfjlcOmxVW262x6qhkqA2+NsShn/pJ4Ppx760zrH42dD9YdP1dFR1EpuTKIjFPEUlh2jAOMcn0yNYbUjK2pNcRjPmyCPyq3j0+SG1R39096y/q3p23TT1dxheWqjEaTxSNTgbMcyxqAMcn+b0+2lS12Kqouq6OjKR0sy1y7JUAMa9mYKO5Ow4x99TdJ3Ongiugq6qVmDOzD5tl3hsYwAOAGHOOORpuqYrZfqTe1DVxVGwLul8JZkyeZQoww29sg7m+2tuiLqEALcORVDKxikIzxXUtnmT5JXd2ZkYkkOBtGOFx9hz/wBtIHXvUlruFJTW8Vc9OsuZ3HDLsU5OftgZzxj01ilJ8YevOlka2VtQlRSu3+7VS0rpJMo45GOGx3GSfvoQJazqKeJqRzJSEyTGNdqDODnJxnbnk7jjA99YtdFkjnIm6CrNJ/EAWLqeKodV11H1Bfv4y0VbI5qNsTRyhgkRUAk+3OCQfQ8c6ILSRpSxRW22vDLTbEjdMZRn5LHf3BA4/OvNHQW2WKkEcB8R53RpaiMIEReVdvZW7jPOMDV9KYUU1c1JUstVVMTFO/nU7FHiblJzjafKONXEa7YwF6VorOxW1cmQZaqMlO3ybxV1NTk7jv8AChCmUDsJME8/cf30z22XqGz2qhS2Xy5QQiNpDSzSgKhwSvOO+RyPbvoBBVUtugkiHhU8SwmP5yWNjLliMjIP089u2NG4Op6R+mKoFqaA0peNWjcFZSpxiMHuD7+nOqnVI5Au+LNa3Qxp927W9/twORnijEnXnxMkho6lLtBIiwRzMPlwqq+7AjI5w3c4PGOdVbl8ffiJS2ue2JSUj1BqiVmEQicQgbQI8+UAYyxPuNK8t+uNVbUqLZK9NvUszscFsDIxkgA4457DVW02F7zHPVVtdExjSQACMsGV9u44JB259efTRrHRbu4AeVAM1Q+0F17PRBo7LJYdx0qpP1/1fc5zV3q4yXCctN4rRwKVPGfDwBxlfXBz30bo+u7GLbFTJReFNT+GsS0nATCZKszZYPgnuCD340xR9N0drzb4rQ1TUxKJ3erj8sqkbAGZSFUhW4XOcgd9Uq/pqgqaKpElOnzTsGaV4CgFOqbFEjgjzE8EYyQM5HbWxttOltVCxnA9O1eczzJKxwOKz293q23i2JWW6F5GWR3cKuwRK/BjU5xtG0EH3yfXQGknpkEtLSVoWF81EciyN4iuR/wzg9ie/oT9tOkXR89N1bPZ/kw1tnhVmjVgURhje2Pq28rgHtp/65sHTlu/h1LR0VsS3LAIKlVjy6SYIIlfGfY5B9saz2s6g1g48VcmrzQ9NfVZhbwtgms4sXSZraeBbZSUqbi0KyRsz5kcZO1OTlWBHbTjY7BcrNVmsH8RpthWCWRWbzwkbo2DD074z5hzoRbKOGFZIpo5WpCJSWBcMrqgwMjlWzgnP2GmWodaSQU9PMRE6LJHKJyBKdu0BRuwD3B78+ura0FtqlsSmP5FDu7O79n9QAuh7p/IiqPVDdbx2S509L15c4JvlJPCiNW0iSKUJDEHtkHaD7jOuLuiKa7dNfEOOxVzSLUSyJF4EyOslQ7Hhd3rnnOeNdo3Va6tkmpZKw00UC+AEPFTJLsBUeEQAQoIb7gn20gdZ9G0FS9BGt3WWrp6ynjldYXSWmUSL3yMrySRjIIPfWdg0S8hZnmxtH8VrtY13RbhFOnxlZOCTjjpyKSOjK1aWBqaOeo+VSaRY3k8paUuVeMg8BVbAH99FLpdKGsrEmkoP94yAlRgho2C4dSD3B9CdNFrtNKl7vFqrIlEFvuUnhfpgK3mJzyfX/XXq99M294lLOq1kLEF45CAVzkEHGcg4/HOp+HHMwlAoEct0Lfw0fg9j0pSjgMlXQVMFRFUeLEyMjnbnaPKSAMbl7H3GO50bsdmkt6pUiqj3zEyqzRkxlR/XjP9scfbV6bpFEqVqpHEcAAqfCXClmGGwMfShx3xnVieRq6f516aKSrqOZKaJSViZuPFY+pxxgfvzqytfDQl34ArMXVvMrCJ+/SinT8sNBd6213ilpvHRgfEhlV4gpTeWTYSM8jAznvnnUN5WCeFFcsYSo2ufNuVhnAIxnjn9tFLT0v1ztWufp5qaARbIx4IAKocbzkeuf8AxoT1BZbjbYJLetIiKlSrx0+eNpbdkt2yTlQBoMl+sz7VNW9vYJDGShyxFUkroah6dKitEq1UbOhj/VkO3jchPC8DBxyM6DXa6T1UnzsEPy9MzFIosh5VUjGFAGAD39hqX5paCiipZaiOdaR3emwdqgvneOMZOW2+xwNWrdbq5bmnixRQU6YDIFLl39VIzkY4GdFSASECqWW+nXIPFfOnOoblT3w3eBrwlQ6EVDxYCGZFCkADHA4zj+2uqOgfjZaLxb4KWoPydUHCtDUOQWYJ5ufTnj351i8FiNDX/IPdaVJVlNZSoSRLGkgXdGFYYzkYLYGOB99fZY4Lo4ljijkqDKREh434yHYcAZ7cf21T+02nNDEJgMjp8q03snp9tr8jW002yXtnoRxXUtVX2650UsMVQj06MhXwzuwOSVJP+Y1xV8Zes6K29fvV0FZHLGAtvmCPlXjckY/zH20RvU3UlgM81iuNdTPMCtVEZTiRducbe2QfTWKIsklRJUVLLM07I++SLxHLZJwecDPp+NUel2UbsZg2fhTeqaPc6DdLHOMgngjpW2WClqI7UjxhXYKY0jyGRnI48rcklR6E8e2gsFxo6CaukmrKKmjEoqFaGLNQu7hVORu2gcA5IGqD3ishsAlSrV3dljRo0MLBsHaCr5HvkjSVJcf4etPHdYGiJfx3qDKHXBHJJHA/H+R1eaPbSWsrTMKf9sdUtrizhtbcnsTxTrfur6ioppZ6GOGGOYsCyzHbJwMkqxIPb9z2xpBlvlVBG15pKJoJBIMU0EgUH3b3AP459dMHS9OOuL/b7FTQxwQUaF5PDOVRM55VRgqc49NPHX3S1mip6l/mXEiRgM0adzgbVOe6gDU9S1MRsEfrWLsy0cZVByaodJW0TW+pUQhmRQ6eI20sUbnBPHrkffVHqujSnrKlZGhjHgJKXdiyFt3csp4Y9s88+g009PRpWRvbEURLOfpcbmfH3znn/TQWtttOlabdUS1DojGLMaAJCxOSzBuVAHA7k541X2Exku8mvT9c09IdEVEOcc/vQq3wUdkvlNTXWhmW118HixxsCAZNu4qoyM4HOMjnnWoUlDZqcWeCjrp6WKOT5hqfbv3Js3hywGQFzkgtz7HSd1FIlx6cgkWnKV1L4T0gEXMZjbszHluPb350z0PUKTmCpqJUZw6OohVlDh4yhxxyVDMB+cZONbrS5AGZO9eQ6pZmIK6jg186k6fbqGFbdI0cFLRCbbLDUFmqmwCJUU8oD6j10rdGpPLaLpR3aCczQuEjjVeJSQdrHHAGO49hrRLXLTRU9PFVRqbdT00cDxGUSEmP6QxxvQrxuJPPr21nj3IUXV1XK9cVpamZNqwSkIRjIfd/Tjj9tB9okH4Yuhwxpr2TMf8Ak0E/u0yUdW38GFdDVkVLhQQELYGAckYOeRwNDo6uvqVqJ6O3FHdPEkkmCYUldrD3zjBwDxqx09YamWvutojnpYqWrlMiTBXO/wBTGQOT37jGBq/WCkoRcPkrUk9LFTkB4eDCVGHKptZlQcZG3ByOdB0iCG5s0f61Ze0l5dWWpSRA4B5H0FLd9sd6c7rvC1LTUkayClXlJFY9nIP1Hv8AjSvRK0gpJkaQIj+HTtASGjQE7Wk92PueMa2eVaS5dIQVSCellp6dDO80Yd343BAo4JA4Y9h3zrF6Sy1NdPXS0onMULePNuTcIwDgEgd8Z9eBo+oW8dqFKDAxWWW4knY7zk0bsVZPDTfwWqlU0RnLqgplUnDZKsucMnc5Y5OBpxpbjFPHcYbAq1NLDSyTSDbtmjVPrlAXnb24Lbcn7aVbRRGNRZ6iEhayFGqHqKlhmNT5doHpnzD7anpqZ7RMIqag+cnnZqZ5mXPjuw8oVe23tnjQoNQaEgZytWVtpwu4yQcGtes3yF16dijnq/lqp4kCmTE6uxXxNm1eWK4wWPPIPGqUoWqqjUUTBzJgSwMmBOwGwgjksQCDnIzpMobtQmyo/gPTXG3NHVTNRghpVB2OgzwGZNwwT2/Gi6VU9zr5LZDQywTU8EUsjxz4yqP4hCsON6xqEGMjJ9daGG6jmUFTxVNc2cltKQ4q9S0ym7Ib3JDS08EBid5IsmSHG3ZsQ9t38pOQcau/Eak6lpkpLpdraKW0eAq0VWUwjRqPKGXBIf8APv30e+EBtvVfXF2lbc1NUrHOYUTKeIh3AckHdg85HJBOtumt6dRx1NruMC1NIf0lEvAbnHrwQfca869prpZLrawyP+1otCu7jSZFuIfeHrXKFNTQJWT0dJWU58UB4o0O9MsAQrbuT7HnkHVel6olo5Gtdys0NJGgkRxHKUwo5HPpgjIA9hox1f8ACufpq9xUNIJKSnz4SzvKxH/FLbnb1GOPLjAA0mdXWq8QR1DT06TmnqYyWhA8V5GJSRue4C4I9sj8aJpVjcWRF1ZNuQ9R/dabVvaex1+D8PfRlJB0PUffFX+rjPbblbrtba0y09yCvAvKCZSAVbfknIO4NnB83tpcvl1ra+5QPNaoKcvWU5jjQksu2Rchtvc8Yz21bju1tulnioKitUT0cgWjhnbDpziLavoSAQe+c868y3SnFGKqtK06wVKyLG+H2tvGW3j1x6emNX99MZF8RDww5FZGwt4mYxNye3xq/wBa0Edl+I98FZRSU9NVSNloWO4lx32/fP8AloUlbUihjargDSrJHH8w4CtJsOGcAc7dm0cjk+nrrT/jvaKOGtlp6CnWtvV0lgp6SMltxJjDb0Zf5lHJJwoB1jE0tdaa42i/08ltr98daTLGHTwmQxY4yCpbnI4zrM6ZcGaPYx5BI/WrWK+NuSjcip626GCpo7fFb/HlovGWRhMVB8U52lvUAEYHoR31v3wV6HtUlwp7lthkYFmqpUwT4jL2IORtDYGfQ65hu1OtAyyRytURfpKJo8oszK2dwx+fXOtD6U+InUnQtTcKnp5vEphndBMniIPL5uO+BgnI9fXTl9C7wFUbBqvkunu5g6j+xXaFNQ2i2NLbVoppaeSQyqZCGQHPp9wfTSt1j8MLF1VSmGChEEsxSocEEIpQkptYfzZzn050v/Df4sUHU9za23R4KOsWmimjKSGNZkkUHcgfsftye+tWtlf4FLDLRuJVEZH6g2umc4fPbB1iXS4s5fNTaOQQQea4r+Jvw1uvTkLVNHSTiBQNkZUtu5J3Akds+h1JaUrLexnlp0UzwLIwfH6kiYACqDyCWwR3JGfTXaEtHSVFJGLnDDU7FMqRSwKyh/6gSD6Ht99Yz8Q/h1NYaee69EUC1tvWWT5inY7zSeQlmC8bgM59ce2tbomtpuCXRwexpDUITJh1rLKmjSrqbZcBXCZZIWlWMyFi4J2HEoG7GQcjvnGgNwoWgoorrXS/LzQmVJgHLEEOSMA8FgMZHB+2jnS8FxuVLS1dsoo5aeKmleEQVBV4YuDIcHBJYqTjuD21JW9AdRVFHHRyUVoamrgXjT55HdZ3bcrlQcLtQ+dicj11sr64tGiMUrAZ6f3SVi89pMs0ecqRQOvro620Q14qomSMK8zjG8buF38ck+msOuKNQdUJAKlhC85aSQ4CbD9GPQDvye341td16T6vNpWht9Za5Pl5mUJBV78ojY8VNoKshzwQc49NZR8QunrjbLAl2r7xb6qWn8PfTUzuSoZsFeVA457n++vPbIQ20jbWzXqOt6z/AJeGKNv/AJpnutsuU1Pb7bBG1VFUy+KmwMyEBMhAy5C88bs4186u6bjnsxqJrghgYoJVgQKN2QVDMM5IwRwfTVL4Z3ethvMENFdoWLRMlLHUQGRWlxwhwy4xkngH21qnUNKz9Hy2mrmmmDTMGmSmUKXZchgDhsFhgYXI5763GmQpJCT3rz3XJnWcZ6dqGfA3pWltFlr7vSUcitVruRSzOqxqcBN/oO5P3Ol/ri8CrrKqlkmB3Pt2tzlR6E+2lGXrTrDoSguFRZXj/h09P5YJiCYpd2SwDY59NInQPXdw6ru1ym6jr2kj34QJDwh9SxAPt66xeq6ZN47T5BFWmgCOW5jRvUVuFuqKK3pU07qarwsxSNkjyld3BPPbkH11Vh8PwxTW3wWd9pjUyHxHwN247sZxnnntoDTdRWiS3xCWqgFC+FLvMqyq2OGHOMfn8a92S70dVKrG7U9OhcwpM0ysseew2f3833wdMxQCG4J9a0kusm+sFjPUZB+VMVSloqIqKZaXaXIiEvibMl8h43Iby+cAjPcaGdOVSU7zUT4aSlcb/BDGYwISdwYHnGThfU6gLRW+OppGvVOTNvibEiCGQ44yCeT9/TQez3qQST2G01EG6uMMCrvTMxBxt8xBAyff01dQTrBKHzWdv1WW2wK1Oh6jn6juc3T3T9Upp62FRKXYF41VeWkXHBIxu74JGdCeqOkL1bvFpxSkSQBGp9uNpjxtO1eDj/l7A62z4cfCnpPoenpLhUXq3teJFZaqZK2IIGJyyRrngYwPudJfXr2/qC43aKkrKeJ6dJg0grEKnBzkHPGRwdVN9rpuJ9oHlFd0CwgkVw5wcZz0xSV0Ve6mutjU9XFMlZE4pYmps7iQeWDehHb99Fqa6QolX40U0sssM9JNDEwVA74CQgnls43EnjI1m09+nstTDdbbeqWNw7qQsy42Kf0ztz9WM5/vq/T9XfxOSkvFqNMtTHUITvqUXDEEFlzznPv/AJaf02drCVgvuN+lE1iWPVbMPMf/AFj/AP0KfbjWUVqsMVealoZaGeOWaJFMnjRyr4bRhO5JO38d9aj0T8PBb7TDfY6Zaa6V9NIatiquiCUDgIeCAQB2xwdZF0LRU/WPVdu6cu15ppoTMZalFqo1jEEQyXxngg4GfXXXaVfSlTTSij6js/yzLiKJqyMPGpAG0Dd9idL+0+pmVUhiPx/esvZwDljXPXxn6OvVLardVR26OorqNkpY6mNgGlUnOcKAABknPtxpOh2w2aOtkvMMdRTSxuzqh82CVZQewx6ng62j4k3bpys6bittT1LQxJBOVMUc6O8qrxg8kKCcfuNYDR3CgNPcKZbrDTfJTkGOWSN45jjltpOBnIz+NK6TOXTDHmriymFvMVPQ1dq4qEUnzFLVbZKpSI1kdlhIAPp9O3BJBJ9PvqjQ9SVVwRqRJlp46eGKGWKpjJ8TwwVcpjuXyDj2xocbhFVVlFZ4Xopkmifez1KHxMJtAKZ2p3JHfRisorJSNbLdb6uKqcFhinqkBRgoBypOA33zqye/FqNueTVp/jDqjl0wQO+R+lXOgeqOoeiOskqrIZwxR2qYpSQhjOCC6v2GP5hyNdWdF/FrpDqqGngesSkufiGBopxgSH1CE8OuMYI5+2udbYtsoY45P4rSyO8TF0lqovEiQsAUyDhySATz240r9dV1nUeDFf4KaqgqvmRJHMm3C4clCDwWbC4HGM6orl1v5eRVxcez0NvZb3fzAdM10R8YKqa3RVM9U6LHvSSFqctI4I4diOAo24B/OshoIrb1VaaMz17eA9OHaCcndAzBhIzyIfEbKhcZzggHjSHU/Em8vRVdFJ1LHXfNtMQlU6u0TMDkLk8+4J/7aqWfqqOmlUyVcKrSxRSxDxhG1QZF2mN3BJIDdxjGtBogbTmZXYFT9/zXn14iSxhl94VeuHS92t9VFWU1ZRXCWokCg+IFk8pBEgB58PHG48d/XRz4m9KVHRFfPY68A0lVSLcYwI1ZAGAJCt/MVfvn00y09wt0VA9oFTaRTpDLC0/ixvjCh8hgQxXBYd++kv4p9S1FXY6CyXyqp6mht9Qk1LVxVSPJ8tJHwh57H1B5GNOatabts9uwx3GRS9nOUYbuD2rQ/ihYlu8vSvXsFveshewpTzwUj7JfCmj2GWPkbnDDOAckdtc/VtX0tNfY7P0ZJeLhbenLXLQ+LcUaOeqmkcM64zwEYYwffTjbvjPTJ0X0/bmulOJrOghUFlfCLIwBPPPBBxoPapbbXV0l9hko1kqJ/HqYo3SGNiWzhtpGMkZzyedZm0g8GYsx4zxVwqtdsdtX7f03VVURqaiFKSOGNGTdMDncePKRwB3xnkjRq5xw2q2pUQeHVuIGlq9iELHGrdt3rnkfbJ76ICr6bFOlTJfKRKiSndGMsyNtfkxAAHk9xk9h30IrquxSWeSGkneJaioaN4kqowjLkFlHPl82T9+2reVldSpIq6s7aO2YSD3h3zRy0StcLVHX19PTNPnEX6ZLLj6cMPTbjn7aYunfiL1v0yksNnqjXwCFoV+akz5c71wW9c5H37azeyXKz0bVdBcLvTSPAAsASYbWUDAyTxyvcD1Gmm23S208bRVF5tqrNEdpM6BWAXjufLj0GsdqO+2uAByK9U0qw0rXdPJu9u/14B+taJU/4gesYII5qm2UsTIfFqTTLkJHjB2K3HORn20mXz/Ex1vcaG4Uz2e2okh+VCLJsdgFHmyO6nuTjvqnd+qLDW0D1oqaCeYQGFgJkAUFe4APPA0gXpKGe6pPG9B4VWiNHKkqqkII+5yBkdhzzqz0+3FwQWiGK899o9I0zTG220+T6dcfDivI+I1bZ+rjPXwBqUn5mSlgcwmQFgzqDjAYEYBA7HW89K9T9L9T9FN1JdYJqJJ1lp5/BhNRDTOGzGVJYeYA+3OTzrDKiy2urhjluVRQmpmURU8ElQm8s4JFR3yAAMFSfXTfdLX0DZaG2W3oXqMSwXKCnuFXTTVCqYSEx4Wc+YGTc3v2B01r0X4Sy8TPm6DBzWRstss+zt3PStAorZ8PZY/4Xa66spPHx8u1NRrGKY7QG2iSRsliMksDg8DA1hPxttdpt1TdbPZribmailzNHUxBJaeoQ5G0JhcnOcHI9tbRbrBT0vVNL05euobbE9TTwTyTirjdYxKvAyG7jjPtpE+IMPR9D1dLaviDU083kSNK231UbmaPnwzuB5TI/wCoaw+n380V0rT5Kd+KuZIldSIzg/Ouapai7WWggr0tlRJ4WJEl27VglUecH0GtV6Z+Jkd+tdHS1c9Q9VTCNZNrnKkcv5s8IQQcY/Gh/WD01r6b+Zr6uiKRSs0qmaMYVTjIUMSzOp9R3GRrOOrZLX8POpYaqz1G+gkgRXijlEjzI6jzd85GcZ/vr017gWrJLF0YVTYNyngy9Aev80Z+LV8qrlFVUEVVTzpEQ0skMARVA5HnAG844J59NL3wbpIpbXdpzKYT44CFSfEkJ9QPXGvnWPUFBU2eOgoKim21MW9h4oBCjnHB7/21d+Ed1s9N0lIlVOxV6tv0xOqmTGPqP21XT3EtyjORj4Vq9PtLKxmVN4bjJPT8q//Z') 0 0 no-repeat; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/ieCompatTrue.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/ieCompatTrue.css deleted file mode 100644 index 3552ce11..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/ieCompatTrue.css +++ /dev/null @@ -1,5 +0,0 @@ -body { - width: 288px; - height: 288px; - background: transparent url('include/bob.jpg') 0 0 no-repeat; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual/level2/style3.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual/level2/style3.css deleted file mode 100644 index ef8eb942..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual/level2/style3.css +++ /dev/null @@ -1,3 +0,0 @@ -body { - color: #ffffff; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual/style.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual/style.css deleted file mode 100644 index ef8eb942..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual/style.css +++ /dev/null @@ -1,3 +0,0 @@ -body { - color: #ffffff; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual/style2.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual/style2.css deleted file mode 100644 index 3eb69319..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual/style2.css +++ /dev/null @@ -1,3 +0,0 @@ -#header { - background: #ffffff; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual_flatten/style.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual_flatten/style.css deleted file mode 100644 index ef8eb942..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual_flatten/style.css +++ /dev/null @@ -1,3 +0,0 @@ -body { - color: #ffffff; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual_flatten/style2.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual_flatten/style2.css deleted file mode 100644 index 3eb69319..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual_flatten/style2.css +++ /dev/null @@ -1,3 +0,0 @@ -#header { - background: #ffffff; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual_flatten/style3.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual_flatten/style3.css deleted file mode 100644 index ef8eb942..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/individual_flatten/style3.css +++ /dev/null @@ -1,3 +0,0 @@ -body { - color: #ffffff; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/less.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/less.css deleted file mode 100644 index ef8eb942..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/less.css +++ /dev/null @@ -1,3 +0,0 @@ -body { - color: #ffffff; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/nomatches.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/nomatches.css deleted file mode 100644 index e69de29b..00000000 diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/nopaths.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/nopaths.css deleted file mode 100644 index ef8eb942..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/nopaths.css +++ /dev/null @@ -1,3 +0,0 @@ -body { - color: #ffffff; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/variablesAsLess.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/variablesAsLess.css deleted file mode 100644 index 3eb69319..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/expected/variablesAsLess.css +++ /dev/null @@ -1,3 +0,0 @@ -#header { - background: #ffffff; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/customFunctions.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/customFunctions.less deleted file mode 100644 index ac4a4608..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/customFunctions.less +++ /dev/null @@ -1,5 +0,0 @@ -.myRule { - background-color: get-color(red); - width: multiple-args(1px, 4px); - background: string-result(3); -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/ieCompat.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/ieCompat.less deleted file mode 100644 index 20463e6d..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/ieCompat.less +++ /dev/null @@ -1,5 +0,0 @@ -body { - width: 288px; - height: 288px; - background: transparent data-uri('include/bob.jpg') 0 0 no-repeat; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/include/bob.jpg b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/include/bob.jpg deleted file mode 100644 index d4e2a46206912b69de989ec32d33201254f29cd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65127 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%0DNvkIskG+OJisB;7$=mYNU-BBx-|zuB9x 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 PD;bqHhT|mk{Hy=jCtBRv diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/include/variables.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/include/variables.less deleted file mode 100644 index 48a21133..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/include/variables.less +++ /dev/null @@ -1 +0,0 @@ -@color: #ffffff; diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/include/variablesAsLess.css b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/include/variablesAsLess.css deleted file mode 100644 index 48a21133..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/include/variablesAsLess.css +++ /dev/null @@ -1 +0,0 @@ -@color: #ffffff; diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/level2/style3.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/level2/style3.less deleted file mode 100644 index 2a2f0d3b..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/level2/style3.less +++ /dev/null @@ -1,4 +0,0 @@ -@import "variables.less"; -body { - color: @color; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/nopaths.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/nopaths.less deleted file mode 100644 index dcb229ab..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/nopaths.less +++ /dev/null @@ -1,4 +0,0 @@ -@import "include/variables.less"; -body { - color: @color; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/style.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/style.less deleted file mode 100644 index 95ac28a1..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/style.less +++ /dev/null @@ -1,4 +0,0 @@ -@import "variables.less"; -body { - color: @color; -} \ No newline at end of file diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/style2.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/style2.less deleted file mode 100644 index 8478aa11..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/style2.less +++ /dev/null @@ -1,4 +0,0 @@ -@import "variables.less"; -#header { - background: @color; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/style3.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/style3.less deleted file mode 100644 index b6d23b13..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/style3.less +++ /dev/null @@ -1,4 +0,0 @@ -#footer { - color: #377; - background: #233; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/variablesAsLess.less b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/variablesAsLess.less deleted file mode 100644 index 97f7ef1b..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/fixtures/variablesAsLess.less +++ /dev/null @@ -1,4 +0,0 @@ -@import (less) "include/variablesAsLess.css"; -#header { - background: @color; -} diff --git a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/less_test.js b/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/less_test.js deleted file mode 100644 index 50a1fe58..00000000 --- a/apps/wiki/static--wiki--editor--node_modules--grunt-contrib-less--test/less_test.js +++ /dev/null @@ -1,130 +0,0 @@ -'use strict'; - -var grunt = require('grunt'); -var fs = require('fs'); - -exports.less = { - compile: function(test) { - test.expect(2); - - var actual = grunt.file.read('tmp/less.css'); - var expected = grunt.file.read('test/expected/less.css'); - test.equal(expected, actual, 'should compile less, with the ability to handle imported files from alternate include paths'); - - actual = grunt.file.read('tmp/concat.css'); - expected = grunt.file.read('test/expected/concat.css'); - test.equal(expected, actual, 'should concat output when passed an array'); - - test.done(); - }, - compress: function(test) { - test.expect(1); - - var actual = grunt.file.read('tmp/compress.css'); - var expected = grunt.file.read('test/expected/compress.css'); - test.equal(expected, actual, 'should compress output when compress option is true'); - - test.done(); - }, - nopaths: function(test) { - test.expect(1); - - var actual = grunt.file.read('tmp/nopaths.css'); - var expected = grunt.file.read('test/expected/nopaths.css'); - test.equal(expected, actual, 'should default paths to the dirname of the less file'); - - test.done(); - }, - cleancss: function(test) { - test.expect(2); - - var actual = grunt.file.read('tmp/cleancss.css'); - var expected = grunt.file.read('test/expected/cleancss.css'); - test.equal(expected, actual, 'should cleancss output when cleancss option is true'); - - actual = grunt.file.read('tmp/cleancssReport.css'); - expected = grunt.file.read('test/expected/cleancssReport.css'); - test.equal(expected, actual, 'should cleancss output when cleancss option is true and concating is enable'); - - test.done(); - }, - ieCompat: function(test) { - test.expect(2); - - var actual = grunt.file.read('tmp/ieCompatFalse.css'); - var expected = grunt.file.read('test/expected/ieCompatFalse.css'); - test.equal(expected, actual, 'should generate data-uris no matter the size when ieCompat option is true'); - - actual = grunt.file.read('tmp/ieCompatTrue.css'); - expected = grunt.file.read('test/expected/ieCompatTrue.css'); - test.equal(expected, actual, 'should generate data-uris only when under the 32KB mark for Internet Explorer 8'); - - test.done(); - }, - variablesAsLess: function(test) { - test.expect(1); - - var actual = grunt.file.read('tmp/variablesAsLess.css'); - var expected = grunt.file.read('test/expected/variablesAsLess.css'); - test.equal(expected, actual, 'should process css files imported less files'); - - test.done(); - }, - sourceMap: function(test) { - test.expect(1); - - var actual = grunt.file.read('tmp/sourceMap.css'); - test.ok(actual.indexOf('/*# sourceMappingURL=') !== -1, 'compiled file should include a source map.'); - - test.done(); - }, - sourceMapFilename: function(test) { - test.expect(1); - - var sourceMap = grunt.file.readJSON('tmp/sourceMapFilename.css.map'); - test.equal(sourceMap.sources[0], 'test/fixtures/style3.less', 'should generate a sourceMap with the less file reference.'); - - test.done(); - }, - sourceMapURL: function(test) { - test.expect(1); - - var actual = grunt.file.read('tmp/sourceMapWithCustomURL.css'); - test.ok(actual.indexOf('/*# sourceMappingURL=custom/url/for/sourceMap.css.map') !== -1, 'compiled file should have a custom source map URL.'); - test.done(); - }, - sourceMapBasepath: function(test) { - test.expect(1); - - var sourceMap = grunt.file.readJSON('tmp/sourceMapBasepath.css.map'); - test.equal(sourceMap.sources[0], 'style3.less', 'should use the basepath for the less file references in the generated sourceMap.'); - - test.done(); - }, - sourceMapRootpath: function(test) { - test.expect(1); - - var sourceMap = grunt.file.readJSON('tmp/sourceMapRootpath.css.map'); - test.equal(sourceMap.sources[0], 'http://example.org/test/fixtures/style3.less', 'should use the rootpath for the less file references in the generated sourceMap.'); - - test.done(); - }, - sourceMapLessInline: function(test) { - test.expect(1); - - var expected = grunt.file.read('test/fixtures/style3.less'); - var sourceMap = grunt.file.readJSON('tmp/sourceMapLessInline.css.map'); - test.equal(sourceMap.sourcesContent[0], expected, 'should put the less file into the generated sourceMap instead of referencing them.'); - - test.done(); - }, - customFunctions: function(test) { - test.expect(1); - - var actual = grunt.file.read('tmp/customFunctions.css'); - var expected = grunt.file.read('test/expected/customFunctions.css'); - test.equal(expected, actual, 'should execute custom functions'); - - test.done(); - } -}; diff --git a/apps/wiki/templates/wiki/document_details.html b/apps/wiki/templates/wiki/document_details.html deleted file mode 100644 index db003d2c..00000000 --- a/apps/wiki/templates/wiki/document_details.html +++ /dev/null @@ -1,49 +0,0 @@ -{% extends "wiki/document_details_base.html" %} -{% load i18n %} - -{% block extrabody %} -{{ block.super }} -<script src="{{ STATIC_URL }}js/lib/codemirror-0.8/codemirror.js" type="text/javascript" charset="utf-8"> -</script> -<script src="{{ STATIC_URL }}js/wiki/loader.js" type="text/javascript" charset="utf-8"> </script> -{% endblock %} - -{% block tabs-menu %} - {% include "wiki/tabs/summary_view_item.html" %} - {% include "wiki/tabs/wysiwyg_editor_item.html" %} - {% include "wiki/tabs/source_editor_item.html" %} - {% include "wiki/tabs/history_view_item.html" %} -{% endblock %} - -{% block tabs-content %} - {% include "wiki/tabs/summary_view.html" %} - {% include "wiki/tabs/wysiwyg_editor.html" %} - {% include "wiki/tabs/source_editor.html" %} - {% include "wiki/tabs/history_view.html" %} -{% endblock %} - -{% block tabs-right %} - {% include "wiki/tabs/gallery_view_item.html" %} - {% include "wiki/tabs/annotations_view_item.html" %} - {% include "wiki/tabs/search_view_item.html" %} -{% endblock %} - -{% block splitter-extra %} -<div class="vsplitbar" title="{% trans "Click to open/close gallery" %}"> - <p class="vsplitbar-title"></p> - </div> - <div id="sidebar"> - {% include "wiki/tabs/gallery_view.html" %} - {% include "wiki/tabs/annotations_view.html" %} - {% include "wiki/tabs/search_view.html" %} - </div> -{% endblock %} - -{% block dialogs %} - {% include "wiki/save_dialog.html" %} - {% include "wiki/revert_dialog.html" %} - {% include "wiki/tag_dialog.html" %} - {% if can_pubmark %} - {% include "wiki/pubmark_dialog.html" %} - {% endif %} -{% endblock %} diff --git a/apps/wiki/templates/wiki/document_details_base.html b/apps/wiki/templates/wiki/document_details_base.html deleted file mode 100644 index e164a9ee..00000000 --- a/apps/wiki/templates/wiki/document_details_base.html +++ /dev/null @@ -1,58 +0,0 @@ -{% extends "base.html" %} -{% load toolbar_tags i18n %} - -{% block title %}{{ book.title }} - {{ block.super }}{% endblock %} -{% block extrahead %} -{% load compressed %} -{% compressed_css 'detail' %} -{% endblock %} - -{% block extrabody %} -<script type="text/javascript" charset="utf-8"> - var STATIC_URL = '{{STATIC_URL}}'; -</script> -{% compressed_js 'detail' %} -{% endblock %} - -{% block maincontent %} -<div id="document-meta" - data-chunk-id="{{ chunk.pk }}" style="display:none"> - - <span data-key="gallery">{{ chunk.book.gallery }}</span> - <span data-key="gallery-start">{% if chunk.gallery_start %}{{ chunk.gallery_start }}{% endif %}</span> - <span data-key="revision">{{ revision }}</span> - <span data-key="diff">{{ request.GET.diff }}</span> - - {% block meta-extra %} {% endblock %} -</div> - -<div id="header"> - <h1><a href="{% url 'catalogue_document_list' %}"><img src="{{STATIC_URL}}icons/go-home.png"/><a href="{% url 'catalogue_document_list' %}">Strona<br>gÅówna</a></h1> - <div id="tools"> - <a href="{{ REDMINE_URL }}projects/wl-publikacje/wiki/Pomoc" target="_blank"> - {% trans "Help" %}</a> - | {% include "registration/head_login.html" %} - | {% trans "Version" %}: <span id="document-revision">{% trans "Unknown" %}</span> - {% if not readonly %} - | <button style="margin-left: 6px" id="save-button">{% trans "Save" %}</button> - <span id='save-attempt-info'>{% trans "Save attempt in progress" %}</span> - <span id='out-of-date-info'>{% trans "There is a newer version of this document!" %}</span> - {% endif %} - </div> - <ol id="tabs" class="tabs"> - {% block tabs-menu %} {% endblock %} - </ol> - <ol id="tabs-right" class="tabs"> - {% block tabs-right %} {% endblock %} - </ol> -</div> -<div id="splitter"> - <div id="editor" class="{% block editor-class %} {% endblock %}"> - {% block tabs-content %} {% endblock %} - </div> - {% block splitter-extra %} {% endblock %} -</div> - -{% block dialogs %} {% endblock %} - -{% endblock %} diff --git a/apps/wiki/templates/wiki/document_details_readonly.html b/apps/wiki/templates/wiki/document_details_readonly.html deleted file mode 100644 index 71556a19..00000000 --- a/apps/wiki/templates/wiki/document_details_readonly.html +++ /dev/null @@ -1,27 +0,0 @@ -{% extends "wiki/document_details_base.html" %} -{% load i18n %} - -{% block editor-class %}readonly{% endblock %} - -{% block extrabody %} -{{ block.super }} -<script src="{{STATIC_URL}}js/lib/codemirror-0.8/codemirror.js" type="text/javascript" charset="utf-8"> -</script> -<script src="{{STATIC_URL}}js/wiki/loader_readonly.js" type="text/javascript" charset="utf-8"> </script> -{% endblock %} - -{% block tabs-menu %} - {% include "wiki/tabs/wysiwyg_editor_item.html" %} - {% include "wiki/tabs/source_editor_item.html" %} -{% endblock %} - -{% block tabs-content %} - {% include "wiki/tabs/wysiwyg_editor.html" %} - {% include "wiki/tabs/source_editor.html" %} -{% endblock %} - -{% block splitter-extra %} -{% endblock %} - -{% block dialogs %} -{% endblock %} \ No newline at end of file diff --git a/apps/wiki/templates/wiki/tabs/history_view.html b/apps/wiki/templates/wiki/tabs/history_view.html deleted file mode 100644 index 93b0bb64..00000000 --- a/apps/wiki/templates/wiki/tabs/history_view.html +++ /dev/null @@ -1,41 +0,0 @@ -{% load i18n %} -<div id="history-view-editor" class="editor" style="display: none"> - <div class="toolbar"> - <button type="button" id="make-diff-button" - data-enabled-when="2" disabled="disabled">{% trans "Compare versions" %}</button> - {% if can_pubmark %} - <button type="button" id="pubmark-changeset-button" - data-enabled-when="1" disabled="disabled">{% trans "Mark for publishing" %}</button> - {% endif %} - <button type="button" id="doc-revert-button" - data-enabled-when="1" disabled="disabled">{% trans "Revert document" %}</button> - <button id="open-preview-button" disabled="disabled" - data-enabled-when="1" - data-basehref="{% url 'wiki_editor_readonly' chunk.book.slug chunk.slug %}">{% trans "View version" %}</button> - - </div> - <div id="history-view"> - <p class="message-box" style="display:none;"></p> - - <table id="changes-list-container"> - <tbody id="changes-list"> - </tbody> - <tbody style="display: none;"> - <tr class="entry row-stub"> - <td data-stub-value="version"></td> - <td> - <span data-stub-value="date"></span> - <br/><span data-stub-value="author"></span> - <br /> - <span data-stub-value="description"></span> - </td> - <td> - <div data-stub-value="publishable"></div> - <div data-stub-value="published"></div> - <div data-stub-value="tag"></div> - </td> - </tr> - </tbody> - </table> - </div> -</div> diff --git a/apps/wiki/templates/wiki/tabs/history_view_item.html b/apps/wiki/templates/wiki/tabs/history_view_item.html deleted file mode 100644 index bf39a333..00000000 --- a/apps/wiki/templates/wiki/tabs/history_view_item.html +++ /dev/null @@ -1,4 +0,0 @@ -{% load i18n %} -<li id="HistoryPerspective" data-ui-related="history-view-editor" data-ui-jsclass="HistoryPerspective"> - <span>{% trans "History" %}</span> -</li> diff --git a/apps/wiki/templates/wiki/tabs/summary_view.html b/apps/wiki/templates/wiki/tabs/summary_view.html deleted file mode 100644 index 8a57769e..00000000 --- a/apps/wiki/templates/wiki/tabs/summary_view.html +++ /dev/null @@ -1,44 +0,0 @@ -{% load i18n %} -<div id="summary-view-editor" class="editor" style="display: none"> - <!-- <div class="toolbar"> - </div> --> - <div id="summary-view"> - <div class="summary-cover-area"> - <p><img id="summary-cover" class="book-cover" - {% if revision %} - src="{% url 'cover_preview' chunk.book.slug chunk.slug revision %}" - {% else %} - src="{% url 'cover_preview' chunk.book.slug chunk.slug %}" - {% endif %}></p> - <p><button id="summary-cover-refresh">{% trans "Refresh from working copy" %}</button></p> - </div> - - <h2> - <label for="title">{% trans "Title" %}:</label> - <span data-ui-editable="true" data-edit-target="meta.displayTitle" - >{{ chunk.pretty_name }}</span> - </h2> - <p><a href="{{ chunk.book.get_absolute_url }}">{% trans "Go to the book's page" %}</a> - </p> - <p> - <label>{% trans "Document ID" %}:</label> - <span>{{ chunk.book.slug }}/{{ chunk.slug }}</span> - </p> - <p> - <label>{% trans "Current version" %}:</label> - {{ chunk.revision }} ({{ chunk.head.created_at }}) - <p> - <label>{% trans "Last edited by" %}:</label> - {{ chunk.head.author }} - </p> - <p> - <label for="gallery">{% trans "Link to gallery" %}:</label> - <span data-ui-editable="true" data-edit-target="meta.galleryLink" - >{{ chunk.book.gallery }}</span> - </p> - <p> - <label>{% trans "Characters in document" %}:</label> - <span id="charcount"></span> (<span id="charcount_pages"></span> {% trans "pages" %}<span id="charcount_untagged">, {% trans "untagged" %}</span>) - </p> - </div> -</div> diff --git a/apps/wiki/templates/wiki/tabs/summary_view_item.html b/apps/wiki/templates/wiki/tabs/summary_view_item.html deleted file mode 100644 index 856b3d70..00000000 --- a/apps/wiki/templates/wiki/tabs/summary_view_item.html +++ /dev/null @@ -1,4 +0,0 @@ -{% load i18n %} -<li id="SummaryPerspective" data-ui-related="summary-view-editor" data-ui-jsclass="SummaryPerspective"> - <span>{% trans "Summary" %}</span> -</li> diff --git a/apps/wiki/urls.py b/apps/wiki/urls.py index ee13b850..69472103 100644 --- a/apps/wiki/urls.py +++ b/apps/wiki/urls.py @@ -2,22 +2,17 @@ from django.conf.urls import patterns, url -urlpatterns = patterns('wiki.views', +urlpatterns = patterns( + 'wiki.views', url(r'^edit/(?P<pk>[^/]+)/$', 'editor', name="wiki_editor"), - url(r'^readonly/(?P<pk>[^/]+)/$', - 'editor_readonly', name="wiki_editor_readonly"), - url(r'^gallery/(?P<directory>[^/]+)/$', 'gallery', name="wiki_gallery"), url(r'^history/(?P<doc_id>\d+)/$', 'history', name="wiki_history"), - url(r'^rev/(?P<chunk_id>\d+)/$', - 'revision', name="wiki_revision"), - url(r'^text/(?P<doc_id>\d+)/$', 'text', name="wiki_text"), diff --git a/apps/wiki/views.py b/apps/wiki/views.py index 9a17faab..1b16077f 100644 --- a/apps/wiki/views.py +++ b/apps/wiki/views.py @@ -1,28 +1,29 @@ -from datetime import datetime +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# import json import os import logging import urllib from django.conf import settings -from django.core.urlresolvers import reverse from django import http -from django.http import Http404, HttpResponseForbidden +from django.http import HttpResponseForbidden from django.middleware.gzip import GZipMiddleware from django.utils.decorators import decorator_from_middleware from django.utils.encoding import smart_unicode from django.utils.formats import localize from django.utils.translation import ugettext as _ -from django.views.decorators.http import require_POST, require_GET +from django.views.decorators.http import require_POST from django.shortcuts import get_object_or_404, render -from django.contrib.auth.decorators import login_required from catalogue.models import Document, Template from dvcs.models import Revision import nice_diff from wiki import forms -from wiki.helpers import (JSONResponse, JSONFormInvalid, JSONServerError, - ajax_require_permission) +from wiki.helpers import JSONResponse, JSONFormInvalid # # Quick hack around caching problems, TODO: use ETags @@ -38,38 +39,25 @@ def get_history(document): revisions = [] for i, revision in enumerate(document.history()): revisions.append({ - "version": i + 1, - "description": revision.description, - "author": revision.author_str(), - "date": localize(revision.created_at), - "published": "", - "revision": revision.pk, - "published": _("Published") + ": " + \ - localize(revision.publish_log.order_by('-timestamp')[0].timestamp) \ - if revision.publish_log.exists() else "", - }) + "version": i + 1, + "description": revision.description, + "author": revision.author_str(), + "date": localize(revision.created_at), + "revision": revision.pk, + "published": _("Published") + ": " + + localize(revision.publish_log.order_by('-timestamp')[0].timestamp) + if revision.publish_log.exists() else "", + }) return revisions @never_cache -#@login_required -def editor(request, pk, chunk=None, template_name='wiki/bootstrap.html'): +def editor(request, pk, template_name='wiki/bootstrap.html'): doc = get_object_or_404(Document, pk=pk, deleted=False) - #~ if not doc.accessible(request): - #~ return HttpResponseForbidden("Not authorized.") - - access_time = datetime.now() save_form = forms.DocumentTextSaveForm(user=request.user, prefix="textsave") - try: - version = int(request.GET.get('version', None)) - except: - version = None - if version: - text = doc.at_revision(version).materialize() - else: - text = doc.materialize() - revision = doc.revision + text = doc.materialize() + revision = doc.revision history = get_history(doc) return render(request, template_name, { 'serialized_document_data': json.dumps({ @@ -77,7 +65,7 @@ def editor(request, pk, chunk=None, template_name='wiki/bootstrap.html'): 'document_id': doc.pk, 'title': doc.meta().get('title', ''), 'history': history, - 'version': len(history), #version or chunk.revision(), + 'version': len(history), 'revision': revision.pk, 'stage': doc.stage, 'assignment': str(doc.assigned_to), @@ -94,42 +82,12 @@ def editor(request, pk, chunk=None, template_name='wiki/bootstrap.html'): }) -@require_GET -def editor_readonly(request, slug, chunk=None, template_name='wiki/document_details_readonly.html'): - try: - chunk = Chunk.get(slug, chunk) - revision = request.GET['revision'] - except (Chunk.MultipleObjectsReturned, Chunk.DoesNotExist, KeyError): - raise Http404 - if not chunk.book.accessible(request): - return HttpResponseForbidden("Not authorized.") - - access_time = datetime.now() - last_books = request.session.get("wiki_last_books", {}) - last_books[slug, chunk.slug] = { - 'time': access_time, - 'title': chunk.book.title, - } - - if len(last_books) > MAX_LAST_DOCS: - oldest_key = min(last_books, key=lambda x: last_books[x]['time']) - del last_books[oldest_key] - request.session['wiki_last_books'] = last_books - - return render(request, template_name, { - 'chunk': chunk, - 'revision': revision, - 'readonly': True, - 'REDMINE_URL': settings.REDMINE_URL, - }) - - @never_cache @decorator_from_middleware(GZipMiddleware) def text(request, doc_id): doc = get_object_or_404(Document, pk=doc_id, deleted=False) - #~ if not doc.book.accessible(request): - #~ return HttpResponseForbidden("Not authorized.") + # if not doc.book.accessible(request): + # return HttpResponseForbidden("Not authorized.") if request.method == 'POST': form = forms.DocumentTextSaveForm(request.POST, user=request.user, prefix="textsave") @@ -139,33 +97,33 @@ def text(request, doc_id): else: author = None text = form.cleaned_data['text'] - #~ parent_revision = form.cleaned_data['parent_revision'] - #~ if parent_revision is not None: - #~ parent = doc.at_revision(parent_revision) - #~ else: - #~ parent = None + # parent_revision = form.cleaned_data['parent_revision'] + # if parent_revision is not None: + # parent = doc.at_revision(parent_revision) + # else: + # parent = None stage = form.cleaned_data['stage'] - #~ tags = [stage] if stage else [] - #~ publishable = (form.cleaned_data['publishable'] and - #~ request.user.has_perm('catalogue.can_pubmark')) + # tags = [stage] if stage else [] + # publishable = (form.cleaned_data['publishable'] and + # request.user.has_perm('catalogue.can_pubmark')) try: - doc.commit(author=author, - text=text, - parent=False, - description=form.cleaned_data['comment'], - author_name=form.cleaned_data['author_name'], - author_email=form.cleaned_data['author_email'], - ) + doc.commit( + author=author, + text=text, + description=form.cleaned_data['comment'], + author_name=form.cleaned_data['author_name'], + author_email=form.cleaned_data['author_email'], + ) doc.set_stage(stage) except: from traceback import print_exc print_exc() raise - #revision = doc.revision() + # revision = doc.revision() return JSONResponse({ - 'text': None, #doc.materialize() if parent_revision != revision else None, - #'version': revision, - #'stage': doc.stage.name if doc.stage else None, + 'text': None, # doc.materialize() if parent_revision != revision else None, + # 'version': revision, + # 'stage': doc.stage.name if doc.stage else None, 'assignment': doc.assigned_to.username if doc.assigned_to else None }) else: @@ -206,20 +164,20 @@ def revert(request, doc_id): else: author = None - #before = doc.revision + # before = doc.revision logger.info("Reverting %s to %s", doc_id, rev.pk) - doc.commit(author=author, - text=rev.materialize(), - parent=False, #? - description=comment, - #author_name=form.cleaned_data['author_name'], #? - #author_email=form.cleaned_data['author_email'], #? - ) + doc.commit( + author=author, + text=rev.materialize(), + description=comment, + # author_name=form.cleaned_data['author_name'], #? + # author_email=form.cleaned_data['author_email'], #? + ) return JSONResponse({ - #'document': None, #doc.materialize() if before != doc.revision else None, - #'version': doc.revision(), + # 'document': None, #doc.materialize() if before != doc.revision else None, + # 'version': doc.revision(), }) else: return JSONFormInvalid(form) @@ -278,16 +236,7 @@ def diff(request, doc_id): docA = "" docB = Revision.objects.get(pk=revB).materialize() - return http.HttpResponse(nice_diff.html_diff_table(docA.splitlines(), - docB.splitlines(), context=3)) - - -@never_cache -def revision(request, chunk_id): - doc = get_object_or_404(Chunk, pk=chunk_id) - if not doc.book.accessible(request): - return HttpResponseForbidden("Not authorized.") - return http.HttpResponse(str(doc.revision())) + return http.HttpResponse(nice_diff.html_diff_table(docA.splitlines(), docB.splitlines(), context=3)) @never_cache diff --git a/deployment.py b/deployment.py index b989fc7a..e478a47d 100644 --- a/deployment.py +++ b/deployment.py @@ -1,13 +1,17 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from __future__ import with_statement -import shutil import os import sys import logging +from string import Template logging.basicConfig(stream=sys.stderr, format="%(levelname)s:: %(message)s", level=logging.INFO) -from string import Template class DeploySite(object): @@ -92,6 +96,7 @@ class DeploySite(object): site = cls(*args, **kwargs) return site.deploy() + class WSGISite(DeploySite): def __init__(self, **env): @@ -99,7 +104,7 @@ class WSGISite(DeploySite): if 'WSGI_FILE' not in self.env: self.env['WSGI_FILE'] = os.path.join(self.env['ROOT'], 'www', - 'wsgi', self.env['PROJECT_NAME']) + '.wsgi' + 'wsgi', self.env['PROJECT_NAME']) + '.wsgi' self.env['WSGI_DIR'] = os.path.dirname(self.env['WSGI_FILE']) @@ -119,6 +124,7 @@ class WSGISite(DeploySite): source = self.find_resource(self.env['WSGI_SOURCE_FILE']) self.render_template(source, self.env['WSGI_FILE']) + class PIPSite(DeploySite): def install_dependencies(self): @@ -131,12 +137,14 @@ class PIPSite(DeploySite): except ValueError: pass + class GitSite(DeploySite): def update_app(self): self.info("Updating repository.") os.system("cd %s; git pull" % self.env['APP_DIR']) + class ApacheSite(DeploySite): def __init__(self, **env): diff --git a/lib/librarian b/lib/librarian index 25af49b6..d1037d61 160000 --- a/lib/librarian +++ b/lib/librarian @@ -1 +1 @@ -Subproject commit 25af49b6c63e1c005129856e107143864ad5b245 +Subproject commit d1037d617d8cd2cafc60e67ac0272f86d2e24dfa diff --git a/redakcja/context_processors.py b/redakcja/context_processors.py index 6ba41c6b..8aaf6933 100644 --- a/redakcja/context_processors.py +++ b/redakcja/context_processors.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 + def settings(request): from django.conf import settings diff --git a/redakcja/forms.py b/redakcja/forms.py index 22f3bab6..16ad87e7 100644 --- a/redakcja/forms.py +++ b/redakcja/forms.py @@ -1,5 +1,11 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django import forms + class RegistrationForm(forms.Form): first_name = forms.CharField() last_name = forms.CharField() diff --git a/redakcja/settings/__init__.py b/redakcja/settings/__init__.py index 4d4fe8fb..2d04c8dc 100644 --- a/redakcja/settings/__init__.py +++ b/redakcja/settings/__init__.py @@ -1,11 +1,16 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from __future__ import absolute_import from os import path from redakcja.settings.common import * DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. - 'NAME': path.join(PROJECT_ROOT, 'dev.sqlite'), # Or path to database file if using sqlite3. + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': path.join(PROJECT_ROOT, 'dev.sqlite'), 'USER': '', # Not used with sqlite3. 'PASSWORD': '', # Not used with sqlite3. 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. @@ -13,11 +18,7 @@ DATABASES = { } } -try: - LOGGING_CONFIG_FILE -except NameError: - LOGGING_CONFIG_FILE = os.path.join(PROJECT_ROOT, 'config', - ('logging.cfg' if not DEBUG else 'logging.cfg.dev')) +LOGGING_CONFIG_FILE = os.path.join(PROJECT_ROOT, 'config', ('logging.cfg' if not DEBUG else 'logging.cfg.dev')) try: import logging diff --git a/redakcja/settings/common.py b/redakcja/settings/common.py index b5e7f097..c32b6ad9 100644 --- a/redakcja/settings/common.py +++ b/redakcja/settings/common.py @@ -26,8 +26,8 @@ TIME_ZONE = 'Europe/Warsaw' # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'en' -#import locale -#locale.setlocale(locale.LC_ALL, '') +# import locale +# locale.setlocale(locale.LC_ALL, '') SITE_ID = 1 @@ -71,7 +71,7 @@ TEMPLATE_CONTEXT_PROCESSORS = ( "django.contrib.auth.context_processors.auth", "django.core.context_processors.debug", "django.core.context_processors.i18n", - "redakcja.context_processors.settings", # this is instead of media + "redakcja.context_processors.settings", # this is instead of media 'django.core.context_processors.csrf', "django.core.context_processors.request", ) @@ -85,18 +85,18 @@ MIDDLEWARE_CLASSES = ( 'django.middleware.locale.LocaleMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', - #'django_cas.middleware.CASMiddleware', + # 'django_cas.middleware.CASMiddleware', 'django.contrib.admindocs.middleware.XViewMiddleware', 'pagination.middleware.PaginationMiddleware', - #'maintenancemode.middleware.MaintenanceModeMiddleware', + # 'maintenancemode.middleware.MaintenanceModeMiddleware', 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', ) -#AUTHENTICATION_BACKENDS = ( -# 'django.contrib.auth.backends.ModelBackend', -# 'fnpdjango.auth_backends.AttrCASBackend', -#) +# AUTHENTICATION_BACKENDS = ( +# 'django.contrib.auth.backends.ModelBackend', +# 'fnpdjango.auth_backends.AttrCASBackend', +# ) ROOT_URLCONF = 'redakcja.urls' @@ -116,24 +116,24 @@ INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.admindocs', 'django.contrib.flatpages', - #'django.contrib.comments', + # 'django.contrib.comments', - #'south', + # 'south', 'sorl.thumbnail', 'pagination', - #'gravatar', - #'kombu.transport.django', + # 'gravatar', + # 'kombu.transport.django', 'fileupload', 'pipeline', 'modeltranslation', 'catalogue', - 'cover', + # 'cover', 'dvcs', 'organizations', 'wiki', - #'toolbar', - #'apiclient', + # 'toolbar', + # 'apiclient', 'email_mangler', 'build', 'attachments', @@ -145,16 +145,16 @@ INSTALLED_APPS = ( LOGIN_REDIRECT_URL = '/' -#CAS_USER_ATTRS_MAP = { -# 'email': 'email', 'firstname': 'first_name', 'lastname': 'last_name'} +# CAS_USER_ATTRS_MAP = { +# 'email': 'email', 'firstname': 'first_name', 'lastname': 'last_name'} # REPOSITORY_PATH = '/Users/zuber/Projekty/platforma/files/books' IMAGE_DIR = 'images/' -#import djcelery -#djcelery.setup_loader() +# import djcelery +# djcelery.setup_loader() BROKER_BACKEND = "djkombu.transport.DatabaseTransport" BROKER_HOST = "localhost" @@ -170,9 +170,7 @@ FORMS_BUILDER_EDITABLE_SLUGS = True FORMS_BUILDER_LABEL_MAX_LENGTH = 2048 - try: from redakcja.settings.compress import * except ImportError: pass - diff --git a/redakcja/settings/compress.py b/redakcja/settings/compress.py index 05b3b15a..decfa166 100644 --- a/redakcja/settings/compress.py +++ b/redakcja/settings/compress.py @@ -1,7 +1,12 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', -# 'django.contrib.staticfiles.finders.DefaultStorageFinder', + # 'django.contrib.staticfiles.finders.DefaultStorageFinder', ) @@ -14,7 +19,7 @@ PIPELINE_STORAGE = 'pipeline.storage.PipelineFinderStorage' # CSS and JS files to compress PIPELINE_CSS = { 'detail': { - 'source_filenames': ( + 'source_filenames': ( 'css/master.css', 'css/toolbar.css', 'css/gallery.css', @@ -28,13 +33,13 @@ PIPELINE_CSS = { }, 'catalogue': { 'source_filenames': ( - #'css/filelist.css', + # 'css/filelist.css', 'css/base.css', 'datepicker/css/datepicker.css', ), 'output_filename': 'compressed/catalogue_styles.css', - }, - 'book': { + }, + 'book': { 'source_filenames': ( 'css/book.css', ), @@ -94,8 +99,8 @@ PIPELINE_JS = { 'datepicker/js/bootstrap-datepicker.js', ), 'output_filename': 'compressed/catalogue_scripts.js', - }, - 'book': { + }, + 'book': { 'source_filenames': ( 'js/book_text/jquery.eventdelegation.js', 'js/book_text/jquery.scrollto.js', diff --git a/redakcja/settings/integration_test.py b/redakcja/settings/integration_test.py index ba477bb0..36939319 100644 --- a/redakcja/settings/integration_test.py +++ b/redakcja/settings/integration_test.py @@ -1,7 +1,11 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from redakcja.settings.test import * NOSE_ARGS = () STATIC_ROOT_SYMLINK = os.path.dirname(STATIC_ROOT) + '_test' STATICFILES_DIRS.append(STATIC_ROOT_SYMLINK) - diff --git a/redakcja/settings/test.py b/redakcja/settings/test.py index d667ddd7..832e2c0e 100644 --- a/redakcja/settings/test.py +++ b/redakcja/settings/test.py @@ -1,15 +1,21 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# # # Nose tests # from redakcja.settings.common import * +import tempfile # ROOT_URLCONF = 'yourapp.settings.test.urls' DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. - 'NAME': '', # Or path to database file if using sqlite3. + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': '', # Or path to database file if using sqlite3. 'USER': '', # Not used with sqlite3. 'PASSWORD': '', # Not used with sqlite3. 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. @@ -17,7 +23,6 @@ DATABASES = { } } -import tempfile CATALOGUE_REPO_PATH = tempfile.mkdtemp(prefix='redakcja-repo') MEDIA_ROOT = tempfile.mkdtemp(prefix='media-root') @@ -26,8 +31,8 @@ USE_CELERY = False INSTALLED_APPS += ('django_nose', 'dvcs.tests') TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' -TEST_MODULES = ('catalogue', 'cover', 'dvcs.tests', 'wiki', 'toolbar') -COVER_APPS = ('catalogue', 'cover', 'dvcs', 'wiki', 'toolbar') +TEST_MODULES = ('catalogue', 'dvcs.tests', 'wiki', 'toolbar') +COVER_APPS = ('catalogue', 'dvcs', 'wiki', 'toolbar') NOSE_ARGS = ( '--tests=' + ','.join(TEST_MODULES), '--cover-package=' + ','.join(COVER_APPS), diff --git a/redakcja/static/css/html.css b/redakcja/static/css/html.css index 0d43611b..50a3e024 100644 --- a/redakcja/static/css/html.css +++ b/redakcja/static/css/html.css @@ -198,8 +198,7 @@ } /* bÅÄdne wersy */ -.htmlview *: -not(.strofa) > *[x-verse]::after { +.htmlview *:not(.strofa) > *[x-verse]::after { content: "Ten wers znajduje siÄ poza strofÄ ."; display: inline; background: red; @@ -418,7 +417,7 @@ div[x-node] > .uwaga { background-color: #ffcccc; } .htmlview .pe .annotation:hover { - background-color: #96e0e4;*/ + background-color: #96e0e4; } *.htmlview *.annotation-inline-box { position: static; diff --git a/redakcja/static/js/wiki/loader.js b/redakcja/static/js/wiki/loader.js deleted file mode 100644 index f2d7fb71..00000000 --- a/redakcja/static/js/wiki/loader.js +++ /dev/null @@ -1,151 +0,0 @@ -if (!window.console) { - window.console = { - log: function(){ - } - } -} - -var DEFAULT_PERSPECTIVE = "#VisualPerspective"; - -$(function() -{ - var tabs = $('ol#tabs li'); - var gallery = null; - CurrentDocument = new $.wikiapi.WikiDocument("document-meta"); - - $.blockUI.defaults.baseZ = 10000; - - function initialize() - { - $(document).keydown(function(event) { - console.log("Received key:", event); - }); - - /* The save button */ - $('#save-button').click(function(event){ - event.preventDefault(); - $.wiki.showDialog('#save_dialog'); - }); - - $('.editor').hide(); - - /* - * TABS - */ - $('.tabs li').live('click', function(event, callback) { - $.wiki.switchToTab(this); - }); - - $('#tabs li > .tabclose').live('click', function(event, callback) { - var $tab = $(this).parent(); - - if($tab.is('.active')) - $.wiki.switchToTab(DEFAULT_PERSPECTIVE); - - var p = $.wiki.perspectiveForTab($tab); - p.destroy(); - - return false; - }); - - - $(window).resize(function(){ - $('iframe').height($(window).height() - $('#tabs').outerHeight() - $('#source-editor .toolbar').outerHeight()); - }); - - $(window).resize(); - - $('.vsplitbar').toggle( - function() { - $.wiki.state.perspectives.ScanGalleryPerspective.show = true; - $('#sidebar').show(); - $('.vsplitbar').css('right', 480).addClass('active'); - $('#editor .editor').css('right', 510); - $(window).resize(); - $.wiki.perspectiveForTab('#tabs-right .active').onEnter(); - }, - function() { - var active_right = $.wiki.perspectiveForTab('#tabs-right .active'); - $.wiki.state.perspectives.ScanGalleryPerspective.show = false; - $('#sidebar').hide(); - $('.vsplitbar').css('right', 0).removeClass('active'); - $(".vsplitbar-title").html("↑ " + active_right.vsplitbar + " ↑"); - $('#editor .editor').css('right', 30); - $(window).resize(); - active_right.onExit(); - } - ); - - if($.wiki.state.perspectives.ScanGalleryPerspective.show){ - $('.vsplitbar').trigger('click'); - $(".vsplitbar-title").html("↓ GALERIA ↓"); - } else { - $(".vsplitbar-title").html("↑ GALERIA ↑"); - } - window.onbeforeunload = function(e) { - if($.wiki.isDirty()) { - e.returnValue = "Na stronie mogÄ byÄ nie zapisane zmiany."; - return "Na stronie mogÄ byÄ nie zapisane zmiany."; - }; - }; - - console.log("Fetching document's text"); - - $(document).bind('wlapi_document_changed', function(event, doc) { - try { - $('#document-revision').text(doc.revision); - } catch(e) { - console.log("Failed handler", e); - } - }); - - CurrentDocument.fetch({ - success: function(){ - console.log("Fetch success"); - $('#loading-overlay').fadeOut(); - var active_tab = document.location.hash || DEFAULT_PERSPECTIVE; - - if(active_tab == "#ScanGalleryPerspective") - active_tab = DEFAULT_PERSPECTIVE; - - console.log("Initial tab is:", active_tab) - $.wiki.switchToTab(active_tab); - - /* every 5 minutes check for a newer version */ - var revTimer = setInterval(function() { - CurrentDocument.checkRevision({outdated: function(){ - $('#header').addClass('out-of-date'); - clearInterval(revTimer); - }}); - }, 300000); - }, - failure: function() { - $('#loading-overlay').fadeOut(); - alert("FAILURE"); - } - }); - }; /* end of initialize() */ - - - /* Load configuration */ - $.wiki.loadConfig(); - - var initAll = function(a, f) { - if (a.length == 0) return f(); - - $.wiki.initTab({ - tab: a.pop(), - doc: CurrentDocument, - callback: function(){ - initAll(a, f); - } - }); - }; - - - /* - * Initialize all perspectives - */ - initAll( $.makeArray($('.tabs li')), initialize); - console.log(location.hash); -}); diff --git a/redakcja/static/js/wiki/view_summary.js b/redakcja/static/js/wiki/view_summary.js index 099a0e81..55b9e53b 100644 --- a/redakcja/static/js/wiki/view_summary.js +++ b/redakcja/static/js/wiki/view_summary.js @@ -12,10 +12,10 @@ }); old_callback.call(this); - } + }; $.wiki.Perspective.call(this, options); - }; + } SummaryPerspective.prototype = new $.wiki.Perspective(); diff --git a/redakcja/static/js/wiki/wikiapi.js b/redakcja/static/js/wiki/wikiapi.js index d901e847..d9a183c4 100644 --- a/redakcja/static/js/wiki/wikiapi.js +++ b/redakcja/static/js/wiki/wikiapi.js @@ -1,73 +1,73 @@ (function($) { - $.wikiapi = {}; - var noop = function() { - }; - var noops = { - success: noop, - failure: noop - }; - /* - * Return absolute reverse path of given named view. (at least he have it - * hard-coded in one place) - * - * TODO: think of a way, not to hard-code it here ;) - * - */ - function reverse() { - var vname = arguments[0]; - var base_path = "/editor"; - - if (vname == "ajax_document_text") { - var path = "/text/" + arguments[1] + '/'; - - if (arguments[2] !== undefined) - path += arguments[2] + '/'; - - return base_path + path; - } + $.wikiapi = {}; + var noop = function() { + }; + var noops = { + success: noop, + failure: noop + }; + /* + * Return absolute reverse path of given named view. (at least he have it + * hard-coded in one place) + * + * TODO: think of a way, not to hard-code it here ;) + * + */ + function reverse() { + var vname = arguments[0]; + var base_path = "/editor"; + + if (vname == "ajax_document_text") { + var path = "/text/" + arguments[1] + '/'; + + if (arguments[2] !== undefined) + path += arguments[2] + '/'; + + return base_path + path; + } if (vname == "ajax_document_revert") { return base_path + "/revert/" + arguments[1] + '/'; } - if (vname == "ajax_document_history") { + if (vname == "ajax_document_history") { - return base_path + "/history/" + arguments[1] + '/'; - } + return base_path + "/history/" + arguments[1] + '/'; + } - if (vname == "ajax_document_gallery") { + if (vname == "ajax_document_gallery") { - return base_path + "/gallery/" + arguments[1] + '/'; - } + return base_path + "/gallery/" + arguments[1] + '/'; + } - if (vname == "ajax_document_diff") - return base_path + "/diff/" + arguments[1] + '/'; + if (vname == "ajax_document_diff") + return base_path + "/diff/" + arguments[1] + '/'; if (vname == "ajax_document_rev") return base_path + "/rev/" + arguments[1] + '/'; - if (vname == "ajax_document_pubmark") - return base_path + "/pubmark/" + arguments[1] + '/'; + if (vname == "ajax_document_pubmark") + return base_path + "/pubmark/" + arguments[1] + '/'; - if (vname == "ajax_cover_preview") - return "/cover/preview/"; + if (vname == "ajax_cover_preview") + return "/cover/preview/"; - console.log("Couldn't reverse match:", vname); - return "/404.html"; - }; + console.log("Couldn't reverse match:", vname); + return "/404.html"; + } - /* - * Document Abstraction - */ - function WikiDocument(element_id) { - var meta = $('#' + element_id); - this.id = meta.attr('data-chunk-id'); + /* + * Document Abstraction + */ + function WikiDocument(element_id) { + var meta = $('#' + element_id); + this.id = meta.attr('data-chunk-id'); - this.revision = $("*[data-key='revision']", meta).text(); - this.readonly = !!$("*[data-key='readonly']", meta).text(); + this.revision = $("*[data-key='revision']", meta).text(); + this.readonly = !!$("*[data-key='readonly']", meta).text(); - this.galleryLink = $("*[data-key='gallery']", meta).text(); + this.galleryLink = $("*[data-key='gallery']", meta).text(); this.galleryStart = parseInt($("*[data-key='gallery-start']", meta).text()); var diff = $("*[data-key='diff']", meta).text(); @@ -77,209 +77,193 @@ this.diff = diff; else if (diff.length == 1) { diff = parseInt(diff); - if (diff != NaN) + if (!isNaN(diff)) this.diff = [diff - 1, diff]; } } - this.galleryImages = []; - this.text = null; - this.has_local_changes = false; - this._lock = -1; - this._context_lock = -1; - this._lock_count = 0; - }; - - WikiDocument.prototype.triggerDocumentChanged = function() { - $(document).trigger('wlapi_document_changed', this); - }; - /* - * Fetch text of this document. - */ - WikiDocument.prototype.fetch = function(params) { - params = $.extend({}, noops, params); - var self = this; - $.ajax({ - method: "GET", - url: reverse("ajax_document_text", self.id), - data: {"revision": self.revision}, - dataType: 'json', - success: function(data) { - var changed = false; - - if (self.text === null || self.revision !== data.revision) { - self.text = data.text; - self.revision = data.revision; - self.gallery = data.gallery; - changed = true; - self.triggerDocumentChanged(); - }; - - self.has_local_changes = false; - params['success'](self, changed); - }, - error: function() { - params['failure'](self, "Nie udaÅo siÄ wczytaÄ treÅci dokumentu."); - } - }); - }; - /* - * Fetch history of this document. - * - * from - First revision to fetch (default = 0) upto - Last revision to - * fetch (default = tip) - * - */ - WikiDocument.prototype.fetchHistory = function(params) { - /* this doesn't modify anything, so no locks */ - params = $.extend({}, noops, params); - var self = this; - $.ajax({ - method: "GET", - url: reverse("ajax_document_history", self.id), - dataType: 'json', - data: { - "from": params['from'], - "upto": params['upto'] - }, - success: function(data) { - params['success'](self, data); - }, - error: function() { - params['failure'](self, "Nie udaÅo siÄ wczytaÄ historii dokumentu."); - } - }); - }; - WikiDocument.prototype.fetchDiff = function(params) { - /* this doesn't modify anything, so no locks */ - var self = this; - params = $.extend({ - 'from': self.revision, - 'to': self.revision - }, noops, params); - $.ajax({ - method: "GET", - url: reverse("ajax_document_diff", self.id), - dataType: 'html', - data: { - "from": params['from'], - "to": params['to'] - }, - success: function(data) { - params['success'](self, data); - }, - error: function() { - params['failure'](self, "Nie udaÅo siÄ wczytaÄ porównania wersji."); - } - }); - }; - - WikiDocument.prototype.checkRevision = function(params) { - /* this doesn't modify anything, so no locks */ + this.galleryImages = []; + this.text = null; + this.has_local_changes = false; + this._lock = -1; + this._context_lock = -1; + this._lock_count = 0; + } + + WikiDocument.prototype.triggerDocumentChanged = function() { + $(document).trigger('wlapi_document_changed', this); + }; + /* + * Fetch text of this document. + */ + WikiDocument.prototype.fetch = function(params) { + params = $.extend({}, noops, params); var self = this; $.ajax({ method: "GET", - url: reverse("ajax_document_rev", self.id), - dataType: 'text', + url: reverse("ajax_document_text", self.id), + data: {"revision": self.revision}, + dataType: 'json', success: function(data) { - if (data == '') { - if (params.error) - params.error(); + var changed = false; + + if (self.text === null || self.revision !== data.revision) { + self.text = data.text; + self.revision = data.revision; + self.gallery = data.gallery; + changed = true; + self.triggerDocumentChanged(); } - else if (data != self.revision) - params.outdated(); + + self.has_local_changes = false; + params['success'](self, changed); + }, + error: function() { + params['failure'](self, "Nie udaÅo siÄ wczytaÄ treÅci dokumentu."); + } + }); + }; + /* + * Fetch history of this document. + * + * from - First revision to fetch (default = 0) upto - Last revision to + * fetch (default = tip) + * + */ + WikiDocument.prototype.fetchHistory = function(params) { + /* this doesn't modify anything, so no locks */ + params = $.extend({}, noops, params); + var self = this; + $.ajax({ + method: "GET", + url: reverse("ajax_document_history", self.id), + dataType: 'json', + data: { + "from": params['from'], + "upto": params['upto'] + }, + success: function(data) { + params['success'](self, data); + }, + error: function() { + params['failure'](self, "Nie udaÅo siÄ wczytaÄ historii dokumentu."); + } + }); + }; + WikiDocument.prototype.fetchDiff = function(params) { + /* this doesn't modify anything, so no locks */ + var self = this; + params = $.extend({ + 'from': self.revision, + 'to': self.revision + }, noops, params); + $.ajax({ + method: "GET", + url: reverse("ajax_document_diff", self.id), + dataType: 'html', + data: { + "from": params['from'], + "to": params['to'] + }, + success: function(data) { + params['success'](self, data); + }, + error: function() { + params['failure'](self, "Nie udaÅo siÄ wczytaÄ porównania wersji."); } }); }; - /* - * Fetch gallery - */ - WikiDocument.prototype.refreshGallery = function(params) { - params = $.extend({}, noops, params); - var self = this; - $.ajax({ - method: "GET", - url: reverse("ajax_document_gallery", self.galleryLink), - dataType: 'json', - // data: {}, - success: function(data) { - self.galleryImages = data; - params['success'](self, data); - }, - error: function(xhr) { + /* + * Fetch gallery + */ + WikiDocument.prototype.refreshGallery = function(params) { + params = $.extend({}, noops, params); + var self = this; + $.ajax({ + method: "GET", + url: reverse("ajax_document_gallery", self.galleryLink), + dataType: 'json', + // data: {}, + success: function(data) { + self.galleryImages = data; + params['success'](self, data); + }, + error: function(xhr) { + var msg; switch (xhr.status) { case 403: - var msg = 'Galerie dostÄpne tylko dla zalogowanych użytkowników.'; + msg = 'Galerie dostÄpne tylko dla zalogowanych użytkowników.'; break; case 404: - var msg = "Nie znaleziono galerii o nazwie: '" + self.galleryLink + "'."; + msg = "Nie znaleziono galerii o nazwie: '" + self.galleryLink + "'."; + break; default: - var msg = "Nie udaÅo siÄ wczytaÄ galerii o nazwie: '" + self.galleryLink + "'."; + msg = "Nie udaÅo siÄ wczytaÄ galerii o nazwie: '" + self.galleryLink + "'."; } - self.galleryImages = []; - params['failure'](self, "<p>" + msg + "</p>"); - } - }); - }; - - /* - * Set document's text - */ - WikiDocument.prototype.setText = function(text) { - this.text = text; - this.has_local_changes = true; - }; - - /* - * Set document's gallery link - */ - WikiDocument.prototype.setGalleryLink = function(gallery) { - this.galleryLink = gallery; - this.has_local_changes = true; - }; - - /* - * Save text back to the server - */ - WikiDocument.prototype.save = function(params) { - params = $.extend({}, noops, params); - var self = this; - - if (!self.has_local_changes) { - console.log("Abort: no changes."); - return params['success'](self, false, "Nie ma zmian do zapisania."); - }; - - // Serialize form to dictionary - var data = {}; - $.each(params['form'].serializeArray(), function() { - data[this.name] = this.value; - }); - - data['textsave-text'] = self.text; - - $.ajax({ - url: reverse("ajax_document_text", self.id), - type: "POST", - dataType: "json", - data: data, - success: function(data) { - var changed = false; + self.galleryImages = []; + params['failure'](self, "<p>" + msg + "</p>"); + } + }); + }; + + /* + * Set document's text + */ + WikiDocument.prototype.setText = function(text) { + this.text = text; + this.has_local_changes = true; + }; + + /* + * Set document's gallery link + */ + WikiDocument.prototype.setGalleryLink = function(gallery) { + this.galleryLink = gallery; + this.has_local_changes = true; + }; + + /* + * Save text back to the server + */ + WikiDocument.prototype.save = function(params) { + params = $.extend({}, noops, params); + var self = this; + + if (!self.has_local_changes) { + console.log("Abort: no changes."); + return params['success'](self, false, "Nie ma zmian do zapisania."); + } + + // Serialize form to dictionary + var data = {}; + $.each(params['form'].serializeArray(), function() { + data[this.name] = this.value; + }); + + data['textsave-text'] = self.text; + + $.ajax({ + url: reverse("ajax_document_text", self.id), + type: "POST", + dataType: "json", + data: data, + success: function(data) { + var changed = false; $('#header').removeClass('saving'); - if (data.text) { - self.text = data.text; - self.revision = data.revision; - self.gallery = data.gallery; - changed = true; - self.triggerDocumentChanged(); - }; - - params['success'](self, changed, ((changed && "UdaÅo siÄ zapisaÄ :)") || "Twoja wersja i serwera jest identyczna")); - }, - error: function(xhr) { + if (data.text) { + self.text = data.text; + self.revision = data.revision; + self.gallery = data.gallery; + changed = true; + self.triggerDocumentChanged(); + } + + params['success'](self, changed, ((changed && "UdaÅo siÄ zapisaÄ :)") || "Twoja wersja i serwera jest identyczna")); + }, + error: function(xhr) { if ($('#header').hasClass('saving')) { $('#header').removeClass('saving'); $.blockUI({ @@ -294,18 +278,18 @@ params['failure'](self, { "__message": "<p>Nie udaÅo siÄ zapisaÄ - bÅÄ d serwera.</p>" }); - }; + } } - } - }); + } + }); $('#save-hide').click(function(){ $('#header').addClass('saving'); $.unblockUI(); $.wiki.blocking.unblock(); }); - }; /* end of save() */ + }; /* end of save() */ WikiDocument.prototype.revertToVersion = function(params) { var self = this; @@ -346,51 +330,52 @@ }); }; - WikiDocument.prototype.pubmark = function(params) { - params = $.extend({}, noops, params); - var self = this; - var data = { - "pubmark-id": self.id, - }; - - /* unpack form */ - $.each(params.form.serializeArray(), function() { - data[this.name] = this.value; - }); - - $.ajax({ - url: reverse("ajax_document_pubmark", self.id), - type: "POST", - dataType: "json", - data: data, - success: function(data) { - params.success(self, data.message); - }, - error: function(xhr) { - if (xhr.status == 403 || xhr.status == 401) { - params.failure(self, { - "__all__": ["Nie masz uprawnieÅ lub nie jesteÅ zalogowany."] - }); - } - else { - try { - params.failure(self, $.parseJSON(xhr.responseText)); - } - catch (e) { - params.failure(self, { - "__all__": ["Nie udaÅo siÄ - bÅÄ d serwera."] - }); - }; - }; - } - }); - }; - - WikiDocument.prototype.refreshCover = function(params) { + WikiDocument.prototype.pubmark = function(params) { + params = $.extend({}, noops, params); var self = this; - var data = { - xml: self.text // TODO: send just DC - }; + var data = { + "pubmark-id": self.id + }; + + /* unpack form */ + $.each(params.form.serializeArray(), function() { + data[this.name] = this.value; + }); + + $.ajax({ + url: reverse("ajax_document_pubmark", self.id), + type: "POST", + dataType: "json", + data: data, + success: function(data) { + params.success(self, data.message); + }, + error: function(xhr) { + if (xhr.status == 403 || xhr.status == 401) { + params.failure(self, { + "__all__": ["Nie masz uprawnieÅ lub nie jesteÅ zalogowany."] + }); + } + else { + try { + params.failure(self, $.parseJSON(xhr.responseText)); + } + catch (e) { + params.failure(self, { + "__all__": ["Nie udaÅo siÄ - bÅÄ d serwera."] + }); + } + } + } + }); + }; + + /* unused except view_summary.js which is apparently unused */ + WikiDocument.prototype.refreshCover = function(params) { + var self = this; + var data = { + xml: self.text // TODO: send just DC + }; $.ajax({ url: reverse("ajax_cover_preview"), type: "POST", @@ -402,7 +387,7 @@ // params.failure("Nie udaÅo siÄ odÅwieżyÄ okÅadki - bÅÄ d serwera."); } }); - }; + }; WikiDocument.prototype.getLength = function(params) { @@ -419,8 +404,8 @@ var text = $(doc).text(); text = $.trim(text.replace(/\s{2,}/g, ' ')); return text.length; - } + }; - $.wikiapi.WikiDocument = WikiDocument; + $.wikiapi.WikiDocument = WikiDocument; })(jQuery); diff --git a/redakcja/templates/registration/head_login.html b/redakcja/templates/registration/head_login.html index 5223da07..f743f409 100644 --- a/redakcja/templates/registration/head_login.html +++ b/redakcja/templates/registration/head_login.html @@ -59,7 +59,6 @@ {% endif %} <li><a href="{% url 'logout' %}">{% trans "Logout" %}</a></li> </ul> - </div> </li> @@ -74,8 +73,8 @@ > {% trans "Log in / Register" %} </button> - <div class="dropdown-menu" style="padding:0;margin-top:-5px; border:none;box-shadow:none; min-width:240px"> - <div class="panel panel-default" style="color: #333;"> + <div class="dropdown-menu" style="padding:0;margin-top:-5px; border:none;box-shadow:none; min-width:240px"> + <div class="panel panel-default" style="color: #333;"> <div class="panel-heading"> <h3 class="panel-title">{% trans "Log in / Register" %}</h3> </div> @@ -104,6 +103,7 @@ <p style="margin-bottom:1em">{% trans "<strong>Register now</strong> to start editing your own materials." %}</p> <a class="btn btn-default" href="{% url 'register' %}">{% trans "Register" %}</a> </div> + </div> </div> </li> {% endifnotequal %} diff --git a/redakcja/urls.py b/redakcja/urls.py index 2dd64411..da12c29b 100644 --- a/redakcja/urls.py +++ b/redakcja/urls.py @@ -5,20 +5,20 @@ from django.contrib import admin from django.conf import settings from django.conf.urls.static import static from django.contrib.staticfiles.urls import staticfiles_urlpatterns -from django.views.generic import RedirectView import forms_builder.forms.urls admin.autodiscover() -urlpatterns = patterns('', +urlpatterns = patterns( + '', # Auth - #url(r'^accounts/login/$', 'django_cas.views.login', name='login'), - #url(r'^accounts/logout/$', 'django_cas.views.logout', name='logout'), - #url(r'^accounts/login/$', 'django.contrib.auth.views.login', name='login'), - #url(r'^accounts/logout/$', 'django.contrib.auth.views.login', name='logout'), - #url(r'^admin/login/$', 'django_cas.views.login', name='login'), - #url(r'^admin/logout/$', 'django_cas.views.logout', name='logout'), + # url(r'^accounts/login/$', 'django_cas.views.login', name='login'), + # url(r'^accounts/logout/$', 'django_cas.views.logout', name='logout'), + # url(r'^accounts/login/$', 'django.contrib.auth.views.login', name='login'), + # url(r'^accounts/logout/$', 'django.contrib.auth.views.login', name='logout'), + # url(r'^admin/login/$', 'django_cas.views.login', name='login'), + # url(r'^admin/logout/$', 'django_cas.views.logout', name='logout'), url('^accounts/', include('django.contrib.auth.urls')), # Admin panel @@ -29,7 +29,6 @@ urlpatterns = patterns('', url(r'^register$', 'redakcja.views.register', name='register'), url(r'^documents/', include('catalogue.urls')), url(r'^editor/', include('wiki.urls')), - url(r'^cover/', include('cover.urls')), url(r'^organizations/', include('organizations.urls')), url(r'^forms/', include(forms_builder.forms.urls)), @@ -43,7 +42,10 @@ if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) if getattr(settings, 'SERVE_FILES_WITH_DEBUG_FALSE', False): - urlpatterns += patterns('', - (r'^%s(?P<path>.*)$' % settings.STATIC_URL[1:], 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}), - (r'^%s(?P<path>.*)$' % settings.MEDIA_URL[1:], 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}), -) + urlpatterns += patterns( + '', + (r'^%s(?P<path>.*)$' % settings.STATIC_URL[1:], + 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}), + (r'^%s(?P<path>.*)$' % settings.MEDIA_URL[1:], + 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}), + ) diff --git a/redakcja/views.py b/redakcja/views.py index a3045dbd..07c6d65b 100644 --- a/redakcja/views.py +++ b/redakcja/views.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login from django.contrib.auth.models import User @@ -6,6 +11,7 @@ from .forms import RegistrationForm from catalogue.models import Document from organizations.models import Organization + def main(request): upcoming = Document.objects.filter(deleted=False).filter(publish_log=None) finished = Document.objects.filter(deleted=False).exclude(publish_log=None) @@ -17,7 +23,6 @@ def main(request): finished = finished[:8] organizations = organizations[:8] - return render(request, 'main.html', { 'finished': finished, 'upcoming': upcoming, @@ -27,6 +32,7 @@ def main(request): 'more_organizations': more_organizations, }) + def register(request): if request.method == 'POST': form = RegistrationForm(request.POST, request.FILES) @@ -40,8 +46,9 @@ def register(request): u.set_password(form.cleaned_data['password']) u.save() login(request, authenticate(username=form.cleaned_data['email'], password=form.cleaned_data['password'])) - send_mail('Registered at MIL/PEER', -'''You have been successfully registered at MIL/PEER with this e-mail address. + send_mail( + 'Registered at MIL/PEER', + '''You have been successfully registered at MIL/PEER with this e-mail address. Thank you. diff --git a/redakcja/wsgi.py b/redakcja/wsgi.py index cd69a922..10f09018 100755 --- a/redakcja/wsgi.py +++ b/redakcja/wsgi.py @@ -1,4 +1,8 @@ -import os +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# import os.path import sys diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py index 5c572ea3..9c38bca0 100644 --- a/tests/integration/__init__.py +++ b/tests/integration/__init__.py @@ -1,5 +1,10 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# import os from django.conf import settings if not os.path.exists(settings.STATIC_ROOT_SYMLINK): - os.symlink(settings.STATIC_ROOT, settings.STATIC_ROOT_SYMLINK) \ No newline at end of file + os.symlink(settings.STATIC_ROOT, settings.STATIC_ROOT_SYMLINK) diff --git a/tests/integration/base.py b/tests/integration/base.py index c2774c97..d243eb31 100644 --- a/tests/integration/base.py +++ b/tests/integration/base.py @@ -1,15 +1,18 @@ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# import os import inspect -from urlparse import urlparse from django.test import LiveServerTestCase from django.test.client import Client from django.conf import settings -from django.contrib.auth.models import User, Permission +from django.contrib.auth.models import User from django.utils.translation import ugettext as _ -from selenium import webdriver, selenium -from selenium.webdriver.support.wait import WebDriverWait +from selenium import webdriver class SeleniumTestCase(LiveServerTestCase): @@ -28,7 +31,7 @@ class SeleniumTestCase(LiveServerTestCase): def setUp(self): self.browser.delete_all_cookies() - def create_user(self, username = 'testuser', passwd = 'passwd', do_login = False): + def create_user(self, username='testuser', passwd='passwd', do_login=False): user = User.objects.create_user(username, '', passwd) user._plain_passwd = passwd if do_login: @@ -43,17 +46,16 @@ class SeleniumTestCase(LiveServerTestCase): def login_user(self, user): client = Client() - client.login(username = user.username, password = user._plain_passwd) + client.login(username=user.username, password=user._plain_passwd) if not self.browser.current_url.startswith(self.live_server_url): self.browser.get(self.live_server_url+'/not_existing_url') - self.browser.find_element_by_tag_name('body') # Make sure the page is actually loaded before setting the cookie + self.browser.find_element_by_tag_name('body') # Make sure the page is actually loaded before setting the cookie self.browser.delete_cookie(settings.SESSION_COOKIE_NAME) - self.browser.add_cookie(dict(name = settings.SESSION_COOKIE_NAME, - value = client.cookies[settings.SESSION_COOKIE_NAME].value, - path = '/') - ) + self.browser.add_cookie(dict(name=settings.SESSION_COOKIE_NAME, + value=client.cookies[settings.SESSION_COOKIE_NAME].value, + path='/')) def get_main_page(self): self.browser.get(self.live_server_url) @@ -82,7 +84,7 @@ class MainPage(Page): a.click() self.tab = find_tab_class(tab_title)(self.browser) return - raise Exception, 'Tab not found' + raise Exception('Tab not found') def find_tab_class(tab_title): @@ -121,5 +123,3 @@ class BooksListPage(MainPageTabBase): @property def visible_books_count(self): return len(self.element.find_element_by_id('file-list').find_elements_by_tag_name('tr')) - 2 - - \ No newline at end of file diff --git a/tests/integration/smoke_test.py b/tests/integration/smoke_test.py index fb29a73c..8c48026a 100644 --- a/tests/integration/smoke_test.py +++ b/tests/integration/smoke_test.py @@ -1,10 +1,15 @@ -from tests.integration.base import SeleniumTestCase, MainPage, _ +# -*- coding: utf-8 -*- +# +# This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# +from tests.integration.base import SeleniumTestCase +from django.utils.translation import ugettext as _ + class SmokeTest(SeleniumTestCase): def test_add_book(self): - user = self.create_super_user(do_login = True) - page = self.get_main_page() page.select_tab(_('All')) assert page.tab.visible_books_count == 0 @@ -15,4 +20,3 @@ class SmokeTest(SeleniumTestCase): page.tab.submit() page.select_tab(_('All')) assert page.tab.visible_books_count == 1 - \ No newline at end of file -- 2.20.1